diff --git a/README.md b/README.md index 4041f5e..e375cee 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,6 @@ further benchmarking and tweaking. * Implement action queue when drawing, only execute drawing on zCanvas.sprite.update()-hook * Maintain cache for source images at the display destination size (invalidate on window resize / zoom), this prevents processing large images that are never displayed at their full scale * Dragging of masks on rotated/mirror content is kinda broken -* Animate selection lines between white and black colors * Restored base64 images should be treated as binary once more (see layer-factory) * Zoom set original size isn't that accurate (check also on mobile views), needs calculateMaxScaling ? * Unload Blobs when images are no longer used in document (see sprite-factory disposeSprite, keep instance count of usages) diff --git a/src/components/ui/zcanvas/interaction-pane.js b/src/components/ui/zcanvas/interaction-pane.js index 1579fae..587e6a7 100644 --- a/src/components/ui/zcanvas/interaction-pane.js +++ b/src/components/ui/zcanvas/interaction-pane.js @@ -223,10 +223,6 @@ class InteractionPane extends sprite { // render selection outline if ( /*this.mode === MODE_SELECTION && */ this.document.selection ) { - ctx.save(); - ctx.beginPath(); - ctx.lineWidth = 2 / this.canvas.zoomFactor; - let { selection } = this.document; const firstPoint = selection[ 0 ]; const localPointerX = this._pointerX - viewport.left; // local to viewport @@ -242,21 +238,28 @@ class InteractionPane extends sprite { localPointerY - firstPoint.y + viewport.top ); } - // draw each point in the selection - selection.forEach(( point, index ) => { - ctx[ index === 0 ? "moveTo" : "lineTo" ]( point.x - viewport.left, point.y - viewport.top ); - }); - // for lasso selections, draw line to current cursor position + let currentPosition = null; if ( !this._isRectangleSelect && !this._selectionClosed ) { - ctx.lineTo( localPointerX, localPointerY ); + currentPosition = { x: localPointerX, y: localPointerY }; } - ctx.stroke(); + // draw each point in the selection + ctx.save(); + drawSelectionOutline( ctx, this.canvas, viewport, selection, "#000", currentPosition ); + ctx.restore(); + + ctx.save(); + ctx.setLineDash([ 10 / this.canvas.zoomFactor ]); + drawSelectionOutline( ctx, this.canvas, viewport, selection, "#FFF", currentPosition ); + ctx.restore(); + + ctx.save(); // highlight current cursor position for unclosed selections if ( !this._selectionClosed ) { ctx.beginPath(); ctx.lineWidth *= 1.5; + ctx.strokeStyle = "#0db0bc"; const size = firstPoint && isPointInRange( this._pointerX, this._pointerY, firstPoint.x, firstPoint.y ) ? 15 : 5; ctx.arc( localPointerX, localPointerY, size / this.canvas.zoomFactor, 0, 2 * Math.PI ); ctx.stroke(); @@ -273,6 +276,23 @@ export default InteractionPane; /* internal methods */ +function drawSelectionOutline( ctx, zCanvas, viewport, selection, color, currentPosition = null ) { + ctx.lineWidth = 2 / zCanvas.zoomFactor; + ctx.beginPath(); + ctx.strokeStyle = color; + selection.forEach(( point, index ) => { + ctx[ index === 0 ? "moveTo" : "lineTo" ]( + ( .5 + point.x - viewport.left ) << 0, + ( .5 + point.y - viewport.top ) << 0 + ); + }); + // for lasso selections, draw line to current cursor position + if ( currentPosition ) { + ctx.lineTo(( .5 + currentPosition.x ) << 0, ( .5 + currentPosition.y ) << 0 ); + } + ctx.stroke(); +} + function storeSelectionHistory( document, optPreviousSelection = [] ) { const selection = [ ...document.selection ]; enqueueState( `selection_${document.name}`, {