Skip to content

Commit 9a6bc8f

Browse files
authored
Merge pull request scratchfoundation#5513 from adroitwhiz/drag-new-method
Extract dragged sprites' drawables in screen space
2 parents 46f91f0 + 2573b1b commit 9a6bc8f

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

src/containers/stage.jsx

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -304,25 +304,31 @@ class Stage extends React.Component {
304304
}
305305
this.setState({mouseDownTimeoutId: null});
306306
}
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) {
308314
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
314320
} = 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+
321327
this.dragCanvas.getContext('2d').putImageData(imageData, 0, 0);
322328
// Position so that pick location is at (0, 0) so that positionDragCanvas()
323329
// 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`;
326332
this.dragCanvas.style.display = 'block';
327333
}
328334
clearDragCanvas () {
@@ -349,17 +355,20 @@ class Stage extends React.Component {
349355
// Dragging always brings the target to the front
350356
target.goToFront();
351357

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);
354361

355362
this.props.vm.startDrag(targetId);
356363
this.setState({
357364
isDragging: true,
358365
dragId: targetId,
359-
dragOffset: drawableData.scratchOffset
366+
dragOffset: [offsetX, offsetY]
360367
});
361368
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);
363372
this.positionDragCanvas(x, y);
364373
this.props.vm.postSpriteInfo({visible: false});
365374
this.props.vm.renderer.draw();

0 commit comments

Comments
 (0)