From 68683939e1d96600c7409ab4c6a711fbddafea2b Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Mon, 23 Dec 2024 17:13:34 +0800 Subject: [PATCH] feat: enhance scaleXY auto to support resize canvas wh --- .../feat-wh-scale_2024-12-23-09-13.json | 10 ++++ packages/vstory-core/src/core/canvas.ts | 55 ++++++++++++------- .../vstory/demo/src/demos/animate/Bounce.tsx | 17 ++++-- 3 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 common/changes/@visactor/vstory-core/feat-wh-scale_2024-12-23-09-13.json diff --git a/common/changes/@visactor/vstory-core/feat-wh-scale_2024-12-23-09-13.json b/common/changes/@visactor/vstory-core/feat-wh-scale_2024-12-23-09-13.json new file mode 100644 index 00000000..a42214ce --- /dev/null +++ b/common/changes/@visactor/vstory-core/feat-wh-scale_2024-12-23-09-13.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vstory-core", + "comment": "feat: enhance scaleXY auto to support resize canvas wh", + "type": "none" + } + ], + "packageName": "@visactor/vstory-core" +} \ No newline at end of file diff --git a/packages/vstory-core/src/core/canvas.ts b/packages/vstory-core/src/core/canvas.ts index 6bd89b15..3b53f334 100644 --- a/packages/vstory-core/src/core/canvas.ts +++ b/packages/vstory-core/src/core/canvas.ts @@ -43,20 +43,22 @@ export class StoryCanvas implements IStoryCanvas { const { canvas, - width, - height, + width: _w, + height: _h, background = 'transparent', layerBackground = 'transparent', dpr = vglobal.devicePixelRatio, - scaleX = 1, - scaleY = 1 + scaleX: _sx = 1, + scaleY: _sy = 1 } = params; + const { scaleX, scaleY, width, height } = this.getScale(_w, _h, _sx, _sy); + this._container && this._initCanvasByContainer(width, height, dpr, background); params.canvas && this._initCanvasByCanvas(canvas, width ?? 500, height ?? 500, dpr, background); // this._stage.background = background; this._stage.defaultLayer.setAttributes({ background: layerBackground }); - this.initScale(width, height, scaleX, scaleY); + this._stage.defaultLayer.scale(scaleX, scaleY); } protected _initCanvasByContainer(width: number, height: number, dpr: number, background: string) { @@ -114,27 +116,40 @@ export class StoryCanvas implements IStoryCanvas { return stage; } - protected initScale(width: number, height: number, scaleX: number | 'auto', scaleY: number | 'auto') { + protected getScale( + width: number, + height: number, + scaleX: number | 'auto', + scaleY: number | 'auto' + ): { scaleX: number; scaleY: number; width: number; height: number } { + // 仅在传入width和height时有效 if (scaleX === 'auto' || scaleY === 'auto') { - const clipWidth = this._container ? this._container.clientWidth : this._canvas.width / this.getDpr(); - const clipHeight = this._container ? this._container.clientHeight : this._canvas.height / this.getDpr(); - - const clipAspectRatio = clipWidth / clipHeight; - const contentAspectRatio = width / height; - const scale = clipAspectRatio > contentAspectRatio ? clipHeight / height : clipWidth / width; - if (!isValidNumber(scale)) { + if (!Number.isFinite(width) || !Number.isFinite(height)) { scaleX = scaleY = 1; } else { - if (scaleX === 'auto') { - scaleX = scale; - } - - if (scaleY === 'auto') { - scaleY = scale; + const clipWidth = this._container ? this._container.clientWidth : this._canvas.width / this.getDpr(); + const clipHeight = this._container ? this._container.clientHeight : this._canvas.height / this.getDpr(); + + const clipAspectRatio = clipWidth / clipHeight; + const contentAspectRatio = width / height; + const scale = clipAspectRatio > contentAspectRatio ? clipHeight / height : clipWidth / width; + if (!isValidNumber(scale)) { + scaleX = scaleY = 1; + } else { + if (scaleX === 'auto') { + scaleX = scale; + } + + if (scaleY === 'auto') { + scaleY = scale; + } } + width *= scaleX; + height *= scaleY; } } - this._stage.defaultLayer.scale(scaleX, scaleY); + return { scaleX, scaleY, width, height }; + // this._stage.defaultLayer.scale(scaleX, scaleY); } resize(w: number, h: number) { diff --git a/packages/vstory/demo/src/demos/animate/Bounce.tsx b/packages/vstory/demo/src/demos/animate/Bounce.tsx index 6e7e5166..2d3f0857 100644 --- a/packages/vstory/demo/src/demos/animate/Bounce.tsx +++ b/packages/vstory/demo/src/demos/animate/Bounce.tsx @@ -17,9 +17,9 @@ export const Bounce = () => { const id = 'Bounce'; useEffect(() => { - const container = document.getElementById(id); - const canvas = document.createElement('canvas'); - container?.appendChild(canvas); + // const container = document.getElementById(id); + // const canvas = document.createElement('canvas'); + // container?.appendChild(canvas); const chartSpec = { type: 'bar', @@ -43,7 +43,14 @@ export const Bounce = () => { yField: 'sales' }; - const story = new Story(null, { canvas, width: 800, height: 500, background: 'pink' }); + const story = new Story(null, { + dom: id, + width: 900, + height: 500, + scaleX: 'auto', + scaleY: 'auto', + background: 'pink' + }); const player = new Player(story); story.init(player); @@ -188,5 +195,5 @@ export const Bounce = () => { }; }, []); - return
; + return
; };