UNPKG

@visactor/vrender-core

Version:
125 lines (115 loc) 5.29 kB
import { Logger } from "@visactor/vutils"; import { DefaultArcAttribute, DefaultAreaAttribute, DefaultCircleAttribute, DefaultGlyphAttribute, DefaultGroupAttribute, DefaultImageAttribute, DefaultLineAttribute, DefaultPathAttribute, DefaultPolygonAttribute, DefaultRectAttribute, DefaultSymbolAttribute, DefaultTextAttribute, DefaultRichTextAttribute, DefaultRichTextIconAttribute } from "./config"; const defaultThemeObj = { arc: DefaultArcAttribute, area: DefaultAreaAttribute, circle: DefaultCircleAttribute, line: DefaultLineAttribute, path: DefaultPathAttribute, symbol: DefaultSymbolAttribute, text: DefaultTextAttribute, rect: DefaultRectAttribute, polygon: DefaultPolygonAttribute, richtext: DefaultRichTextAttribute, richtextIcon: DefaultRichTextIconAttribute, image: DefaultImageAttribute, group: DefaultGroupAttribute, glyph: DefaultGlyphAttribute }, themeKeys = Object.keys(defaultThemeObj); export function newThemeObj() { return { arc: Object.assign({}, defaultThemeObj.arc), area: Object.assign({}, defaultThemeObj.area), circle: Object.assign({}, defaultThemeObj.circle), line: Object.assign({}, defaultThemeObj.line), path: Object.assign({}, defaultThemeObj.path), symbol: Object.assign({}, defaultThemeObj.symbol), text: Object.assign({}, defaultThemeObj.text), rect: Object.assign({}, defaultThemeObj.rect), polygon: Object.assign({}, defaultThemeObj.polygon), richtext: Object.assign({}, defaultThemeObj.richtext), richtextIcon: Object.assign({}, defaultThemeObj.richtextIcon), image: Object.assign({}, defaultThemeObj.image), group: Object.assign({}, defaultThemeObj.group), glyph: Object.assign({}, defaultThemeObj.glyph) }; } function combine(out, t) { Object.keys(t).forEach((k => { out[k] = t[k]; })); } const globalThemeObj = newThemeObj(); export class Theme { constructor() { this.initTheme(), this.dirty = !1; } initTheme() { this._defaultTheme = {}, themeKeys.forEach((key => { this._defaultTheme[key] = Object.create(globalThemeObj[key]); })), this.combinedTheme = this._defaultTheme; } getTheme(group) { if (!group) return this.combinedTheme; if (!this.dirty) return this.combinedTheme; let parentTheme = {}; const parentGroup = this.getParentWithTheme(group); return parentGroup && (parentTheme = parentGroup.theme), this.applyTheme(group, parentTheme), this.combinedTheme; } getParentWithTheme(group) { for (;group.parent; ) if ((group = group.parent).theme) return group; return null; } applyTheme(group, pt, force = !1) { if (this.dirty) { const parentGroup = this.getParentWithTheme(group); if (parentGroup) { const parentTheme = parentGroup.theme; (parentTheme.dirty || force) && parentTheme.applyTheme(parentGroup, pt, !0); } this.userTheme ? this.doCombine(parentGroup && parentGroup.theme.combinedTheme) : (parentGroup ? this.combinedTheme = parentGroup.theme.combinedTheme : (this.combinedTheme = this._defaultTheme, Logger.getInstance().warn("未知错误,走到不应该走的区域里")), this.dirty = !1); } return this.combinedTheme; } doCombine(parentCombinedTheme) { const userTheme = this.userTheme, combinedTheme = this.combinedTheme; themeKeys.forEach((k => { const obj = Object.create(globalThemeObj[k]); parentCombinedTheme && parentCombinedTheme[k] && combine(obj, parentCombinedTheme[k]), combinedTheme[k] && combine(obj, combinedTheme[k]), userTheme[k] && combine(obj, userTheme[k]), this.combinedTheme[k] = obj; })), userTheme.common && themeKeys.forEach((k => { combine(this.combinedTheme[k], userTheme.common); })), this.dirty = !1; } setTheme(t, g) { let userTheme = this.userTheme; userTheme ? Object.keys(t).forEach((k => { userTheme[k] ? Object.assign(userTheme[k], t[k]) : userTheme[k] = Object.assign({}, t[k]); })) : userTheme = t, this.userTheme = userTheme, this.dirty = !0, this.dirtyChildren(g); } resetTheme(t, g) { this.userTheme = t, this.dirty = !0, this.dirtyChildren(g); } dirtyChildren(g) { g.forEachChildren((item => { item.isContainer && (item.theme && (item.theme.dirty = !0), this.dirtyChildren(item)); })); } } export const globalTheme = new Theme; export function getTheme(graphic, theme) { return graphic.glyphHost ? getTheme(graphic.glyphHost) : theme ? (graphic.isContainer, theme) : getThemeFromGroup(graphic) || graphic.attachedThemeGraphic && getTheme(graphic.attachedThemeGraphic) || globalTheme.getTheme(); } export function getThemeFromGroup(graphic) { let g; if (g = graphic.isContainer ? graphic : graphic.parent, g) { for (;g && !g.theme; ) g = g.parent; return g ? (g.theme || g.createTheme(), g.theme.getTheme(g)) : globalTheme.getTheme(); } return null; } //# sourceMappingURL=theme.js.map