@@ -17,6 +17,7 @@ import * as Constants from '../constants';
1717import { Direction , getXYFromDirection } from '../drag_direction' ;
1818import { KeyboardDragStrategy } from '../keyboard_drag_strategy' ;
1919import { Navigation } from '../navigation' ;
20+ import { blocks } from 'node_modules/blockly/core/serialization' ;
2021
2122/**
2223 * The distance to move an item, in workspace coordinates, when
@@ -55,6 +56,11 @@ export class Mover {
5556 */
5657 private oldDragStrategy : IDragStrategy | null = null ;
5758
59+ /**
60+ * Temporary element indicating a move.
61+ */
62+ private currentMoveIndicator : SVGElement | null = null ;
63+
5864 constructor ( protected navigation : Navigation ) { }
5965
6066 /**
@@ -101,6 +107,7 @@ export class Mover {
101107 const cursor = workspace ?. getCursor ( ) ;
102108 const block = this . getCurrentBlock ( workspace ) ;
103109 if ( ! cursor || ! block ) throw new Error ( 'precondition failure' ) ;
110+ this . addMoveIndicator ( block ) ;
104111
105112 // Select and focus block.
106113 common . setSelected ( block ) ;
@@ -133,6 +140,8 @@ export class Mover {
133140 * @returns True iff move successfully finished.
134141 */
135142 finishMove ( workspace : WorkspaceSvg ) {
143+ this . removeMoveIndicator ( ) ;
144+
136145 const info = this . moves . get ( workspace ) ;
137146 if ( ! info ) throw new Error ( 'no move info for workspace' ) ;
138147
@@ -156,6 +165,8 @@ export class Mover {
156165 * @returns True iff move successfully aborted.
157166 */
158167 abortMove ( workspace : WorkspaceSvg ) {
168+ this . removeMoveIndicator ( ) ;
169+
159170 const info = this . moves . get ( workspace ) ;
160171 if ( ! info ) throw new Error ( 'no move info for workspace' ) ;
161172
@@ -307,6 +318,42 @@ export class Mover {
307318 this . oldDragStrategy = null ;
308319 }
309320 }
321+
322+ private addMoveIndicator ( block : BlockSvg ) : void {
323+ this . removeMoveIndicator ( ) ;
324+ const blockSvgRoot = block . getSvgRoot ( ) ;
325+ // We only move one block.
326+ const bounds = (
327+ blockSvgRoot . querySelector ( '.blocklyPath' ) as SVGGraphicsElement
328+ ) . getBBox ( ) ;
329+ const size = 40 ;
330+ const indicator = utils . dom . createSvgElement ( 'foreignObject' , {
331+ x : bounds . width - size / 2 ,
332+ y : - size / 2 ,
333+ } ) ;
334+ indicator . classList . add ( 'blocklyMoveIndicator' ) ;
335+ indicator . style . width = `${ size } px` ;
336+ indicator . style . height = indicator . style . width ;
337+ indicator . style . backgroundColor = '#fffc' ;
338+ indicator . style . borderRadius = '50%' ;
339+ indicator . style . border = '1px solid grey' ;
340+ indicator . style . padding = '5px' ;
341+ const img = indicator . appendChild ( document . createElement ( 'img' ) ) ;
342+ img . style . width = '100%' ;
343+ img . style . height = '100%' ;
344+ // tabler:arrows-move from https://icon-sets.iconify.design/ MIT licensed
345+ // Copyright (c) 2020-2024 Paweł Kuna
346+ // TODO: draw one in SVG?
347+ img . src =
348+ 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIGQ9Im0xOCA5bDMgM2wtMyAzbS0zLTNoNk02IDlsLTMgM2wzIDNtLTMtM2g2bTAgNmwzIDNsMy0zbS0zLTN2Nm0zLTE1bC0zLTNsLTMgM20zLTN2NiIvPjwvc3ZnPg==' ;
349+ blockSvgRoot . appendChild ( indicator ) ;
350+ this . currentMoveIndicator = indicator ;
351+ }
352+
353+ private removeMoveIndicator ( ) {
354+ this . currentMoveIndicator ?. remove ( ) ;
355+ this . currentMoveIndicator = null ;
356+ }
310357}
311358
312359/**
0 commit comments