From 6a642f57ca3725f262b5a010f6192ebe52442c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCder?= Date: Wed, 19 Jan 2022 09:40:03 +0100 Subject: [PATCH] Disable cropper while focusarea is in use --- .../Public/TypeScript/ImageManipulation.ts | 24 +++++++++++++++++++ .../Public/JavaScript/ImageManipulation.js | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/ImageManipulation.ts b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/ImageManipulation.ts index d33e8573ca9..910059c92e7 100644 --- a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/ImageManipulation.ts +++ b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/ImageManipulation.ts @@ -538,6 +538,30 @@ class ImageManipulation { .draggable({ containment: container, create: (): void => { + // To make the focusarea draggable cropper must be disabled by + // register the same events as cropper does. + // + // copied from + // https://github.com/fengyuanchen/cropperjs/blob/main/src/js/constants.js + + const IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined'; + const IS_TOUCH_DEVICE = IS_BROWSER && window.document.documentElement ? 'ontouchstart' in window.document.documentElement : false; + const HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in window : false; + const EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown'; + const EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup'; + const EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START; + const EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END; + + // Disable cropper + $(this.focusArea).on(EVENT_POINTER_DOWN, () => { + this.cropper.disable(); + }); + + // Enable cropper + $(this.focusArea).on(EVENT_POINTER_UP, () => { + this.cropper.enable(); + }); + this.scaleAndMoveFocusArea(this.currentCropVariant.focusArea); }, drag: (): void => { diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/ImageManipulation.js b/typo3/sysext/backend/Resources/Public/JavaScript/ImageManipulation.js index 0e552e16b29..a7de91a5874 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/ImageManipulation.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/ImageManipulation.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};define(["require","exports","jquery","TYPO3/CMS/Backend/FormEngineValidation","TYPO3/CMS/Core/Ajax/AjaxRequest","cropperjs","imagesloaded","./Icons","./Modal","jquery-ui/draggable","jquery-ui/resizable"],(function(t,e,r,a,i,s,o,n,c){"use strict";r=__importDefault(r),s=__importDefault(s);class h{constructor(){this.initialized=!1,this.cropImageContainerSelector="#t3js-crop-image-container",this.cropImageSelector="#t3js-crop-image",this.coverAreaSelector=".t3js-cropper-cover-area",this.cropInfoSelector=".t3js-cropper-info-crop",this.focusAreaSelector="#t3js-cropper-focus-area",this.defaultFocusArea={height:1/3,width:1/3,x:0,y:0},this.defaultOpts={autoCrop:!0,autoCropArea:.7,dragMode:"crop",guides:!0,responsive:!0,viewMode:1,zoomable:!1,checkCrossOrigin:!1},this.cropBuiltHandler=()=>{this.initialized=!0;const t=this.cropper.getImageData(),e=this.currentModal.find(this.cropImageSelector);this.currentModal.find(".cropper-canvas img").removeClass("cropper-hide"),this.imageOriginalSizeFactor=e.data("originalWidth")/t.naturalWidth,this.cropVariantTriggers.each((e,a)=>{const i=(0,r.default)(a).attr("data-crop-variant-id"),s=this.convertRelativeToAbsoluteCropArea(this.data[i].cropArea,t),o=r.default.extend(!0,{},this.data[i],{cropArea:s});this.updatePreviewThumbnail(o,(0,r.default)(a))}),this.currentCropVariant.cropArea=this.convertRelativeToAbsoluteCropArea(this.currentCropVariant.cropArea,t),this.cropBox=this.currentModal.find(".cropper-crop-box"),this.setCropArea(this.currentCropVariant.cropArea),this.currentCropVariant.coverAreas&&this.initCoverAreas(this.cropBox,this.currentCropVariant.coverAreas),this.currentCropVariant.focusArea&&(h.isEmptyArea(this.currentCropVariant.focusArea)&&(this.currentCropVariant.focusArea=r.default.extend(!0,{},this.defaultFocusArea)),this.initFocusArea(this.cropBox),this.scaleAndMoveFocusArea(this.currentCropVariant.focusArea)),this.currentCropVariant.selectedRatio&&this.currentModal.find(`[data-bs-option='${this.currentCropVariant.selectedRatio}']`).addClass("active")},this.cropMoveHandler=t=>{if(!this.initialized)return;this.currentCropVariant.cropArea=r.default.extend(!0,this.currentCropVariant.cropArea,{height:Math.floor(t.detail.height),width:Math.floor(t.detail.width),x:Math.floor(t.detail.x),y:Math.floor(t.detail.y)}),this.updatePreviewThumbnail(this.currentCropVariant,this.activeCropVariantTrigger),this.updateCropVariantData(this.currentCropVariant);const e=Math.round(this.currentCropVariant.cropArea.width*this.imageOriginalSizeFactor),a=Math.round(this.currentCropVariant.cropArea.height*this.imageOriginalSizeFactor);this.cropInfo.text(`${e}×${a} px`)},this.cropStartHandler=()=>{this.currentCropVariant.focusArea&&(this.focusArea.draggable("option","disabled",!0),this.focusArea.resizable("option","disabled",!0))},this.cropEndHandler=()=>{this.currentCropVariant.focusArea&&(this.focusArea.draggable("option","disabled",!1),this.focusArea.resizable("option","disabled",!1))}}static isEmptyArea(t){return r.default.isEmptyObject(t)}static wait(t,e){window.setTimeout(t,e)}static toCssPercent(t){return 100*t+"%"}static serializeCropVariants(t){return JSON.stringify(t,(t,e)=>"id"===t||"title"===t||"allowedAspectRatios"===t||"coverAreas"===t?void 0:e)}initializeTrigger(){(0,r.default)(".t3js-image-manipulation-trigger").off("click").on("click",t=>{t.preventDefault(),this.trigger=(0,r.default)(t.currentTarget),this.show()})}initializeCropperModal(){const t=this.currentModal.find(this.cropImageSelector);o(t.get(0),()=>{this.init()})}show(){const t=this.trigger.data("modalTitle"),e=this.trigger.data("buttonPreviewText"),a=this.trigger.data("buttonDismissText"),s=this.trigger.data("buttonSaveText"),o=this.trigger.data("url"),h=this.trigger.data("payload");n.getIcon("spinner-circle",n.sizes.default,null,null,n.markupIdentifiers.inline).then(n=>{this.currentModal=c.advanced({additionalCssClasses:["modal-image-manipulation"],buttons:[{btnClass:"btn-default pull-left",dataAttributes:{method:"preview"},icon:"actions-view",text:e},{btnClass:"btn-default",dataAttributes:{method:"dismiss"},icon:"actions-close",text:a},{btnClass:"btn-primary",dataAttributes:{method:"save"},icon:"actions-document-save",text:s}],content:(0,r.default)('