fix(tracker): change canvas scaling (#1894); fix canvas replay

* fix(tracker): change canvas scaling

* fix(tracker): 12.0.3

* fix(tracker): 12.0.3
This commit is contained in:
Delirium 2024-02-19 16:48:37 +01:00 committed by GitHub
parent 5ff0d61ffb
commit d84371e17e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 41 additions and 12 deletions

View file

@ -2,8 +2,6 @@ import { VElement } from "Player/web/managers/DOM/VirtualDOM";
export default class CanvasManager {
private fileData: string | undefined;
private canvasEl: HTMLVideoElement
private canvasCtx: CanvasRenderingContext2D | null = null;
private videoTag = document.createElement('video')
private lastTs = 0;
@ -38,10 +36,6 @@ export default class CanvasManager {
this.videoTag.setAttribute('crossorigin', 'anonymous');
this.videoTag.src = this.fileData;
this.videoTag.currentTime = 0;
const node = this.getNode(parseInt(this.nodeId, 10)) as unknown as VElement
this.canvasCtx = (node.node as HTMLCanvasElement).getContext('2d');
this.canvasEl = node.node as HTMLVideoElement;
}
move(t: number) {
@ -49,11 +43,14 @@ export default class CanvasManager {
this.lastTs = t;
const playTime = t - this.delta
if (playTime > 0) {
const node = this.getNode(parseInt(this.nodeId, 10)) as unknown as VElement
const canvasCtx = (node.node as HTMLCanvasElement).getContext('2d');
const canvasEl = node.node as HTMLVideoElement;
if (!this.videoTag.paused) {
void this.videoTag.pause()
}
this.videoTag.currentTime = playTime/1000;
this.canvasCtx?.drawImage(this.videoTag, 0, 0, this.canvasEl.width, this.canvasEl.height);
canvasCtx?.drawImage(this.videoTag, 0, 0, canvasEl.width, canvasEl.height);
}
}
}

View file

@ -1,3 +1,7 @@
# 12.0.3
- fixed scaling option for canvas (to ignore window.devicePixelRatio and always render the canvas as 1)
# 12.0.2
- fix for canvas snapshot check

View file

@ -1,7 +1,7 @@
{
"name": "@openreplay/tracker",
"description": "The OpenReplay tracker main package",
"version": "12.0.2",
"version": "12.0.3",
"keywords": [
"logging",
"replay"

View file

@ -6,12 +6,14 @@ interface CanvasSnapshot {
images: { data: string; id: number }[]
createdAt: number
paused: boolean
dummy: HTMLCanvasElement
}
interface Options {
fps: number
quality: 'low' | 'medium' | 'high'
isDebug?: boolean
fixedScaling?: boolean
}
class CanvasRecorder {
@ -84,6 +86,7 @@ class CanvasRecorder {
images: [],
createdAt: ts,
paused: false,
dummy: document.createElement('canvas'),
}
const canvasMsg = CanvasNode(id.toString(), ts)
this.app.send(canvasMsg as Message)
@ -95,7 +98,12 @@ class CanvasRecorder {
clearInterval(int)
} else {
if (!this.snapshots[id].paused) {
const snapshot = captureSnapshot(canvas, this.options.quality)
const snapshot = captureSnapshot(
canvas,
this.options.quality,
this.snapshots[id].dummy,
this.options.fixedScaling,
)
this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot })
if (this.snapshots[id].images.length > 9) {
this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt)
@ -143,14 +151,31 @@ class CanvasRecorder {
}
const qualityInt = {
low: 0.33,
low: 0.35,
medium: 0.55,
high: 0.8,
}
function captureSnapshot(canvas: HTMLCanvasElement, quality: 'low' | 'medium' | 'high' = 'medium') {
function captureSnapshot(
canvas: HTMLCanvasElement,
quality: 'low' | 'medium' | 'high' = 'medium',
dummy: HTMLCanvasElement,
fixedScaling = false,
) {
const imageFormat = 'image/jpeg' // or /png'
return canvas.toDataURL(imageFormat, qualityInt[quality])
if (fixedScaling) {
const canvasScaleRatio = window.devicePixelRatio || 1
dummy.width = canvas.width / canvasScaleRatio
dummy.height = canvas.height / canvasScaleRatio
const ctx = dummy.getContext('2d')
if (!ctx) {
return ''
}
ctx.drawImage(canvas, 0, 0, dummy.width, dummy.height)
return dummy.toDataURL(imageFormat, qualityInt[quality])
} else {
return canvas.toDataURL(imageFormat, qualityInt[quality])
}
}
function dataUrlToBlob(dataUrl: string): [Blob, Uint8Array] | null {

View file

@ -117,6 +117,7 @@ type AppOptions = {
__debug_report_edp: string | null
__debug__?: ILogLevel
__save_canvas_locally?: boolean
fixedCanvasScaling?: boolean
localStorage: Storage | null
sessionStorage: Storage | null
forceSingleTab?: boolean
@ -211,6 +212,7 @@ export default class App {
disableStringDict: false,
forceSingleTab: false,
assistSocketHost: '',
fixedCanvasScaling: false,
},
options,
)
@ -1063,6 +1065,7 @@ export default class App {
fps: canvasFPS,
quality: canvasQuality,
isDebug: this.options.__save_canvas_locally,
fixedScaling: this.options.fixedCanvasScaling,
})
this.canvasRecorder.startTracking()
}