diff --git a/core/block_animations.ts b/core/block_animations.ts index d3bd13118..f3fc3d454 100644 --- a/core/block_animations.ts +++ b/core/block_animations.ts @@ -42,15 +42,11 @@ export function disposeUiEffect(block: BlockSvg) { // Deeply clone the current block. const clone: SVGGElement = svgGroup.cloneNode(true) as SVGGElement; clone.setAttribute('transform', 'translate(' + xy.x + ',' + xy.y + ')'); - if (workspace.isDragging()) { - workspace.getLayerManager()?.moveToDragLayer({ - getSvgRoot: () => { - return clone; - }, - }); - } else { - workspace.getLayerManager()?.getBlockLayer().appendChild(clone); - } + workspace.getLayerManager()?.appendToAnimationLayer({ + getSvgRoot: () => { + return clone; + }, + }); const cloneRect = { 'x': xy.x, 'y': xy.y, diff --git a/core/css.ts b/core/css.ts index 9940c9fad..5a44cc0b6 100644 --- a/core/css.ts +++ b/core/css.ts @@ -500,7 +500,7 @@ input[type=number] { margin-right: -24px; } -.blocklyBlockDragSurface { +.blocklyBlockDragSurface, .blocklyAnimationLayer { position: absolute; top: 0; left: 0; diff --git a/core/dragging/dragger.ts b/core/dragging/dragger.ts index c86d8b1ea..71cfae471 100644 --- a/core/dragging/dragger.ts +++ b/core/dragging/dragger.ts @@ -14,6 +14,8 @@ import {ComponentManager} from '../component_manager.js'; import {IDeleteArea} from '../interfaces/i_delete_area.js'; import * as registry from '../registry.js'; import * as eventUtils from '../events/utils.js'; +import * as blockAnimations from '../block_animations.js'; +import {BlockSvg} from '../block_svg.js'; export class Dragger implements IDragger { protected startLoc: Coordinate; @@ -105,12 +107,18 @@ export class Dragger implements IDragger { this.draggable.revertDrag(); } + const wouldDelete = + isDeletable(this.draggable) && + this.wouldDeleteDraggable(e, this.draggable); + + // TODO(#8148): use a generalized API instead of an instanceof check. + if (wouldDelete && this.draggable instanceof BlockSvg) { + blockAnimations.disposeUiEffect(this.draggable); + } + this.draggable.endDrag(e); - if ( - isDeletable(this.draggable) && - this.wouldDeleteDraggable(e, this.draggable) - ) { + if (wouldDelete && isDeletable(this.draggable)) { // We want to make sure the delete gets grouped with any possible // move event. const newGroup = eventUtils.getGroup(); diff --git a/core/layer_manager.ts b/core/layer_manager.ts index c27339d9b..e181e6801 100644 --- a/core/layer_manager.ts +++ b/core/layer_manager.ts @@ -15,6 +15,8 @@ import {Coordinate} from './utils/coordinate.js'; export class LayerManager { /** The layer elements being dragged are appended to. */ private dragLayer: SVGGElement | undefined; + /** The layer elements being animated are appended to. */ + private animationLayer: SVGGElement | undefined; /** The layers elements not being dragged are appended to. */ private layers = new Map(); @@ -26,6 +28,7 @@ export class LayerManager { // been appended yet. if (injectionDiv) { this.dragLayer = this.createDragLayer(injectionDiv); + this.animationLayer = this.createAnimationLayer(injectionDiv); } // We construct these manually so we can add the css class for backwards @@ -48,6 +51,35 @@ export class LayerManager { return dom.createSvgElement(Svg.G, {}, svg); } + private createAnimationLayer(injectionDiv: Element) { + const svg = dom.createSvgElement(Svg.SVG, { + 'class': 'blocklyAnimationLayer', + 'xmlns': dom.SVG_NS, + 'xmlns:html': dom.HTML_NS, + 'xmlns:xlink': dom.XLINK_NS, + 'version': '1.1', + }); + injectionDiv.append(svg); + return dom.createSvgElement(Svg.G, {}, svg); + } + + /** + * Appends the element to the animation layer. The animation layer doesn't + * move when the workspace moves, so e.g. delete animations don't move + * when a block delete triggers a workspace resize. + * + * @internal + */ + appendToAnimationLayer(elem: IRenderedElement) { + const currentTransform = this.dragLayer?.getAttribute('transform'); + // Only update the current transform when appending, so animations don't + // move if the workspace moves. + if (currentTransform) { + this.animationLayer?.setAttribute('transform', currentTransform); + } + this.animationLayer?.appendChild(elem.getSvgRoot()); + } + /** * Translates layers when the workspace is dragged or zoomed. *