52 lines
2.4 KiB
JavaScript
52 lines
2.4 KiB
JavaScript
// Aufzeichnender Canvas-Kontext für die Engine-Tests (Muster: Proxy aus entwuerfe/smoke.js).
|
|
// fillRect/fillText werden mit dem aktuellen fillStyle/font notiert, alles Übrige ist ein No-op.
|
|
|
|
/**
|
|
* makeCtx({ width, height }) → { ctx, rects, texts, strokes, counts, alphas }
|
|
* rects: [{ x, y, w, h, fill }] jedes fillRect
|
|
* texts: [{ text, x, y, font }] jedes fillText (Nicht-String wirft wie im Smoke-Test)
|
|
* strokes: [{ text, x, y, style, width, rects, texts }] jedes strokeText (style/width = strokeStyle/lineWidth, rects/texts =
|
|
* Anzahl der bis dahin gezeichneten fillRect/fillText: so ist die Reihenfolge prüfbar)
|
|
* counts: { save, restore } Aufrufe von ctx.save()/ctx.restore()
|
|
* alphas: [] jede Zuweisung an ctx.globalAlpha
|
|
*/
|
|
export function makeCtx({ width = 960, height = 768 } = {}) {
|
|
const rects = []
|
|
const texts = []
|
|
const strokes = []
|
|
const counts = { save: 0, restore: 0 }
|
|
const alphas = []
|
|
const target = { canvas: { width, height }, fillStyle: '#000000', font: '10px sans-serif', globalAlpha: 1 }
|
|
const ctx = new Proxy(target, {
|
|
get(t, prop) {
|
|
if (typeof prop === 'symbol') return undefined
|
|
if (prop === 'save') return () => { counts.save++ }
|
|
if (prop === 'restore') return () => { counts.restore++ }
|
|
if (prop === 'measureText') return (text) => ({ width: String(text).length * 7 })
|
|
if (prop === 'fillRect') return (x, y, w, h) => { rects.push({ x, y, w, h, fill: t.fillStyle }) }
|
|
if (prop === 'fillText') {
|
|
return (text, x, y) => {
|
|
if (typeof text !== 'string') throw new Error('fillText mit Nicht-String: ' + text)
|
|
texts.push({ text, x, y, font: t.font })
|
|
}
|
|
}
|
|
if (prop === 'strokeText') {
|
|
return (text, x, y) => {
|
|
if (typeof text !== 'string') throw new Error('strokeText mit Nicht-String: ' + text)
|
|
strokes.push({ text, x, y, style: t.strokeStyle, width: t.lineWidth, rects: rects.length, texts: texts.length })
|
|
}
|
|
}
|
|
if (prop === 'createLinearGradient' || prop === 'createRadialGradient') return () => ({ addColorStop() {} })
|
|
if (prop === 'getImageData') return () => ({ data: new Uint8ClampedArray(4) })
|
|
if (prop in t) return t[prop]
|
|
return () => {}
|
|
},
|
|
set(t, prop, value) {
|
|
if (prop === 'globalAlpha') alphas.push(value)
|
|
t[prop] = value
|
|
return true
|
|
},
|
|
})
|
|
return { ctx, rects, texts, strokes, counts, alphas }
|
|
}
|