mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
Canvas cursor draw - do not use save and restore. (#9)
This commit is contained in:
parent
bada3d1243
commit
9a77f6adea
@ -63,8 +63,7 @@
|
|||||||
|
|
||||||
// synchronize intrinsic with extrinsic dimensions
|
// synchronize intrinsic with extrinsic dimensions
|
||||||
const { width, height } = this._overlay.getBoundingClientRect()
|
const { width, height } = this._overlay.getBoundingClientRect()
|
||||||
this._overlay.width = width * CANVAS_SCALE
|
this.canvasResize({ width, height })
|
||||||
this._overlay.height = height * CANVAS_SCALE
|
|
||||||
|
|
||||||
// store last drawing points
|
// store last drawing points
|
||||||
this._last_points = {}
|
this._last_points = {}
|
||||||
@ -74,9 +73,14 @@
|
|||||||
|
|
||||||
@Watch('canvasSize')
|
@Watch('canvasSize')
|
||||||
onCanvasSizeChange({ width, height }: Dimension) {
|
onCanvasSizeChange({ width, height }: Dimension) {
|
||||||
|
this.canvasResize({ width, height })
|
||||||
|
this.canvasUpdateCursors()
|
||||||
|
}
|
||||||
|
|
||||||
|
canvasResize({ width, height }: Dimension) {
|
||||||
this._overlay.width = width * CANVAS_SCALE
|
this._overlay.width = width * CANVAS_SCALE
|
||||||
this._overlay.height = height * 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
|
// start as undefined to prevent jumping
|
||||||
@ -107,9 +111,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvasDrawPoints(percent: number = 1) {
|
canvasDrawPoints(percent: number = 1) {
|
||||||
// clear & scale canvas
|
// clear canvas
|
||||||
this.canvasClear()
|
this.canvasClear()
|
||||||
this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0)
|
|
||||||
|
|
||||||
// draw current position
|
// draw current position
|
||||||
for (const p of this._points) {
|
for (const p of this._points) {
|
||||||
@ -204,6 +207,9 @@
|
|||||||
x = Math.round((x / this.screenSize.width) * width)
|
x = Math.round((x / this.screenSize.width) * width)
|
||||||
y = Math.round((y / this.screenSize.height) * height)
|
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
|
// use custom draw function, if available
|
||||||
if (this.cursorDraw) {
|
if (this.cursorDraw) {
|
||||||
this.cursorDraw(this._ctx, x, y, id)
|
this.cursorDraw(this._ctx, x, y, id)
|
||||||
@ -214,7 +220,6 @@
|
|||||||
const cursorTag = this.sessions[id]?.profile.name || ''
|
const cursorTag = this.sessions[id]?.profile.name || ''
|
||||||
|
|
||||||
// draw inactive cursor tag
|
// draw inactive cursor tag
|
||||||
this._ctx.save()
|
|
||||||
this._ctx.font = '14px Arial, sans-serif'
|
this._ctx.font = '14px Arial, sans-serif'
|
||||||
this._ctx.textBaseline = 'top'
|
this._ctx.textBaseline = 'top'
|
||||||
this._ctx.shadowColor = 'black'
|
this._ctx.shadowColor = 'black'
|
||||||
@ -225,7 +230,6 @@
|
|||||||
this._ctx.shadowBlur = 0
|
this._ctx.shadowBlur = 0
|
||||||
this._ctx.fillStyle = 'white'
|
this._ctx.fillStyle = 'white'
|
||||||
this._ctx.fillText(cursorTag, x, y)
|
this._ctx.fillText(cursorTag, x, y)
|
||||||
this._ctx.restore()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvasClear() {
|
canvasClear() {
|
||||||
|
@ -124,8 +124,7 @@
|
|||||||
|
|
||||||
// synchronize intrinsic with extrinsic dimensions
|
// synchronize intrinsic with extrinsic dimensions
|
||||||
const { width, height } = this._overlay.getBoundingClientRect()
|
const { width, height } = this._overlay.getBoundingClientRect()
|
||||||
this._overlay.width = width * CANVAS_SCALE
|
this.canvasResize({ width, height })
|
||||||
this._overlay.height = height * CANVAS_SCALE
|
|
||||||
|
|
||||||
let ctrlKey = 0
|
let ctrlKey = 0
|
||||||
let noKeyUp = {} as Record<number, boolean>
|
let noKeyUp = {} as Record<number, boolean>
|
||||||
@ -462,8 +461,7 @@
|
|||||||
|
|
||||||
@Watch('canvasSize')
|
@Watch('canvasSize')
|
||||||
onCanvasSizeChange({ width, height }: Dimension) {
|
onCanvasSizeChange({ width, height }: Dimension) {
|
||||||
this._overlay.width = width * CANVAS_SCALE
|
this.canvasResize({ width, height })
|
||||||
this._overlay.height = height * CANVAS_SCALE
|
|
||||||
this.canvasRequestRedraw()
|
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('hostId')
|
||||||
@Watch('cursorDraw')
|
@Watch('cursorDraw')
|
||||||
canvasRequestRedraw() {
|
canvasRequestRedraw() {
|
||||||
@ -512,6 +516,8 @@
|
|||||||
|
|
||||||
// get intrinsic dimensions
|
// get intrinsic dimensions
|
||||||
let { width, height } = this.canvasSize
|
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)
|
this._ctx.setTransform(CANVAS_SCALE, 0, 0, CANVAS_SCALE, 0, 0)
|
||||||
|
|
||||||
// get cursor position
|
// get cursor position
|
||||||
@ -536,10 +542,9 @@
|
|||||||
// draw cursor tag
|
// draw cursor tag
|
||||||
const cursorTag = this.sessions[this.hostId]?.profile.name || ''
|
const cursorTag = this.sessions[this.hostId]?.profile.name || ''
|
||||||
if (cursorTag) {
|
if (cursorTag) {
|
||||||
x += this.cursorImage.width
|
const x = this.cursorImage.width
|
||||||
y += this.cursorImage.height
|
const y = this.cursorImage.height
|
||||||
|
|
||||||
this._ctx.save()
|
|
||||||
this._ctx.font = '14px Arial, sans-serif'
|
this._ctx.font = '14px Arial, sans-serif'
|
||||||
this._ctx.textBaseline = 'top'
|
this._ctx.textBaseline = 'top'
|
||||||
this._ctx.shadowColor = 'black'
|
this._ctx.shadowColor = 'black'
|
||||||
@ -550,7 +555,6 @@
|
|||||||
this._ctx.shadowBlur = 0
|
this._ctx.shadowBlur = 0
|
||||||
this._ctx.fillStyle = 'white'
|
this._ctx.fillStyle = 'white'
|
||||||
this._ctx.fillText(cursorTag, x, y)
|
this._ctx.fillText(cursorTag, x, y)
|
||||||
this._ctx.restore()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +514,6 @@
|
|||||||
y -= 4
|
y -= 4
|
||||||
|
|
||||||
// draw arrow path
|
// draw arrow path
|
||||||
ctx.save()
|
|
||||||
const arrowPath = new Path2D('M5 5L19 12.5L12.3286 14.465L8.29412 20L5 5Z')
|
const arrowPath = new Path2D('M5 5L19 12.5L12.3286 14.465L8.29412 20L5 5Z')
|
||||||
ctx.globalAlpha = 0.5
|
ctx.globalAlpha = 0.5
|
||||||
ctx.translate(x, y)
|
ctx.translate(x, y)
|
||||||
@ -527,15 +526,12 @@
|
|||||||
ctx.lineJoin = 'round'
|
ctx.lineJoin = 'round'
|
||||||
ctx.strokeStyle = colorDark
|
ctx.strokeStyle = colorDark
|
||||||
ctx.stroke(arrowPath)
|
ctx.stroke(arrowPath)
|
||||||
ctx.restore()
|
|
||||||
ctx.save()
|
|
||||||
|
|
||||||
// draw cursor tag
|
// draw cursor tag
|
||||||
if (cursorTag) {
|
if (cursorTag) {
|
||||||
x += 20 // box margin x
|
const x = 20 // box margin x
|
||||||
y += 20 // box margin y
|
const y = 20 // box margin y
|
||||||
|
|
||||||
ctx.save()
|
|
||||||
ctx.globalAlpha = 0.5
|
ctx.globalAlpha = 0.5
|
||||||
ctx.font = '10px Arial, sans-serif'
|
ctx.font = '10px Arial, sans-serif'
|
||||||
ctx.textBaseline = 'top'
|
ctx.textBaseline = 'top'
|
||||||
@ -547,7 +543,6 @@
|
|||||||
ctx.shadowBlur = 0
|
ctx.shadowBlur = 0
|
||||||
ctx.fillStyle = 'white'
|
ctx.fillStyle = 'white'
|
||||||
ctx.fillText(cursorTag, x, y)
|
ctx.fillText(cursorTag, x, y)
|
||||||
ctx.restore()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -576,7 +571,6 @@
|
|||||||
y -= 4
|
y -= 4
|
||||||
|
|
||||||
// draw arrow path
|
// draw arrow path
|
||||||
ctx.save()
|
|
||||||
const arrowPath = new Path2D('M5 5L26 16.5L15.9929 19.513L9.94118 28L5 5Z')
|
const arrowPath = new Path2D('M5 5L26 16.5L15.9929 19.513L9.94118 28L5 5Z')
|
||||||
ctx.translate(x, y)
|
ctx.translate(x, y)
|
||||||
ctx.fillStyle = colorLight
|
ctx.fillStyle = colorLight
|
||||||
@ -588,7 +582,6 @@
|
|||||||
ctx.lineJoin = 'round'
|
ctx.lineJoin = 'round'
|
||||||
ctx.strokeStyle = colorDark
|
ctx.strokeStyle = colorDark
|
||||||
ctx.stroke(arrowPath)
|
ctx.stroke(arrowPath)
|
||||||
ctx.restore()
|
|
||||||
|
|
||||||
// draw cursor tag
|
// draw cursor tag
|
||||||
if (cursorTag) {
|
if (cursorTag) {
|
||||||
@ -596,15 +589,14 @@
|
|||||||
const boxPaddingX = 9
|
const boxPaddingX = 9
|
||||||
const boxPaddingY = 6
|
const boxPaddingY = 6
|
||||||
|
|
||||||
x += 22 // box margin x
|
const x = 22 // box margin x
|
||||||
y += 28 // box margin y
|
const y = 28 // box margin y
|
||||||
|
|
||||||
// prepare tag text
|
// prepare tag text
|
||||||
ctx.font = '500 ' + fontSize + 'px Roboto, sans-serif'
|
ctx.font = '500 ' + fontSize + 'px Roboto, sans-serif'
|
||||||
ctx.textBaseline = 'ideographic'
|
ctx.textBaseline = 'ideographic'
|
||||||
|
|
||||||
// create tag container
|
// create tag container
|
||||||
ctx.save()
|
|
||||||
const txtWidth = ctx.measureText(cursorTag).width
|
const txtWidth = ctx.measureText(cursorTag).width
|
||||||
const w = txtWidth + boxPaddingX * 2
|
const w = txtWidth + boxPaddingX * 2
|
||||||
const h = fontSize + boxPaddingY * 2
|
const h = fontSize + boxPaddingY * 2
|
||||||
@ -618,7 +610,6 @@
|
|||||||
ctx.closePath()
|
ctx.closePath()
|
||||||
ctx.fillStyle = colorDark
|
ctx.fillStyle = colorDark
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.restore()
|
|
||||||
|
|
||||||
// fill in tag text
|
// fill in tag text
|
||||||
ctx.fillStyle = fontColor
|
ctx.fillStyle = fontColor
|
||||||
|
Loading…
Reference in New Issue
Block a user