Canvas cursor draw - do not use save and restore. (#9)

This commit is contained in:
Miroslav Šedivý 2022-08-25 00:14:47 +02:00 committed by GitHub
parent bada3d1243
commit 9a77f6adea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 28 deletions

View File

@ -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() {

View File

@ -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<number, boolean>
@ -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()
}
}

View File

@ -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