From 28524e8ebd949994e41a8647bfe97e05d25db2d2 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Thu, 15 Jun 2023 19:21:54 +0800 Subject: [PATCH] fix: fix the bug in multiple theme, closed #17 --- docs/demos/src/pages/circle.ts | 65 ++++++++++++------- packages/vrender/src/graphic/theme.ts | 47 ++++++++++---- .../vrender/src/interface/graphic/theme.ts | 2 +- 3 files changed, 80 insertions(+), 34 deletions(-) diff --git a/docs/demos/src/pages/circle.ts b/docs/demos/src/pages/circle.ts index 99705c8ad..96649a732 100644 --- a/docs/demos/src/pages/circle.ts +++ b/docs/demos/src/pages/circle.ts @@ -1,34 +1,35 @@ import { createStage, createCircle, IGraphic } from '@visactor/vrender'; import { colorPools } from '../utils'; +import { createGroup } from '@visactor/vrender'; export const page = () => { const graphics: IGraphic[] = []; - graphics.push(createCircle({ - radius: 50, - x: 100, - y: 200, - fill: colorPools[10], - lineWidth: 2, - })); + // graphics.push(createCircle({ + // radius: 50, + // x: 100, + // y: 200, + // fill: colorPools[10], + // lineWidth: 2, + // })); - graphics.push(createCircle({ - radius: 50, - x: 300, - y: 200, - lineWidth: 2, - background: - '', - texture: 'circle', - textureColor: 'orange', - stroke: 'green', - })); + // graphics.push(createCircle({ + // radius: 50, + // x: 300, + // y: 200, + // lineWidth: 2, + // background: + // '', + // texture: 'circle', + // textureColor: 'orange', + // stroke: 'green', + // })); - graphics.push(createCircle({ + const circle = createCircle({ radius: 50, x: 500, y: 200, fill: colorPools[10], - lineWidth: 2, + // lineWidth: 2, outerBorder: { distance: 10, lineWidth: 6, @@ -42,14 +43,34 @@ export const page = () => { texture: 'circle', textureColor: 'orange', stroke: 'red', - })); + }); + + const group = createGroup(); + group.add(circle); + + group.setTheme({ + common: { + fill: 'green' + } + }) + + graphics.push(group); + const stage = createStage({ canvas: 'main', autoRender: true }); + stage.setTheme({ + common: { + lineWidth: 6 + } + }) + graphics.forEach(g => { stage.defaultLayer.add(g); - }) + }); + + console.log(stage) }; diff --git a/packages/vrender/src/graphic/theme.ts b/packages/vrender/src/graphic/theme.ts index c9e5789e5..a56dc89d8 100644 --- a/packages/vrender/src/graphic/theme.ts +++ b/packages/vrender/src/graphic/theme.ts @@ -1,3 +1,4 @@ +import { clone } from '@visactor/vutils'; import { IGraphicAttribute, IFullThemeSpec, IGraphic, IGroup, ITheme, IThemeSpec } from '../interface'; import { DefaultArcAttribute, @@ -58,17 +59,34 @@ export function newThemeObj(): IFullThemeSpec { } // 将t合并到out中 -function combineTheme(out: IThemeSpec, t: IThemeSpec) { +function combineTheme(out: IThemeSpec, t: IThemeSpec, rewrite: boolean = true) { if (!t) { return; } - Object.keys(t).forEach(k => { - if (out[k]) { - Object.assign(out[k], t[k]); - } else { - out[k] = t[k]; - } - }); + if (rewrite) { + Object.keys(t).forEach(k => { + if (out[k]) { + Object.assign(out[k], t[k]); + } else { + out[k] = t[k]; + } + }); + } else { + Object.keys(t).forEach(k => { + if (out[k]) { + // Object.assign(out[k], t[k]); + const outItem = out[k]; + const tItem = t[k]; + Object.keys(t[k]).forEach(kItem => { + if (outItem[kItem] === undefined) { + outItem[kItem] = tItem[kItem]; + } + }); + } else { + out[k] = t[k]; + } + }); + } } // 全局创建60个theme,节省打点耗时时间 @@ -138,13 +156,20 @@ export class Theme implements ITheme { } // 应用主题,从根节点一直触发到当前节点(如果上层节点需要的话) - applyTheme(group: IGroup, pt: IThemeSpec): IThemeSpec { + applyTheme(group: IGroup, pt: IThemeSpec, force: boolean = false): IThemeSpec { if (this.dirty) { const parentGroup = this.getParentWithTheme(group); if (parentGroup) { const parentTheme = parentGroup.theme; - if (parentTheme.dirty) { - parentTheme.applyTheme(parentGroup, pt); + if (parentTheme.dirty || force) { + // 强制apply所有的上层 + parentTheme.applyTheme(parentGroup, pt, true); + } + // 将parentTheme.userTheme设置给自己的userTheme + if (!this.userTheme) { + this.userTheme = clone(parentTheme.userTheme); + } else { + combineTheme(this.userTheme, parentTheme.userTheme, false); } combineTheme(pt, parentTheme.userTheme); } diff --git a/packages/vrender/src/interface/graphic/theme.ts b/packages/vrender/src/interface/graphic/theme.ts index 1fe587303..d3948edcf 100644 --- a/packages/vrender/src/interface/graphic/theme.ts +++ b/packages/vrender/src/interface/graphic/theme.ts @@ -53,7 +53,7 @@ export interface ITheme { combinedTheme?: IFullThemeSpec; userTheme?: IThemeSpec; nextTheme?: IThemeSpec; - applyTheme: (group: IGroup, pt: IThemeSpec) => IThemeSpec; + applyTheme: (group: IGroup, pt: IThemeSpec, force?: boolean) => IThemeSpec; setTheme: (t: IThemeSpec, g: IGroup) => void; dirty: boolean; }