From 9a77f6adeae8d8f681cac36acc8bc7233ce6fd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Thu, 25 Aug 2022 00:14:47 +0200 Subject: [PATCH] Canvas cursor draw - do not use save and restore. (#9) --- src/component/cursors.vue | 18 +++++++++++------- src/component/overlay.vue | 20 ++++++++++++-------- src/page/main.vue | 17 ++++------------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/component/cursors.vue b/src/component/cursors.vue index da07fbfb..258a92b3 100644 --- a/src/component/cursors.vue +++ b/src/component/cursors.vue @@ -63,8 +63,7 @@ // synchronize intrinsic with extrinsic dimensions const { width, height } = this._overlay.getBoundingClientRect() - this._overlay.width = width * CANVAS_SCALE - this._overlay.height = height * CANVAS_SCALE + this.canvasResize({ width, height }) // store last drawing points this._last_points = {} @@ -74,9 +73,14 @@ @Watch('canvasSize') onCanvasSizeChange({ width, height }: Dimension) { + this.canvasResize({ width, height }) + this.canvasUpdateCursors() + } + + canvasResize({ width, height }: Dimension) { this._overlay.width = width * CANVAS_SCALE this._overlay.height = height * CANVAS_SCALE - this.canvasUpdateCursors() + this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0) } // start as undefined to prevent jumping @@ -107,9 +111,8 @@ } canvasDrawPoints(percent: number = 1) { - // clear & scale canvas + // clear canvas this.canvasClear() - this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0) // draw current position for (const p of this._points) { @@ -204,6 +207,9 @@ x = Math.round((x / this.screenSize.width) * width) y = Math.round((y / this.screenSize.height) * height) + // reset transformation, X and Y will be 0 again + this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0) + // use custom draw function, if available if (this.cursorDraw) { this.cursorDraw(this._ctx, x, y, id) @@ -214,7 +220,6 @@ const cursorTag = this.sessions[id]?.profile.name || '' // draw inactive cursor tag - this._ctx.save() this._ctx.font = '14px Arial, sans-serif' this._ctx.textBaseline = 'top' this._ctx.shadowColor = 'black' @@ -225,7 +230,6 @@ this._ctx.shadowBlur = 0 this._ctx.fillStyle = 'white' this._ctx.fillText(cursorTag, x, y) - this._ctx.restore() } canvasClear() { diff --git a/src/component/overlay.vue b/src/component/overlay.vue index fed71d61..5e57e5ed 100644 --- a/src/component/overlay.vue +++ b/src/component/overlay.vue @@ -124,8 +124,7 @@ // synchronize intrinsic with extrinsic dimensions const { width, height } = this._overlay.getBoundingClientRect() - this._overlay.width = width * CANVAS_SCALE - this._overlay.height = height * CANVAS_SCALE + this.canvasResize({ width, height }) let ctrlKey = 0 let noKeyUp = {} as Record @@ -462,8 +461,7 @@ @Watch('canvasSize') onCanvasSizeChange({ width, height }: Dimension) { - this._overlay.width = width * CANVAS_SCALE - this._overlay.height = height * CANVAS_SCALE + this.canvasResize({ width, height }) this.canvasRequestRedraw() } @@ -482,6 +480,12 @@ } } + canvasResize({ width, height }: Dimension) { + this._overlay.width = width * CANVAS_SCALE + this._overlay.height = height * CANVAS_SCALE + this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0) + } + @Watch('hostId') @Watch('cursorDraw') canvasRequestRedraw() { @@ -512,6 +516,8 @@ // get intrinsic dimensions let { width, height } = this.canvasSize + + // reset transformation, X and Y will be 0 again this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0) // get cursor position @@ -536,10 +542,9 @@ // draw cursor tag const cursorTag = this.sessions[this.hostId]?.profile.name || '' if (cursorTag) { - x += this.cursorImage.width - y += this.cursorImage.height + const x = this.cursorImage.width + const y = this.cursorImage.height - this._ctx.save() this._ctx.font = '14px Arial, sans-serif' this._ctx.textBaseline = 'top' this._ctx.shadowColor = 'black' @@ -550,7 +555,6 @@ this._ctx.shadowBlur = 0 this._ctx.fillStyle = 'white' this._ctx.fillText(cursorTag, x, y) - this._ctx.restore() } } diff --git a/src/page/main.vue b/src/page/main.vue index fdca4cfb..022b655a 100644 --- a/src/page/main.vue +++ b/src/page/main.vue @@ -514,7 +514,6 @@ y -= 4 // draw arrow path - ctx.save() const arrowPath = new Path2D('M5 5L19 12.5L12.3286 14.465L8.29412 20L5 5Z') ctx.globalAlpha = 0.5 ctx.translate(x, y) @@ -527,15 +526,12 @@ ctx.lineJoin = 'round' ctx.strokeStyle = colorDark ctx.stroke(arrowPath) - ctx.restore() - ctx.save() // draw cursor tag if (cursorTag) { - x += 20 // box margin x - y += 20 // box margin y + const x = 20 // box margin x + const y = 20 // box margin y - ctx.save() ctx.globalAlpha = 0.5 ctx.font = '10px Arial, sans-serif' ctx.textBaseline = 'top' @@ -547,7 +543,6 @@ ctx.shadowBlur = 0 ctx.fillStyle = 'white' ctx.fillText(cursorTag, x, y) - ctx.restore() } }, ) @@ -576,7 +571,6 @@ y -= 4 // draw arrow path - ctx.save() const arrowPath = new Path2D('M5 5L26 16.5L15.9929 19.513L9.94118 28L5 5Z') ctx.translate(x, y) ctx.fillStyle = colorLight @@ -588,7 +582,6 @@ ctx.lineJoin = 'round' ctx.strokeStyle = colorDark ctx.stroke(arrowPath) - ctx.restore() // draw cursor tag if (cursorTag) { @@ -596,15 +589,14 @@ const boxPaddingX = 9 const boxPaddingY = 6 - x += 22 // box margin x - y += 28 // box margin y + const x = 22 // box margin x + const y = 28 // box margin y // prepare tag text ctx.font = '500 ' + fontSize + 'px Roboto, sans-serif' ctx.textBaseline = 'ideographic' // create tag container - ctx.save() const txtWidth = ctx.measureText(cursorTag).width const w = txtWidth + boxPaddingX * 2 const h = fontSize + boxPaddingY * 2 @@ -618,7 +610,6 @@ ctx.closePath() ctx.fillStyle = colorDark ctx.fill() - ctx.restore() // fill in tag text ctx.fillStyle = fontColor