Tui.image-editor: Editor unresponsive after undoing crop

Created on 3 Feb 2021  路  7Comments  路  Source: nhn/tui.image-editor

Describe the bug
The image editor is mostly unresponsive after cropping an image and then undoing twice.

This only happens if the cropping rectangle is resized at least once before cropping.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://ui.toast.com/tui-image-editor (Or https://nhn.github.io/tui.image-editor/latest/tutorial-example02-useApiDirect)
  2. Switch to crop mode
  3. Make a cropping rectangle, by either making a custom rectangle or selecting one of the fixed ones.
  4. Resize the cropping rectangle

    • At this point, you should see the 'Undo' button enable. I assume this event gets pushed into the undo stack.

    • Clicking 'Undo' here triggers the error as well.

  5. Crop the image
  6. Click 'Undo'. The image returns to original dimensions.
  7. Click 'Undo' again.

    • Javascript console throws an Uncaught TypeError: Cannot read property 'set' of undefined exception.

  8. Image editor is mostly unresponsive afterwards:

    • Most commands fail with an Uncaught (in promise) The executing command state is locked. exception.

    • Free drawing seems to work though, but changes cannot be undone.

Expected behavior

  • Image editor works after undoing crop.
  • 'Undo' stack is not changed by resizing cropping rectangles.

Desktop (please complete the following information):

  • OS: Mac OS
  • Browser: Chrome
  • Version: 88.0.4324.96 (Official Build) (x86_64)
Bug

Most helpful comment

@lja1018 Thank you for looking into the matter. We are also hoping this can be fixed soon. 馃槂

At the moment, we've implemented a somewhat hacky workaround that seems to work for our case.
@ayappaP if you are in need of addressing this quickly, perhaps this could be of help to you:

const editorInstance = ... // Tui Image Editor instance
const graphics = editorInstance._graphics;
const canvas = graphics._canvas;
const { onObjectModified } = graphics._handler;

// Detach default 'object:modified' listener and replace it with our own
canvas.off('object:modified', onObjectModified);
canvas.on('object:modified', (event) => {
  const { target } = event;
  // Ignore all 'object:modified' events triggered by a cropzone.
  if (target.type === 'cropzone') return;
  // Use the original event handler otherwise.
  onObjectModified(event);
});

All 7 comments

@fjwong
I understand this issue. Thank you for your detailed report. I'll handle it.

@lja1018 Running into the same problem that @fjwong described.

When can we expect a fix for this? Would really appreciate it!! Thanks!!

@ayappaP
It will be fixed soon. Maybe next week.

@lja1018 Thank you for looking into the matter. We are also hoping this can be fixed soon. 馃槂

At the moment, we've implemented a somewhat hacky workaround that seems to work for our case.
@ayappaP if you are in need of addressing this quickly, perhaps this could be of help to you:

const editorInstance = ... // Tui Image Editor instance
const graphics = editorInstance._graphics;
const canvas = graphics._canvas;
const { onObjectModified } = graphics._handler;

// Detach default 'object:modified' listener and replace it with our own
canvas.off('object:modified', onObjectModified);
canvas.on('object:modified', (event) => {
  const { target } = event;
  // Ignore all 'object:modified' events triggered by a cropzone.
  if (target.type === 'cropzone') return;
  // Use the original event handler otherwise.
  onObjectModified(event);
});

Thanks a lot @fjwong !!

I will try this.

@lja1018 Thank you for looking into the matter. We are also hoping this can be fixed soon. 馃槂

At the moment, we've implemented a somewhat hacky workaround that seems to work for our case.
@ayappaP if you are in need of addressing this quickly, perhaps this could be of help to you:

const editorInstance = ... // Tui Image Editor instance
const graphics = editorInstance._graphics;
const canvas = graphics._canvas;
const { onObjectModified } = graphics._handler;

// Detach default 'object:modified' listener and replace it with our own
canvas.off('object:modified', onObjectModified);
canvas.on('object:modified', (event) => {
  const { target } = event;
  // Ignore all 'object:modified' events triggered by a cropzone.
  if (target.type === 'cropzone') return;
  // Use the original event handler otherwise.
  onObjectModified(event);
});

This worked for me. Thanks for your help @fjwong !!

@fjwong @ayappaP
Thanks for the report. Resolved in v3.13.0.

Was this page helpful?
0 / 5 - 0 ratings