Recreate Skia surface on window resize

The WebGL surface is bound to the framebuffer size at creation time.
Resizing the canvas element without recreating the surface left dark
empty space. Now createSurface() is called on every resize.
This commit is contained in:
Danila Poyarkov 2026-02-27 22:03:18 +03:00
parent a3ad587652
commit 0b563ed621

View file

@ -5,20 +5,35 @@ import { getCanvasKit } from '../engine/canvaskit'
import { SkiaRenderer } from '../engine/renderer'
import type { EditorStore } from '../stores/editor'
import type { CanvasKit } from 'canvaskit-wasm'
export function useCanvas(canvasRef: Ref<HTMLCanvasElement | null>, store: EditorStore) {
let renderer: SkiaRenderer | null = null
let ck: CanvasKit | null = null
let destroyed = false
async function init() {
const canvas = canvasRef.value
if (!canvas || destroyed) return
const ck = await getCanvasKit()
ck = await getCanvasKit()
if (destroyed) return
await new Promise((r) => requestAnimationFrame(r))
resizeCanvas(canvas)
createSurface(canvas)
}
function createSurface(canvas: HTMLCanvasElement) {
if (!ck) return
renderer?.destroy()
renderer = null
const dpr = window.devicePixelRatio || 1
const w = canvas.clientWidth
const h = canvas.clientHeight
canvas.width = w * dpr
canvas.height = h * dpr
const surface = ck.MakeWebGLCanvasSurface(canvas)
if (!surface) {
@ -30,16 +45,6 @@ export function useCanvas(canvasRef: Ref<HTMLCanvasElement | null>, store: Edito
render()
}
function resizeCanvas(canvas: HTMLCanvasElement) {
const dpr = window.devicePixelRatio || 1
const w = canvas.clientWidth
const h = canvas.clientHeight
canvas.width = w * dpr
canvas.height = h * dpr
canvas.style.width = `${w}px`
canvas.style.height = `${h}px`
}
function render() {
if (!renderer) return
renderer.dpr = window.devicePixelRatio || 1
@ -60,9 +65,8 @@ export function useCanvas(canvasRef: Ref<HTMLCanvasElement | null>, store: Edito
useResizeObserver(canvasRef, () => {
const canvas = canvasRef.value
if (!canvas || !renderer) return
resizeCanvas(canvas)
render()
if (!canvas || !ck) return
createSurface(canvas)
})
watch(