@@ -304,25 +304,31 @@ class Stage extends React.Component {
304
304
}
305
305
this . setState ( { mouseDownTimeoutId : null } ) ;
306
306
}
307
- drawDragCanvas ( drawableData ) {
307
+ /**
308
+ * Initialize the position of the "dragged sprite" canvas
309
+ * @param {DrawableExtraction } drawableData The data returned from renderer.extractDrawableScreenSpace
310
+ * @param {number } x The x position of the initial drag event
311
+ * @param {number } y The y position of the initial drag event
312
+ */
313
+ drawDragCanvas ( drawableData , x , y ) {
308
314
const {
309
- data ,
310
- width ,
311
- height ,
312
- x ,
313
- y
315
+ imageData ,
316
+ x : boundsX ,
317
+ y : boundsY ,
318
+ width : boundsWidth ,
319
+ height : boundsHeight
314
320
} = drawableData ;
315
- this . dragCanvas . width = width ;
316
- this . dragCanvas . height = height ;
317
- // Need to convert uint8array from WebGL readPixels into Uint8ClampedArray
318
- // for ImageData constructor. Shares underlying buffer, so it is fast.
319
- const imageData = new ImageData (
320
- new Uint8ClampedArray ( data . buffer ) , width , height ) ;
321
+ this . dragCanvas . width = imageData . width ;
322
+ this . dragCanvas . height = imageData . height ;
323
+ // On high-DPI devices, the canvas size in layout-pixels is not equal to the size of the extracted data.
324
+ this . dragCanvas . style . width = ` ${ boundsWidth } px` ;
325
+ this . dragCanvas . style . height = ` ${ boundsHeight } px` ;
326
+
321
327
this . dragCanvas . getContext ( '2d' ) . putImageData ( imageData , 0 , 0 ) ;
322
328
// Position so that pick location is at (0, 0) so that positionDragCanvas()
323
329
// can use translation to move to mouse position smoothly.
324
- this . dragCanvas . style . left = `${ - x } px` ;
325
- this . dragCanvas . style . top = `${ - y } px` ;
330
+ this . dragCanvas . style . left = `${ boundsX - x } px` ;
331
+ this . dragCanvas . style . top = `${ boundsY - y } px` ;
326
332
this . dragCanvas . style . display = 'block' ;
327
333
}
328
334
clearDragCanvas ( ) {
@@ -349,17 +355,20 @@ class Stage extends React.Component {
349
355
// Dragging always brings the target to the front
350
356
target . goToFront ( ) ;
351
357
352
- // Extract the drawable art
353
- const drawableData = this . renderer . extractDrawable ( drawableId , x , y ) ;
358
+ const [ scratchMouseX , scratchMouseY ] = this . getScratchCoords ( x , y ) ;
359
+ const offsetX = target . x - scratchMouseX ;
360
+ const offsetY = - ( target . y + scratchMouseY ) ;
354
361
355
362
this . props . vm . startDrag ( targetId ) ;
356
363
this . setState ( {
357
364
isDragging : true ,
358
365
dragId : targetId ,
359
- dragOffset : drawableData . scratchOffset
366
+ dragOffset : [ offsetX , offsetY ]
360
367
} ) ;
361
368
if ( this . props . useEditorDragStyle ) {
362
- this . drawDragCanvas ( drawableData ) ;
369
+ // Extract the drawable art
370
+ const drawableData = this . renderer . extractDrawableScreenSpace ( drawableId ) ;
371
+ this . drawDragCanvas ( drawableData , x , y ) ;
363
372
this . positionDragCanvas ( x , y ) ;
364
373
this . props . vm . postSpriteInfo ( { visible : false } ) ;
365
374
this . props . vm . renderer . draw ( ) ;
0 commit comments