From 286a740f745b533f9bee247f51344ebbbeaf7a60 Mon Sep 17 00:00:00 2001 From: mayintao3 Date: Thu, 7 Mar 2024 15:16:28 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E6=96=B0=E5=BB=BAcanvas=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components-harmony-ets/canvas.ets | 11 ++ .../src/runtime-ets/dom/element/canvas.ts | 15 +++ .../src/runtime-ets/dom/element/element.ts | 105 +++++++++++------- .../src/runtime-ets/dom/element/index.ts | 6 +- .../src/harmony/template/render.ts | 4 + 5 files changed, 96 insertions(+), 45 deletions(-) create mode 100644 packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets create mode 100644 packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts diff --git a/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets b/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets new file mode 100644 index 000000000000..5c3d58006ed9 --- /dev/null +++ b/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets @@ -0,0 +1,11 @@ +import type { TaroCanvasElement } from '@tarojs/runtime' + + +@Component +export default struct TaroCanvas { + @ObjectLink node: TaroCanvasElement + + build() { + Canvas(this.node.context) + } +} diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts new file mode 100644 index 000000000000..fb4214ed8588 --- /dev/null +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts @@ -0,0 +1,15 @@ +import { TaroElement } from './element' + +import type { CanvasProps, CanvasTouchEvent } from '@tarojs/components/types' + +@Observed +export class TaroCanvasElement extends TaroElement { + settings: RenderingContextSettings + context: CanvasRenderingContext2D + + constructor() { + this.settings = new RenderingContextSettings(true) + this.context = new CanvasRenderingContext2D(this.settings) + super('Canvas') + } +} diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/element.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/element.ts index cce7acb2f7d9..87eafbecccab 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/dom/element/element.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/element.ts @@ -9,11 +9,11 @@ import { ClassList } from '../class-list' import { NodeType, TaroNode } from '../node' import StyleSheet, { HarmonyStyle } from '../stylesheet' -import type { StandardProps } from '@tarojs/components/types' +import type { BaseTouchEvent, ITouchEvent, StandardProps } from '@tarojs/components/types' import type { TaroAny } from '../../utils' import type { ICSSStyleDeclaration } from '../cssStyleDeclaration' -type NamedNodeMap = ({ name: string, value: string })[] +type NamedNodeMap = { name: string, value: string }[] export interface TaroExtraProps { compileMode?: string | boolean @@ -21,7 +21,10 @@ export interface TaroExtraProps { disabled?: boolean } -export class TaroElement extends TaroNode { +export class TaroElement< + T extends StandardProps = StandardProps, + U extends BaseTouchEvent = ITouchEvent +> extends TaroNode { public _innerHTML = '' public _nodeInfo: TaroAny = {} public readonly tagName: string @@ -36,30 +39,30 @@ export class TaroElement extends TaroNo bindAnimation(this) } - public set id (value: string) { + public set id(value: string) { this.setAttribute('id', value) } - public get id (): string { + public get id(): string { return this.getAttribute('id') || this._nid } - public set className (value: string) { + public set className(value: string) { this.setAttribute('class', value) } - public get className (): string { + public get className(): string { return this.getAttribute('class') || '' } - public get classList (): ClassList { + public get classList(): ClassList { return new ClassList(this.className, this) } - public get attributes (): NamedNodeMap { + public get attributes(): NamedNodeMap { const list: NamedNodeMap = [] - Object.keys(this._attrs).forEach(name => { + Object.keys(this._attrs).forEach((name) => { const value: TaroAny = this._attrs[name] list.push({ name, value }) @@ -68,11 +71,11 @@ export class TaroElement extends TaroNo return list } - public get children (): TaroElement[] { - return this.childNodes.filter(node => node.nodeType === NodeType.ELEMENT_NODE) as TaroElement[] + public get children(): TaroElement[] { + return this.childNodes.filter((node) => node.nodeType === NodeType.ELEMENT_NODE) as TaroElement[] } - public setAttribute (name: string, value: TaroAny): void { + public setAttribute(name: string, value: TaroAny): void { switch (name) { case ID: eventSource.delete(this._attrs.id) @@ -106,48 +109,64 @@ export class TaroElement extends TaroNo } } - public getAttribute (name: string): string { + public getAttribute(name: string): string { return this._attrs[name] } - public removeAttribute (name: string): void { + public removeAttribute(name: string): void { this._attrs[name] = null } - public hasAttribute (name: string): boolean { + public hasAttribute(name: string): boolean { return !!this._attrs[name] } - public hasAttributes (): boolean { + public hasAttributes(): boolean { return Object.keys(this._attrs).length > 0 } - public getElementById (id: string | undefined | null) { - return findChildNodeWithDFS(this as TaroAny, (el) => { - return el.id === id - }, false) + public getElementById(id: string | undefined | null) { + return findChildNodeWithDFS( + this as TaroAny, + (el) => { + return el.id === id + }, + false + ) } - public getElementsByTagName (tagName: string) { - return findChildNodeWithDFS(this as TaroAny, (el) => { - return el.nodeName === tagName || (tagName === '*' && this as TaroAny !== el) - }, true) || [] + public getElementsByTagName(tagName: string) { + return ( + findChildNodeWithDFS( + this as TaroAny, + (el) => { + return el.nodeName === tagName || (tagName === '*' && (this as TaroAny) !== el) + }, + true + ) || [] + ) } - public getElementsByClassName (className: string) { + public getElementsByClassName(className: string) { const classNames = className.trim().split(new RegExp('\\s+')) - return findChildNodeWithDFS(this as TaroAny, (el) => { - const classList = el.classList - return classNames.every(c => { - const bool = classList.contains(c) + return ( + findChildNodeWithDFS( + this as TaroAny, + (el) => { + const classList = el.classList + return classNames.every((c) => { + const bool = classList.contains(c) - return bool - }) - }, true) || [] + return bool + }) + }, + true + ) || [] + ) } - public set innerHTML (value: string) { + public set innerHTML(value: string) { if (this.nodeType === NodeType.ELEMENT_NODE && this.ownerDocument) { const ele = this.ownerDocument.createElement('inner-html') ele._innerHTML = value @@ -155,20 +174,20 @@ export class TaroElement extends TaroNo } } - public get innerHTML (): string { + public get innerHTML(): string { return this._innerHTML } public _st = new StyleSheet() // 经转换后的鸿蒙样式 - public get hmStyle () { + public get hmStyle() { return this._st.hmStyle } public _style: ICSSStyleDeclaration | null = null - public get style (): ICSSStyleDeclaration | null { + public get style(): ICSSStyleDeclaration | null { return this._style } @@ -176,16 +195,16 @@ export class TaroElement extends TaroNo // TODO:可根据实际情况,迁移到具体的组件中,如View、ScrollView中,Text\Image其实是不需要的 public _pseudo_before: StyleSheet | null - public get pseudo_before () { + public get pseudo_before() { return this._pseudo_before?.hmStyle } - public set_pseudo_before (value: HarmonyStyle | null) { + public set_pseudo_before(value: HarmonyStyle | null) { if (value) { if (!this._pseudo_before) { this._pseudo_before = new StyleSheet() } - Object.keys(value).forEach(key => { + Object.keys(value).forEach((key) => { this._pseudo_before![key] = value[key] }) } else { @@ -195,16 +214,16 @@ export class TaroElement extends TaroNo public _pseudo_after: StyleSheet | null - public get pseudo_after () { + public get pseudo_after() { return this._pseudo_after?.hmStyle } - public set_pseudo_after (value: HarmonyStyle | null) { + public set_pseudo_after(value: HarmonyStyle | null) { if (value) { if (!this._pseudo_after) { this._pseudo_after = new StyleSheet() } - Object.keys(value).forEach(key => { + Object.keys(value).forEach((key) => { this._pseudo_after![key] = value[key] }) } else { diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts index 809de49ce5af..884d99be29df 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts @@ -1,5 +1,6 @@ import { Current } from '../../current' import { TaroTextNode } from '../node' +import { TaroCanvasElement } from './canvas' import { TaroElement } from './element' import { FormElement, @@ -55,6 +56,7 @@ export function initHarmonyElement () { case 'icon': return new TaroIconElement() case 'label': return new TaroLabelElement() case 'rich-text': return new TaroRichTextElement() + case 'canvas': return new TaroCanvasElement case 'swiper': return new TaroSwiperElement() case 'swiper-item': return new TaroSwiperItemElement() case 'textarea': return new TaroTextAreaElement() @@ -74,6 +76,7 @@ export function initHarmonyElement () { export { FormElement, TaroButtonElement, + TaroCanvasElement, TaroCheckboxElement, TaroCheckboxGroupElement, TaroElement, @@ -99,5 +102,4 @@ export { TaroTextElement, TaroVideoElement, TaroViewElement, - TaroWebViewElement -} + TaroWebViewElement } diff --git a/packages/taro-vite-runner/src/harmony/template/render.ts b/packages/taro-vite-runner/src/harmony/template/render.ts index bd9e0c8eb456..d61d4ba27c5e 100644 --- a/packages/taro-vite-runner/src/harmony/template/render.ts +++ b/packages/taro-vite-runner/src/harmony/template/render.ts @@ -32,6 +32,7 @@ import TaroRichText from './richText' import TaroProgress from './progress' import TaroInnerHtml from './innerHtml' import TaroScrollView from './scrollView' +import TaroCanvas from './canvas' import TaroMovableArea from './movableArea' import TaroMovableView from './movableView' import { TaroRadio, TaroRadioGroup } from './radio' @@ -64,6 +65,7 @@ import type { TaroMovableViewElement, TaroSwiperElement, TaroSwitchElement, + TaroCanvasElement, TaroSliderElement, TaroScrollViewElement, TaroWebViewElement, @@ -112,6 +114,8 @@ function createChildItem (item: TaroElement) { TaroMovableView({node: item as TaroMovableViewElement }) } else if (item.tagName === 'MOVABLE-AREA') { TaroMovableArea({node: item as TaroMovableAreaElement }) + } else if (item.tagName === 'CANVAS') { + TaroCanvas({ node: item as TaroAny as TaroCanvasElement }) } else if (item.tagName === 'RADIO') { TaroRadio({ node: item as TaroRadioElement }) } else if (item.tagName === 'LABEL') { From 69e221e7a9905c93644065292b3fbe765086ee87 Mon Sep 17 00:00:00 2001 From: mayintao3 Date: Fri, 8 Mar 2024 15:54:42 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90context=E9=80=82?= =?UTF-8?q?=E9=85=8D=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/apis/canvas/index.ts | 11 +- .../src/runtime-ets/dom/element/canvas.ts | 257 +++++++++++++++++- 2 files changed, 264 insertions(+), 4 deletions(-) diff --git a/packages/taro-platform-harmony/src/apis/canvas/index.ts b/packages/taro-platform-harmony/src/apis/canvas/index.ts index 36cff57417c5..c160b5f9d9ef 100644 --- a/packages/taro-platform-harmony/src/apis/canvas/index.ts +++ b/packages/taro-platform-harmony/src/apis/canvas/index.ts @@ -1,12 +1,19 @@ -import { temporarilyNotSupport } from '../utils' +import { eventSource } from '@tarojs/runtime/dist/runtime.esm' +import { TaroCanvasElement } from 'src/runtime-ets' +import { temporarilyNotSupport } from '../utils' // 画布 /** 创建离屏 canvas 实例 */ export const createOffscreenCanvas = /* @__PURE__ */ temporarilyNotSupport('createOffscreenCanvas') /** 创建 canvas 的绘图上下文 CanvasContext 对象 */ -export const createCanvasContext = /* @__PURE__ */ temporarilyNotSupport('createOffscreenCanvas') +// export const createCanvasContext = /* @__PURE__ */ temporarilyNotSupport('createOffscreenCanvas') +export const createCanvasContext = (canvasId: string) => { + const dom = eventSource.get(canvasId) + if (dom) return (dom as unknown as TaroCanvasElement).context + +} /** 把当前画布指定区域的内容导出生成指定大小的图片 */ export const canvasToTempFilePath = /* @__PURE__ */ temporarilyNotSupport('createOffscreenCanvas') diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts index fb4214ed8588..94d73178272f 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts @@ -1,15 +1,268 @@ +import { eventSource, TaroAny, TaroNode } from '@tarojs/runtime' + import { TaroElement } from './element' import type { CanvasProps, CanvasTouchEvent } from '@tarojs/components/types' +// class TaroCanvasContext2D { +// harmonyContext2D: CanvasRenderingContext2D + +// constructor(ctx2D: CanvasRenderingContext2D) { +// this.harmonyContext2D = ctx2D +// } + +// arc(...args: Parameters) { +// this.harmonyContext2D.arc(...args) +// } + +// arcTo(...args: Parameters) { +// this.harmonyContext2D.arcTo(...args) +// } + +// beginPath(...args: Parameters) { +// this.harmonyContext2D.beginPath(...args) +// } + +// bezierCurveTo(...args: Parameters) { +// this.harmonyContext2D.bezierCurveTo(...args) +// } + +// clearRect(...args: Parameters) { +// this.harmonyContext2D.clearRect(...args) +// } + +// clip(...args: Parameters) { +// this.harmonyContext2D.clip(...args) +// } + +// closePath(...args: Parameters) { +// this.harmonyContext2D.closePath(...args) +// } + +// createLinearGradient(...args: Parameters) { +// this.harmonyContext2D.createLinearGradient(...args) +// } + +// createPattern(...args: Parameters) { +// this.harmonyContext2D.createPattern(...args) +// } + +// drawImage(...args: Parameters) { +// this.harmonyContext2D.drawImage(...args) +// } + +// fill(...args: Parameters) { +// this.harmonyContext2D.fill(...args) +// } + +// fillRect(...args: Parameters) { +// this.harmonyContext2D.fillRect(...args) +// } + +// fillText(...args: Parameters) { +// this.harmonyContext2D.fillText(...args) +// } + +// lineTo(...args: Parameters) { +// this.harmonyContext2D.lineTo(...args) +// } + +// measureText(...args: Parameters) { +// this.harmonyContext2D.measureText(...args) +// } + +// moveTo(...args: Parameters) { +// this.harmonyContext2D.moveTo(...args) +// } + +// quadraticCurveTo(...args: Parameters) { +// this.harmonyContext2D.quadraticCurveTo(...args) +// } + +// rect(...args: Parameters) { +// this.harmonyContext2D.rect(...args) +// } + +// restore(...args: Parameters) { +// this.harmonyContext2D.restore(...args) +// } + +// rotate(...args: Parameters) { +// this.harmonyContext2D.rotate(...args) +// } + +// save(...args: Parameters) { +// this.harmonyContext2D.save(...args) +// } + +// scale(...args: Parameters) { +// this.harmonyContext2D.scale(...args) +// } + +// setTransform(...args: Parameters) { +// this.harmonyContext2D.setTransform(...args) +// } + +// stroke(...args: Parameters) { +// this.harmonyContext2D.stroke(...args) +// } + +// strokeRect(...args: Parameters) { +// this.harmonyContext2D.strokeRect(...args) +// } + +// strokeText(...args: Parameters) { +// this.harmonyContext2D.strokeText(...args) +// } + +// transform(...args: Parameters) { +// this.harmonyContext2D.transform(...args) +// } + +// translate(...args: Parameters) { +// this.harmonyContext2D.translate(...args) +// } + +// createCircularGradient() { +// // Not supported now +// } + +// draw() { +// // Not supported now +// } + +// setFillStyle(fillStyle: typeof this.harmonyContext2D.fillStyle) { +// this.harmonyContext2D.fillStyle = fillStyle +// } + +// setFontSize(fontSize: number) { +// const font = this.harmonyContext2D.font.split(' ') +// font[2] = `${fontSize}` +// this.harmonyContext2D.font = font.join(' ') +// } + +// setGlobalAlpha(globalAlpha: typeof this.harmonyContext2D.globalAlpha) { +// this.harmonyContext2D.globalAlpha = globalAlpha +// } + +// setLineCap(lineCap: typeof this.harmonyContext2D.lineCap) { +// this.harmonyContext2D.lineCap = lineCap +// } + +// setLineDash(...args: Parameters) { +// this.harmonyContext2D.setLineDash(...args) +// } + +// setLineJoin(lineJoin: typeof this.harmonyContext2D.lineJoin) { +// this.harmonyContext2D.lineJoin = lineJoin +// } + +// setLineWidth(lineWidth: typeof this.harmonyContext2D.lineWidth) { +// this.harmonyContext2D.lineWidth = lineWidth +// } + +// setMiterLimit(miterLimit: typeof this.harmonyContext2D.miterLimit) { +// this.harmonyContext2D.miterLimit = miterLimit +// } + +// setShadow(offsetX: number, offsetY: number, blur: number, color: string) { +// this.harmonyContext2D.shadowOffsetX = offsetX +// this.harmonyContext2D.shadowOffsetY = offsetY +// this.harmonyContext2D.shadowBlur = blur +// this.harmonyContext2D.shadowColor = color +// } + +// setStrokeStyle(strokeStyle: typeof this.harmonyContext2D.strokeStyle) { +// this.harmonyContext2D.strokeStyle = strokeStyle +// } + +// setTextAlign(textAlign: typeof this.harmonyContext2D.textAlign) { +// this.harmonyContext2D.textAlign = textAlign +// } + +// setTextBaseline(textBaseline: typeof this.harmonyContext2D.textBaseline) { +// this.harmonyContext2D.textBaseline = textBaseline +// } +// } + +class CanvasRenderingContext2DWXAdapter extends CanvasRenderingContext2D { + constructor(settings?: RenderingContextSetting) { + super(settings) + } + + createCircularGradient() { + // Not supported now + } + + draw() { + // Not supported now + } + + setFillStyle(fillStyle: typeof this.fillStyle) { + this.fillStyle = fillStyle + } + + setFontSize(fontSize: number) { + const font = this.font.split(' ') + font[2] = `${fontSize}` + this.font = font.join(' ') + } + + setGlobalAlpha(globalAlpha: typeof this.globalAlpha) { + this.globalAlpha = globalAlpha + } + + setLineCap(lineCap: typeof this.lineCap) { + this.lineCap = lineCap + } + + setLineJoin(lineJoin: typeof this.lineJoin) { + this.lineJoin = lineJoin + } + + setLineWidth(lineWidth: typeof this.lineWidth) { + this.lineWidth = lineWidth + } + + setMiterLimit(miterLimit: typeof this.miterLimit) { + this.miterLimit = miterLimit + } + + setShadow(offsetX: number, offsetY: number, blur: number, color: string) { + this.shadowOffsetX = offsetX + this.shadowOffsetY = offsetY + this.shadowBlur = blur + this.shadowColor = color + } + + setStrokeStyle(strokeStyle: typeof this.strokeStyle) { + this.strokeStyle = strokeStyle + } + + setTextAlign(textAlign: typeof this.textAlign) { + this.textAlign = textAlign + } + + setTextBaseline(textBaseline: typeof this.textBaseline) { + this.textBaseline = textBaseline + } +} + @Observed export class TaroCanvasElement extends TaroElement { settings: RenderingContextSettings context: CanvasRenderingContext2D constructor() { - this.settings = new RenderingContextSettings(true) - this.context = new CanvasRenderingContext2D(this.settings) super('Canvas') + this.settings = new RenderingContextSettings(true) + this.context = new CanvasRenderingContext2DWXAdapter(this.settings) as CanvasRenderingContext2D + } + + public setAttribute(name: string, value: TaroAny): void { + if (name === 'canvasId') { + eventSource.set(value, this as TaroNode) + } + super.setAttribute(name, value) } } From 02c71aea8c4aab79488708fa4536ee6e13727dbe Mon Sep 17 00:00:00 2001 From: mayintao3 Date: Fri, 8 Mar 2024 20:23:36 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90canvas=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/apis/canvas/index.ts | 4 +- .../components-harmony-ets/canvas.ets | 34 ++- .../src/runtime-ets/dom/element/canvas.ts | 237 ++++-------------- 3 files changed, 87 insertions(+), 188 deletions(-) diff --git a/packages/taro-platform-harmony/src/apis/canvas/index.ts b/packages/taro-platform-harmony/src/apis/canvas/index.ts index c160b5f9d9ef..2e276f9cb008 100644 --- a/packages/taro-platform-harmony/src/apis/canvas/index.ts +++ b/packages/taro-platform-harmony/src/apis/canvas/index.ts @@ -10,9 +10,9 @@ export const createOffscreenCanvas = /* @__PURE__ */ temporarilyNotSupport('crea /** 创建 canvas 的绘图上下文 CanvasContext 对象 */ // export const createCanvasContext = /* @__PURE__ */ temporarilyNotSupport('createOffscreenCanvas') export const createCanvasContext = (canvasId: string) => { - const dom = eventSource.get(canvasId) + const dom = eventSource.get(`canvasId-${canvasId}`) + // return dom as TaroCanvasElement if (dom) return (dom as unknown as TaroCanvasElement).context - } /** 把当前画布指定区域的内容导出生成指定大小的图片 */ diff --git a/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets b/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets index 5c3d58006ed9..bb904122442c 100644 --- a/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets +++ b/packages/taro-platform-harmony/src/components/components-harmony-ets/canvas.ets @@ -1,11 +1,43 @@ import type { TaroCanvasElement } from '@tarojs/runtime' +import { cancelAnimationFrame, requestAnimationFrame } from '@tarojs/runtime' @Component export default struct TaroCanvas { @ObjectLink node: TaroCanvasElement + rafId: number = 0 + + + aboutToDisappear() { + if(this.rafId) { + cancelAnimationFrame(this.rafId) + } + } build() { - Canvas(this.node.context) + Canvas(this.node._context) + .width('100%') + .height('100%') + .backgroundColor('#ffff00') + .onReady(() => { + const context = this.node._context + + const draw = () => { + if (this.node._drawList.length) { + while (this.node._drawList.length) { + const item = this.node._drawList.shift() + if (item) { + if (typeof context[item.key] === 'function') { + context[item.key](...[].concat(item.value)) + } else { + context[item.key] = item.value + } + } + } + } + this.rafId = requestAnimationFrame(draw) + } + draw() + }) } } diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts index 94d73178272f..d2bb776b48a1 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts @@ -4,188 +4,7 @@ import { TaroElement } from './element' import type { CanvasProps, CanvasTouchEvent } from '@tarojs/components/types' -// class TaroCanvasContext2D { -// harmonyContext2D: CanvasRenderingContext2D - -// constructor(ctx2D: CanvasRenderingContext2D) { -// this.harmonyContext2D = ctx2D -// } - -// arc(...args: Parameters) { -// this.harmonyContext2D.arc(...args) -// } - -// arcTo(...args: Parameters) { -// this.harmonyContext2D.arcTo(...args) -// } - -// beginPath(...args: Parameters) { -// this.harmonyContext2D.beginPath(...args) -// } - -// bezierCurveTo(...args: Parameters) { -// this.harmonyContext2D.bezierCurveTo(...args) -// } - -// clearRect(...args: Parameters) { -// this.harmonyContext2D.clearRect(...args) -// } - -// clip(...args: Parameters) { -// this.harmonyContext2D.clip(...args) -// } - -// closePath(...args: Parameters) { -// this.harmonyContext2D.closePath(...args) -// } - -// createLinearGradient(...args: Parameters) { -// this.harmonyContext2D.createLinearGradient(...args) -// } - -// createPattern(...args: Parameters) { -// this.harmonyContext2D.createPattern(...args) -// } - -// drawImage(...args: Parameters) { -// this.harmonyContext2D.drawImage(...args) -// } - -// fill(...args: Parameters) { -// this.harmonyContext2D.fill(...args) -// } - -// fillRect(...args: Parameters) { -// this.harmonyContext2D.fillRect(...args) -// } - -// fillText(...args: Parameters) { -// this.harmonyContext2D.fillText(...args) -// } - -// lineTo(...args: Parameters) { -// this.harmonyContext2D.lineTo(...args) -// } - -// measureText(...args: Parameters) { -// this.harmonyContext2D.measureText(...args) -// } - -// moveTo(...args: Parameters) { -// this.harmonyContext2D.moveTo(...args) -// } - -// quadraticCurveTo(...args: Parameters) { -// this.harmonyContext2D.quadraticCurveTo(...args) -// } - -// rect(...args: Parameters) { -// this.harmonyContext2D.rect(...args) -// } - -// restore(...args: Parameters) { -// this.harmonyContext2D.restore(...args) -// } - -// rotate(...args: Parameters) { -// this.harmonyContext2D.rotate(...args) -// } - -// save(...args: Parameters) { -// this.harmonyContext2D.save(...args) -// } - -// scale(...args: Parameters) { -// this.harmonyContext2D.scale(...args) -// } - -// setTransform(...args: Parameters) { -// this.harmonyContext2D.setTransform(...args) -// } - -// stroke(...args: Parameters) { -// this.harmonyContext2D.stroke(...args) -// } - -// strokeRect(...args: Parameters) { -// this.harmonyContext2D.strokeRect(...args) -// } - -// strokeText(...args: Parameters) { -// this.harmonyContext2D.strokeText(...args) -// } - -// transform(...args: Parameters) { -// this.harmonyContext2D.transform(...args) -// } - -// translate(...args: Parameters) { -// this.harmonyContext2D.translate(...args) -// } - -// createCircularGradient() { -// // Not supported now -// } - -// draw() { -// // Not supported now -// } - -// setFillStyle(fillStyle: typeof this.harmonyContext2D.fillStyle) { -// this.harmonyContext2D.fillStyle = fillStyle -// } - -// setFontSize(fontSize: number) { -// const font = this.harmonyContext2D.font.split(' ') -// font[2] = `${fontSize}` -// this.harmonyContext2D.font = font.join(' ') -// } - -// setGlobalAlpha(globalAlpha: typeof this.harmonyContext2D.globalAlpha) { -// this.harmonyContext2D.globalAlpha = globalAlpha -// } - -// setLineCap(lineCap: typeof this.harmonyContext2D.lineCap) { -// this.harmonyContext2D.lineCap = lineCap -// } - -// setLineDash(...args: Parameters) { -// this.harmonyContext2D.setLineDash(...args) -// } - -// setLineJoin(lineJoin: typeof this.harmonyContext2D.lineJoin) { -// this.harmonyContext2D.lineJoin = lineJoin -// } - -// setLineWidth(lineWidth: typeof this.harmonyContext2D.lineWidth) { -// this.harmonyContext2D.lineWidth = lineWidth -// } - -// setMiterLimit(miterLimit: typeof this.harmonyContext2D.miterLimit) { -// this.harmonyContext2D.miterLimit = miterLimit -// } - -// setShadow(offsetX: number, offsetY: number, blur: number, color: string) { -// this.harmonyContext2D.shadowOffsetX = offsetX -// this.harmonyContext2D.shadowOffsetY = offsetY -// this.harmonyContext2D.shadowBlur = blur -// this.harmonyContext2D.shadowColor = color -// } - -// setStrokeStyle(strokeStyle: typeof this.harmonyContext2D.strokeStyle) { -// this.harmonyContext2D.strokeStyle = strokeStyle -// } - -// setTextAlign(textAlign: typeof this.harmonyContext2D.textAlign) { -// this.harmonyContext2D.textAlign = textAlign -// } - -// setTextBaseline(textBaseline: typeof this.harmonyContext2D.textBaseline) { -// this.harmonyContext2D.textBaseline = textBaseline -// } -// } - -class CanvasRenderingContext2DWXAdapter extends CanvasRenderingContext2D { +export class CanvasRenderingContext2DWXAdapter extends CanvasRenderingContext2D { constructor(settings?: RenderingContextSetting) { super(settings) } @@ -247,21 +66,69 @@ class CanvasRenderingContext2DWXAdapter extends CanvasRenderingContext2D { this.textBaseline = textBaseline } } +function getContextKey(obj) { + let currentObj = obj + let res = [] + while (currentObj) { + if (currentObj instanceof CanvasRenderingContext2D) { + res = [...res, ...Object.getOwnPropertyNames(currentObj)] + } + currentObj = Object.getPrototypeOf(currentObj) + } + return res +} @Observed export class TaroCanvasElement extends TaroElement { + _drawList: { + key: string + value: TaroAny + }[] = [] + settings: RenderingContextSettings - context: CanvasRenderingContext2D + _context: CanvasRenderingContext2D + _contextProxy: CanvasRenderingContext2D constructor() { super('Canvas') this.settings = new RenderingContextSettings(true) - this.context = new CanvasRenderingContext2DWXAdapter(this.settings) as CanvasRenderingContext2D + const context = new CanvasRenderingContext2DWXAdapter(this.settings) as CanvasRenderingContext2D + this._context = context + + const proxyObj = getContextKey(context).reduce((obj, key) => { + if (typeof context[key] === 'function') { + obj[key] = new Proxy(context[key], { + apply: (target, thisArg, argumentsList) => { + this._drawList.push({ + key, + value: argumentsList, + }) + }, + }) + } else { + obj[key] = context[key] + } + return obj + }, {}) + + this._contextProxy = new Proxy(proxyObj, { + set: (_, property, value) => { + this._drawList.push({ + key: property, + value, + }) + return true + }, + }) + } + + get context() { + return this._contextProxy } public setAttribute(name: string, value: TaroAny): void { if (name === 'canvasId') { - eventSource.set(value, this as TaroNode) + eventSource.set(`canvasId-${value}`, this as TaroNode) } super.setAttribute(name, value) } From 2c9edbe5d518a46dd4b74b226fc8bc29fb7daa07 Mon Sep 17 00:00:00 2001 From: mayintao3 Date: Fri, 8 Mar 2024 20:37:17 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0draw=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/runtime-ets/dom/element/canvas.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts index d2bb776b48a1..cdb8e3eb2f14 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/canvas.ts @@ -13,7 +13,8 @@ export class CanvasRenderingContext2DWXAdapter extends CanvasRenderingContext2D // Not supported now } - draw() { + draw(cb?: (...args: any[]) => any) { + typeof cb === 'function' && cb() // Not supported now } From b4f9a3166f05bfe7a9cf230e5d51c88ae49c6228 Mon Sep 17 00:00:00 2001 From: mayintao3 Date: Tue, 12 Mar 2024 10:31:44 +0800 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=E4=B8=BAwindow=E6=B7=BB=E5=8A=A0pi?= =?UTF-8?q?xelRatio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-platform-harmony/src/apis/base/system.ts | 2 +- packages/taro-platform-harmony/src/runtime-ets/bom/window.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/taro-platform-harmony/src/apis/base/system.ts b/packages/taro-platform-harmony/src/apis/base/system.ts index 8ecee9e4b7d9..1a1afc85d94a 100644 --- a/packages/taro-platform-harmony/src/apis/base/system.ts +++ b/packages/taro-platform-harmony/src/apis/base/system.ts @@ -75,7 +75,7 @@ export const getSystemInfoSync: typeof Taro.getSystemInfoSync = function () { res.notificationSoundAuthorized = false // 通知带有声音的开关(仅 iOS 有效)boolean res.phoneCalendarAuthorized = null // 使用日历的开关 boolean res.wifiEnabled = false // Wi-Fi 的系统开关 boolean - res.pixelRatio = display && (Math.round(display.xDPI / display.width * 100) / 100) // 设备像素比,number + res.pixelRatio = display && display.densityPixels // 设备像素比,number res.platform = 'harmony' // 客户端平台 string res.safeArea = safeArea // 在竖屏正方向下的安全区域 General.SafeAreaResult res.screenHeight = display?.height // 屏幕高度,单位px number diff --git a/packages/taro-platform-harmony/src/runtime-ets/bom/window.ts b/packages/taro-platform-harmony/src/runtime-ets/bom/window.ts index d0831de272e5..651f2cb51f01 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/bom/window.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/bom/window.ts @@ -1,5 +1,6 @@ import ohosWindow from '@ohos.window' import { History, Location } from '@tarojs/runtime/dist/runtime.esm' +import { getSystemInfoSync } from '@tarojs/taro' import { TaroEventTarget } from '../dom/eventTarget' import { getComputedStyle } from './getComputedStyle' @@ -30,6 +31,10 @@ class Window extends TaroEventTarget { return this._doc } + get devicePixelRatio () { + return getSystemInfoSync().pixelRatio + } + setTimeout (...args: Parameters) { setTimeout(...args) } From 556678175c72bbc7e1cca50b6db218f83f3fb57d Mon Sep 17 00:00:00 2001 From: mayintao3 Date: Thu, 14 Mar 2024 16:13:59 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-platform-harmony/src/apis/canvas/index.ts | 5 +++-- .../src/runtime-ets/dom/element/index.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/taro-platform-harmony/src/apis/canvas/index.ts b/packages/taro-platform-harmony/src/apis/canvas/index.ts index 2e276f9cb008..b61456f32ced 100644 --- a/packages/taro-platform-harmony/src/apis/canvas/index.ts +++ b/packages/taro-platform-harmony/src/apis/canvas/index.ts @@ -1,7 +1,8 @@ -import { eventSource } from '@tarojs/runtime/dist/runtime.esm' -import { TaroCanvasElement } from 'src/runtime-ets' +import { eventSource } from '@tarojs/runtime' import { temporarilyNotSupport } from '../utils' + +import type { TaroCanvasElement } from '@tarojs/runtime' // 画布 /** 创建离屏 canvas 实例 */ diff --git a/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts b/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts index 884d99be29df..fe6111d9be5a 100644 --- a/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts +++ b/packages/taro-platform-harmony/src/runtime-ets/dom/element/index.ts @@ -56,7 +56,7 @@ export function initHarmonyElement () { case 'icon': return new TaroIconElement() case 'label': return new TaroLabelElement() case 'rich-text': return new TaroRichTextElement() - case 'canvas': return new TaroCanvasElement + case 'canvas': return new TaroCanvasElement() case 'swiper': return new TaroSwiperElement() case 'swiper-item': return new TaroSwiperItemElement() case 'textarea': return new TaroTextAreaElement()