Tui.image-editor: Zoom feature.

Created on 20 Nov 2018  Â·  17Comments  Â·  Source: nhn/tui.image-editor

Version

tui-image-editor.js 3.2.1

Development Environment

Chrome, Windows, AngularJS

Current Behavior


No zoom feature.


Expected Behavior

My image is quite large and when previewing on tui editor, it looks pixelated, it would be a good feature to have zoom for images have texts to make them readable.

Enhancement

Most helpful comment

I had to create a Fork to address Zoom and Pan. Hope this helps.

All 17 comments

that kinda sucks :D I am just done adding the image editor to my project and this feature is kinda mandatory... should have probably done my research

I need too

You can try this hack:

  $('#tui-image-editor .tui-image-editor').on('mousewheel', (e) => {
      var imageOriginalSize = {
        width: imageEditor._graphics.canvasImage.width,
        height: imageEditor._graphics.canvasImage.height
      };
      var wDelta = e.originalEvent.wheelDelta || e.originalEvent.deltaY;
      var imageEditorWindow = e.currentTarget;
      var scrollContainer = $('.tui-image-editor-wrap');
      var initWidth = imageEditorWindow.style.width;
      var initHeight = imageEditorWindow.style.height;
      var scrollContainerInitial = {
        top: scrollContainer.scrollTop(),
        left: scrollContainer.scrollLeft(),
        height: scrollContainer[0].scrollHeight,
        width: scrollContainer[0].scrollWidth
      };
      var mousePosition = {
        top: e.clientY - $(imageEditorWindow).offset().top,
        left: e.clientX - $(imageEditorWindow).offset().left
      };
      var newWidth;
      var newHeight;
      var offsetY;
      var offsetX;
      // Zoom step 10%
      if (wDelta > 0) {
        newWidth = parseInt(initWidth, 10) * 1.1;
        newHeight = parseInt(initHeight, 10) * 1.1;
        // Limit maximum zoom by image resolution
        if (newWidth > imageOriginalSize.width || newHeight > imageOriginalSize.height) {
          newWidth = imageOriginalSize.width;
          newHeight = imageOriginalSize.height;
        }
      } else {
        newWidth = parseInt(initWidth, 10) * 0.9;
        newHeight = parseInt(initHeight, 10) * 0.9;
        // Limit minimum zoom by 0.5 of original container size
        if (parseInt(imageEditorWindow.dataset.minWidth, 10) * 0.5 > parseInt(newWidth, 10)) {
          newWidth = parseInt(imageEditorWindow.dataset.minWidth, 10) * 0.5;
          newHeight = parseInt(imageEditorWindow.dataset.minHeight, 10) * 0.5;
        }
      }
      imageEditorWindow.style.width = newWidth + 'px';
      imageEditorWindow.style.height = newHeight + 'px';
      $(imageEditorWindow).find('canvas, .tui-image-editor-canvas-container')
        .css('max-width', imageEditorWindow.style.width)
        .css('max-height', imageEditorWindow.style.height);

      // Save initial size of container
      if (imageEditorWindow.dataset.minHeight === undefined) {
        imageEditorWindow.dataset.minHeight = initHeight;
        imageEditorWindow.dataset.minWidth = initWidth;
      }

      // Calculate scroll offset for new position
      offsetY = (scrollContainer[0].scrollHeight - scrollContainerInitial.height)
      * (mousePosition.top / scrollContainerInitial.height);
      offsetX = (scrollContainer[0].scrollWidth - scrollContainerInitial.width)
      * (mousePosition.left / scrollContainerInitial.width);

      scrollContainer.scrollTop(scrollContainerInitial.top + offsetY);
      scrollContainer.scrollLeft(scrollContainerInitial.left + offsetX);

      e.preventDefault();
      e.stopPropagation();
    });
    // Prevent scroll with wheel
    $('.tui-image-editor-wrap')[0].onwheel = function() { return false; };
    // Prevent overlapping from toolbar
    $('.tui-image-editor-wrap').css('height', 'calc(100% - 150px)');

Run this after image editor initialization. This example for mouse wheel, but you also can implement this for buttons.

To prevent image jumping issue required to override top position of .tui-image-editor.

#tui-image-editor {
  .tui-image-editor {
    top: 0px !important;
  }
}

You can try this hack:

  $('#tui-image-editor .tui-image-editor').on('mousewheel', (e) => {
      var imageOriginalSize = {
        width: imageEditor._graphics.canvasImage.width,
        height: imageEditor._graphics.canvasImage.height
      };
      var wDelta = e.originalEvent.wheelDelta || e.originalEvent.deltaY;
      var imageEditorWindow = e.currentTarget;
      var scrollContainer = $('.tui-image-editor-wrap');
      var initWidth = imageEditorWindow.style.width;
      var initHeight = imageEditorWindow.style.height;
      var scrollContainerInitial = {
        top: scrollContainer.scrollTop(),
        left: scrollContainer.scrollLeft(),
        height: scrollContainer[0].scrollHeight,
        width: scrollContainer[0].scrollWidth
      };
      var mousePosition = {
        top: e.clientY - $(imageEditorWindow).offset().top,
        left: e.clientX - $(imageEditorWindow).offset().left
      };
      var newWidth;
      var newHeight;
      var offsetY;
      var offsetX;
      // Zoom step 10%
      if (wDelta > 0) {
        newWidth = parseInt(initWidth, 10) * 1.1;
        newHeight = parseInt(initHeight, 10) * 1.1;
        // Limit maximum zoom by image resolution
        if (newWidth > imageOriginalSize.width || newHeight > imageOriginalSize.height) {
          newWidth = imageOriginalSize.width;
          newHeight = imageOriginalSize.height;
        }
      } else {
        newWidth = parseInt(initWidth, 10) * 0.9;
        newHeight = parseInt(initHeight, 10) * 0.9;
        // Limit minimum zoom by 0.5 of original container size
        if (parseInt(imageEditorWindow.dataset.minWidth, 10) * 0.5 > parseInt(newWidth, 10)) {
          newWidth = parseInt(imageEditorWindow.dataset.minWidth, 10) * 0.5;
          newHeight = parseInt(imageEditorWindow.dataset.minHeight, 10) * 0.5;
        }
      }
      imageEditorWindow.style.width = newWidth + 'px';
      imageEditorWindow.style.height = newHeight + 'px';
      $(imageEditorWindow).find('canvas, .tui-image-editor-canvas-container')
        .css('max-width', imageEditorWindow.style.width)
        .css('max-height', imageEditorWindow.style.height);

      // Save initial size of container
      if (imageEditorWindow.dataset.minHeight === undefined) {
        imageEditorWindow.dataset.minHeight = initHeight;
        imageEditorWindow.dataset.minWidth = initWidth;
      }

      // Calculate scroll offset for new position
      offsetY = (scrollContainer[0].scrollHeight - scrollContainerInitial.height)
      * (mousePosition.top / scrollContainerInitial.height);
      offsetX = (scrollContainer[0].scrollWidth - scrollContainerInitial.width)
      * (mousePosition.left / scrollContainerInitial.width);

      scrollContainer.scrollTop(scrollContainerInitial.top + offsetY);
      scrollContainer.scrollLeft(scrollContainerInitial.left + offsetX);

      e.preventDefault();
      e.stopPropagation();
    });
    // Prevent scroll with wheel
    $('.tui-image-editor-wrap')[0].onwheel = function() { return false; };
    // Prevent overlapping from toolbar
    $('.tui-image-editor-wrap').css('height', 'calc(100% - 150px)');

Run this after image editor initialization. This example for mouse wheel, but you also can implement this for buttons.

To prevent image jumping issue required to override top position of .tui-image-editor.

#tui-image-editor {
  .tui-image-editor {
    top: 0px !important;
  }
}

You can try this hack:

  $('#tui-image-editor .tui-image-editor').on('mousewheel', (e) => {
      var imageOriginalSize = {
        width: imageEditor._graphics.canvasImage.width,
        height: imageEditor._graphics.canvasImage.height
      };
      var wDelta = e.originalEvent.wheelDelta || e.originalEvent.deltaY;
      var imageEditorWindow = e.currentTarget;
      var scrollContainer = $('.tui-image-editor-wrap');
      var initWidth = imageEditorWindow.style.width;
      var initHeight = imageEditorWindow.style.height;
      var scrollContainerInitial = {
        top: scrollContainer.scrollTop(),
        left: scrollContainer.scrollLeft(),
        height: scrollContainer[0].scrollHeight,
        width: scrollContainer[0].scrollWidth
      };
      var mousePosition = {
        top: e.clientY - $(imageEditorWindow).offset().top,
        left: e.clientX - $(imageEditorWindow).offset().left
      };
      var newWidth;
      var newHeight;
      var offsetY;
      var offsetX;
      // Zoom step 10%
      if (wDelta > 0) {
        newWidth = parseInt(initWidth, 10) * 1.1;
        newHeight = parseInt(initHeight, 10) * 1.1;
        // Limit maximum zoom by image resolution
        if (newWidth > imageOriginalSize.width || newHeight > imageOriginalSize.height) {
          newWidth = imageOriginalSize.width;
          newHeight = imageOriginalSize.height;
        }
      } else {
        newWidth = parseInt(initWidth, 10) * 0.9;
        newHeight = parseInt(initHeight, 10) * 0.9;
        // Limit minimum zoom by 0.5 of original container size
        if (parseInt(imageEditorWindow.dataset.minWidth, 10) * 0.5 > parseInt(newWidth, 10)) {
          newWidth = parseInt(imageEditorWindow.dataset.minWidth, 10) * 0.5;
          newHeight = parseInt(imageEditorWindow.dataset.minHeight, 10) * 0.5;
        }
      }
      imageEditorWindow.style.width = newWidth + 'px';
      imageEditorWindow.style.height = newHeight + 'px';
      $(imageEditorWindow).find('canvas, .tui-image-editor-canvas-container')
        .css('max-width', imageEditorWindow.style.width)
        .css('max-height', imageEditorWindow.style.height);

      // Save initial size of container
      if (imageEditorWindow.dataset.minHeight === undefined) {
        imageEditorWindow.dataset.minHeight = initHeight;
        imageEditorWindow.dataset.minWidth = initWidth;
      }

      // Calculate scroll offset for new position
      offsetY = (scrollContainer[0].scrollHeight - scrollContainerInitial.height)
      * (mousePosition.top / scrollContainerInitial.height);
      offsetX = (scrollContainer[0].scrollWidth - scrollContainerInitial.width)
      * (mousePosition.left / scrollContainerInitial.width);

      scrollContainer.scrollTop(scrollContainerInitial.top + offsetY);
      scrollContainer.scrollLeft(scrollContainerInitial.left + offsetX);

      e.preventDefault();
      e.stopPropagation();
    });
    // Prevent scroll with wheel
    $('.tui-image-editor-wrap')[0].onwheel = function() { return false; };
    // Prevent overlapping from toolbar
    $('.tui-image-editor-wrap').css('height', 'calc(100% - 150px)');

Run this after image editor initialization. This example for mouse wheel, but you also can implement this for buttons.

To prevent image jumping issue required to override top position of .tui-image-editor.

#tui-image-editor {
  .tui-image-editor {
    top: 0px !important;
  }
}

it's not working
$('.tui-image-editor-wrap')[0].onwheel = function() { return false; };
Uncaught TypeError: Cannot set property 'onwheel' of undefined
at Object.eval (tui-image-editor.js?02b4:6338)
at webpack_require (tui-image-editor.js?02b4:36)
at Object.eval (tui-image-editor.js?02b4:4966)
at webpack_require (tui-image-editor.js?02b4:36)
at Object.eval (tui-image-editor.js?02b4:608)
at webpack_require (tui-image-editor.js?02b4:36)
at Object.eval (tui-image-editor.js?02b4:67)
at webpack_require (tui-image-editor.js?02b4:36)
at eval (tui-image-editor.js?02b4:56)
at eval (tui-image-editor.js?02b4:59)
at webpackUniversalModuleDefinition (tui-image-editor.js?02b4:9)
at Object.eval (tui-image-editor.js?02b4:16)
at eval (tui-image-editor.js:18608)
at Object../node_modules/tui-image-editor/dist/tui-image-editor.js (vendor.bundle.js:5235)
at webpack_require (manifest.bundle.js:694)

try this
add this in constructor of graphics.js
onMouseWheel: this._onMouseWheel.bind(this),
and add this method below
_onMouseWheel(fEvent) { const delta = fEvent.e.deltaY / 1000; let zoom = this._canvas.getZoom(); zoom = zoom + delta; if (zoom > 5) { zoom = 5; } if (zoom < 1) { zoom = 1; } this._canvas.setZoom(zoom); // update vptCoords this._canvas.calcViewportBoundaries(); fEvent.e.preventDefault(); fEvent.e.stopPropagation(); }

yes
This is working fine but i am not able to move the image after zooming the
image
Thank you..

On Fri, Nov 22, 2019 at 2:25 PM Cocoroise notifications@github.com wrote:

try this
add this in constructor in graphics.js

onMouseWheel: this._onMouseWheel.bind(this),

and add this method

_onMouseWheel(fEvent) {
const delta = fEvent.e.deltaY / 1000;
let zoom = this._canvas.getZoom();
zoom = zoom + delta;
if (zoom > 5) {
zoom = 5;
}
if (zoom < 1) {
zoom = 1;
}
this._canvas.setZoom(zoom);
// update vptCoords
this._canvas.calcViewportBoundaries();
fEvent.e.preventDefault();
fEvent.e.stopPropagation();
}

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/nhn/tui.image-editor/issues/95?email_source=notifications&email_token=AL4VRXZB422EDPCOEK3WENTQU6M7DA5CNFSM4GFIKI7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEE47YOY#issuecomment-557448251,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AL4VRX33N7AWUJKGMQUNQDDQU6M7DANCNFSM4GFIKI7A
.

yes This is working fine but i am not able to move the image after zooming the image Thank you..
…
On Fri, Nov 22, 2019 at 2:25 PM Cocoroise @.*> wrote: try this add this in constructor in graphics.js onMouseWheel: this._onMouseWheel.bind(this), and add this method _onMouseWheel(fEvent) { const delta = fEvent.e.deltaY / 1000; let zoom = this._canvas.getZoom(); zoom = zoom + delta; if (zoom > 5) { zoom = 5; } if (zoom < 1) { zoom = 1; } this._canvas.setZoom(zoom); // update vptCoords this._canvas.calcViewportBoundaries(); fEvent.e.preventDefault(); fEvent.e.stopPropagation(); } — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#95?email_source=notifications&email_token=AL4VRXZB422EDPCOEK3WENTQU6M7DA5CNFSM4GFIKI7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEE47YOY#issuecomment-557448251>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL4VRX33N7AWUJKGMQUNQDDQU6M7DANCNFSM4GFIKI7A .

if you want to move the canvas you should add new feature,fabric dont implement this. In my code,i add a select component to do this , after this you should listen for mouse movement events and limit the movement range of the canvas.Below is part of my code.
````js
_onFabricMouseMove(fEvent) {
const canvas = this.getCanvas();
if (this.isDragging) {
// eslint-disable-next-line prefer-destructuring
const e = fEvent.e;
const vpt = canvas.viewportTransform;
const zoom = canvas.getZoom();
const offsetX = e.clientX - this.lastPosX;
const offsetY = e.clientY - this.lastPosY;

        // viewportTransform 4/5 is the offset position
        vpt[4] += offsetX;
        vpt[5] += offsetY;
        const width = canvas.getWidth();
        const height = canvas.getHeight();

        // limit the canvas
        if (vpt[4] >= 0) {
            vpt[4] = 0;
        } else if (vpt[4] <= width - width * zoom) {
            vpt[4] = width - width * zoom;
        }
        if (vpt[5] >= 0) {
            vpt[5] = 0;
        } else if (vpt[5] <= height - height * zoom) {
            vpt[5] = height - height * zoom;
        }

        canvas.renderAll();
        this.lastPosX = e.clientX;
        this.lastPosY = e.clientY;
    }
}

````
Zoom and pan, introduction to FabricJS part 5

I had to create a Fork to address Zoom and Pan. Hope this helps.

@sabinayakc looks good, could you open a Pull-Request with that?

@sabinayakc what's up ?

You can also check this repo: https://github.com/bradstiff/react-responsive-pinch-zoom-pan, to allow pinch zoom with mobile and touch devices

@sabinayakc did you create a pull request? It would be great to have zoom and pan added in!

I think he hadnt yet. But I forked his fork https://github.com/Amerlander/tui.image-editor and wrote about my implementation in a PR here https://github.com/sabinayakc/tui.image-editor/pull/1. Maybe it is helpfull in some way. The PR is marked as Merged, but it was reverted later as you can see in the last comment.

@Amerlander , @mattStayner , @marioviana - If you guys wanna be a collaborator and make changes to the forked repo please let me know. I can add you all. Been very busy in my professional life so haven't had a time to catch up.

Pan and Zoom using mouse gestures:
https://ricardojlrufino.github.io/tui.image-editor-zoom/

No changes in sources, i use a separete class:
https://github.com/ricardojlrufino/tui.image-editor-zoom/blob/master/js/panZoom.js

Only need: call new IEditorPanZoom(imageEditor).enable();

I haven't tested it on iPhone yet ...

  • Desktop/Browser:

    • Zoom on Mouse Whell


    • Pan ou Middle button click

  • Mobile:

    • Pinch zoom gestures



    • TODO:


    • Pan on Mobile (TODO need a custom UI button)

@ricardojlrufino did you provided touch mobile compatibility ?

example: https://github.com/prc5/react-zoom-pan-pinch

@ricardojlrufino did you provided touch mobile compatibility ?

example: https://github.com/prc5/react-zoom-pan-pinch

Only Zoom for mobile !

PAN need custom user option to work together with object selection.

Was this page helpful?
0 / 5 - 0 ratings