Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: feat/支持 Canvas Web 异步版本 #313

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

imsenyu
Copy link
Collaborator

@imsenyu imsenyu commented Feb 10, 2025

在支付宝小程序中,可以使用最早期的 小程序异步版本 Canvas 「以下用 CanvasContext 来指代」来满足图形绘制需求(而不需要强依赖新版本的 Canvas 同层实现能力)

实现方案

原始依赖的 CanvasElement 和 getContext('2d') 「以下用 CanvasRenderingContext2D 来指代」 提供了与 W3C 完全一致的 API,但是降级版本的 CanvasContext 内部实现为异步指令批量发送模式,并且需要主动调用 context.draw() 来触发指令提交,因此 API 调用上有如下差异

模拟实现

  • CanvasElement
    • createImage(API 对接到 my.preloadCanvasImage,提供 onload / onerror 回调)
    • requestAnimationFrame(API 对接到 setTimeout,并且在每次结束主动调用 canvasContext.draw() 来同步指令)
    • cancelAnimationFrame
  • 模拟的 CanvasRenderingContext2D (API 对接到 CanvasContext)
    • 实际支持度见下表

注意事项

仅假设「Canvas 同层实现能力」不可用,而 「my.createOffscreenCanvas」仍然可用,因此涉及到 OffscreenCanvas 的调用均未处理

API 支持度

未提供以下 API 支持

  • filter
  • imageSmoothingEnabled
  • shadowBlur
  • shadowColor
  • shadowOffsetX
  • shadowOffsetY
  • createImageData
  • createPath2D
  • getImageData
  • getLineDash
  • getTransform
  • isPointInPath(仅 OffscreenCanvas 使用,不受影响)
  • isPointInStroke
  • measureText(仅 OffscreenCanvas 使用,不受影响)
  • putImageData
  • roundRect

提供了以下 API 的兼容

属性

注意,由于 CanvasContext 为异步指令批量发送模式,此处所有 get 属性均为模拟实现

  • set fillStyle
  • get fillStyle
  • set font
  • get font
  • set fontSize
  • set globalAlpha
  • get globalAlpha
  • set globalCompositeOperation
  • get globalCompositeOperation
  • set lineCap
  • get lineCap
  • set lineDashOffset
  • get lineDashOffset
  • set lineJoin
  • get lineJoin
  • set lineWidth
  • get lineWidth
  • set miterLimit
  • get miterLimit
  • set strokeStyle
  • get strokeStyle
  • set textAlign
  • get textAlign
  • set textBaseline
  • get textBaseline

方法

  • arc(x: number, y: number, radius: number, startDeg: number, endDeg: number, anticlockwise?: boolean)
  • arcTo(x1: number, y1: number, x2: number, y2: number, radius: number)
  • beginPath()
  • bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number)
  • clearRect(x: number, y: number, width: number, height: number)
  • clip()
  • closePath()
  • createLinearGradient(x0: number, y0: number, x1: number, y1: number)
  • createPattern(image: TCanvasImageSource, repeat: TCanvasPatternRepeat)
  • createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number)
  • drawImage(image: TCanvasImageSource, sx: number, sy: number, sWidth?: number, sHeight?: number, dx?: number, dy?: number, dWidth?: number, dHeight?: number)
  • ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean)
  • fill()
  • fillRect(x: number, y: number, width: number, height: number)
  • fillText(text: string, x: number, y: number, maxWidth?: number)
  • lineTo(x: number, y: number)
  • moveTo(x: number, y: number)
  • quadraticCurveTo(cpx: number, cpy: number, x: number, y: number)
  • rect(x: number, y: number, width: number, height: number)
  • resetTransform()
  • restore()
  • rotate(angle: number)
  • save()
  • scale(x: number, y: number)
  • setLineDash(gaps: number[])
  • setTransform(a: number, b: number, c: number, d: number, e: number, f: number)
  • stroke()
  • strokeRect(x: number, y: number, width: number, height: number)
  • strokeText(text: string, x: number, y: number, maxWidth?: number)
  • transform(a: number, b: number, c: number, d: number, e: number, f: number)
  • translate(x: number, y: number)

@xiaowoxiaowo xiaowoxiaowo force-pushed the feat/miniprogram-support-webcanvas branch from 4a1ff8d to c2e5962 Compare February 13, 2025 08:49
xiaowoxiaowo and others added 4 commits February 13, 2025 17:39
* chore(release): release

* chore: 修复ci

---------

Co-authored-by: xuying.xu <[email protected]>
* chore(release): release

* chore: 修复build失败

---------

Co-authored-by: xuying.xu <[email protected]>
* chore(release): release

* chore: 修复build失败

* feat: offscreenCanvas代替setTimeout

---------

Co-authored-by: xuying.xu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants