@visactor/vrender-core
Version:
## Description
125 lines (115 loc) • 5.29 kB
JavaScript
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