zrender-nightly 5.4.4-dev.20231115 → 5.4.4-dev.20231116
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/zrender.js +136 -4
- package/dist/zrender.js.map +1 -1
- package/dist/zrender.min.js +1 -1
- package/lib/Element.d.ts +1 -0
- package/lib/Element.js +12 -0
- package/lib/svg/Painter.d.ts +2 -0
- package/lib/svg/Painter.js +2 -0
- package/lib/svg/core.d.ts +3 -1
- package/lib/svg/core.js +2 -1
- package/lib/svg/cssAnimation.js +2 -1
- package/lib/svg/cssClassId.d.ts +1 -0
- package/lib/svg/cssClassId.js +4 -0
- package/lib/svg/cssEmphasis.d.ts +3 -0
- package/lib/svg/cssEmphasis.js +60 -0
- package/lib/svg/graphic.js +22 -1
- package/lib/tool/color.d.ts +3 -0
- package/lib/tool/color.js +21 -0
- package/lib/zrender.d.ts +6 -1
- package/lib/zrender.js +12 -1
- package/package.json +1 -1
- package/src/Element.ts +16 -0
- package/src/svg/Painter.ts +12 -4
- package/src/svg/core.ts +10 -2
- package/src/svg/cssAnimation.ts +2 -1
- package/src/svg/cssClassId.ts +5 -0
- package/src/svg/cssEmphasis.ts +73 -0
- package/src/svg/graphic.ts +24 -1
- package/src/tool/color.ts +27 -1
- package/src/zrender.ts +18 -1
package/lib/Element.d.ts
CHANGED
|
@@ -166,6 +166,7 @@ declare class Element<Props extends ElementProps = ElementProps> {
|
|
|
166
166
|
clearStates(noAnimation?: boolean): void;
|
|
167
167
|
useState(stateName: string, keepCurrentStates?: boolean, noAnimation?: boolean, forceUseHoverLayer?: boolean): ElementState;
|
|
168
168
|
useStates(states: string[], noAnimation?: boolean, forceUseHoverLayer?: boolean): void;
|
|
169
|
+
isSilent(): boolean;
|
|
169
170
|
private _updateAnimationTargets;
|
|
170
171
|
removeState(state: string): void;
|
|
171
172
|
replaceState(oldState: string, newState: string, forceAdd: boolean): void;
|
package/lib/Element.js
CHANGED
|
@@ -400,6 +400,18 @@ var Element = (function () {
|
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
402
|
};
|
|
403
|
+
Element.prototype.isSilent = function () {
|
|
404
|
+
var isSilent = this.silent;
|
|
405
|
+
var ancestor = this.parent;
|
|
406
|
+
while (!isSilent && ancestor) {
|
|
407
|
+
if (ancestor.silent) {
|
|
408
|
+
isSilent = true;
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
ancestor = ancestor.parent;
|
|
412
|
+
}
|
|
413
|
+
return isSilent;
|
|
414
|
+
};
|
|
403
415
|
Element.prototype._updateAnimationTargets = function () {
|
|
404
416
|
for (var i = 0; i < this.animators.length; i++) {
|
|
405
417
|
var animator = this.animators[i];
|
package/lib/svg/Painter.d.ts
CHANGED
|
@@ -39,9 +39,11 @@ declare class SVGPainter implements PainterBase {
|
|
|
39
39
|
willUpdate?: boolean;
|
|
40
40
|
compress?: boolean;
|
|
41
41
|
useViewBox?: boolean;
|
|
42
|
+
emphasis?: boolean;
|
|
42
43
|
}): SVGVNode;
|
|
43
44
|
renderToString(opts?: {
|
|
44
45
|
cssAnimation?: boolean;
|
|
46
|
+
cssEmphasis?: boolean;
|
|
45
47
|
useViewBox?: boolean;
|
|
46
48
|
}): string;
|
|
47
49
|
setBackgroundColor(backgroundColor: SVGPainterBackgroundColor): void;
|
package/lib/svg/Painter.js
CHANGED
|
@@ -65,6 +65,7 @@ var SVGPainter = (function () {
|
|
|
65
65
|
scope.animation = opts.animation;
|
|
66
66
|
scope.willUpdate = opts.willUpdate;
|
|
67
67
|
scope.compress = opts.compress;
|
|
68
|
+
scope.emphasis = opts.emphasis;
|
|
68
69
|
var children = [];
|
|
69
70
|
var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope);
|
|
70
71
|
bgVNode && children.push(bgVNode);
|
|
@@ -89,6 +90,7 @@ var SVGPainter = (function () {
|
|
|
89
90
|
opts = opts || {};
|
|
90
91
|
return vNodeToString(this.renderToVNode({
|
|
91
92
|
animation: retrieve2(opts.cssAnimation, true),
|
|
93
|
+
emphasis: retrieve2(opts.cssEmphasis, true),
|
|
92
94
|
willUpdate: false,
|
|
93
95
|
compress: true,
|
|
94
96
|
useViewBox: retrieve2(opts.useViewBox, true)
|
package/lib/svg/core.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const SVGNS = "http://www.w3.org/2000/svg";
|
|
|
4
4
|
export declare const XLINKNS = "http://www.w3.org/1999/xlink";
|
|
5
5
|
export declare const XMLNS = "http://www.w3.org/2000/xmlns/";
|
|
6
6
|
export declare const XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
|
|
7
|
+
export declare const META_DATA_PREFIX = "ecmeta_";
|
|
7
8
|
export declare function createElement(name: string): SVGElement;
|
|
8
9
|
export declare type SVGVNodeAttrs = Record<string, string | number | undefined | boolean>;
|
|
9
10
|
export interface SVGVNode {
|
|
@@ -30,13 +31,14 @@ export interface BrushScope {
|
|
|
30
31
|
defs: Record<string, SVGVNode>;
|
|
31
32
|
cssNodes: Record<string, CSSSelectorVNode>;
|
|
32
33
|
cssAnims: Record<string, Record<string, Record<string, string>>>;
|
|
33
|
-
|
|
34
|
+
cssStyleCache: Record<string, string>;
|
|
34
35
|
cssAnimIdx: number;
|
|
35
36
|
shadowIdx: number;
|
|
36
37
|
gradientIdx: number;
|
|
37
38
|
patternIdx: number;
|
|
38
39
|
clipPathIdx: number;
|
|
39
40
|
animation?: boolean;
|
|
41
|
+
emphasis?: boolean;
|
|
40
42
|
willUpdate?: boolean;
|
|
41
43
|
compress?: boolean;
|
|
42
44
|
}
|
package/lib/svg/core.js
CHANGED
|
@@ -4,6 +4,7 @@ export var SVGNS = 'http://www.w3.org/2000/svg';
|
|
|
4
4
|
export var XLINKNS = 'http://www.w3.org/1999/xlink';
|
|
5
5
|
export var XMLNS = 'http://www.w3.org/2000/xmlns/';
|
|
6
6
|
export var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
7
|
+
export var META_DATA_PREFIX = 'ecmeta_';
|
|
7
8
|
export function createElement(name) {
|
|
8
9
|
return document.createElementNS(SVGNS, name);
|
|
9
10
|
}
|
|
@@ -85,7 +86,7 @@ export function createBrushScope(zrId) {
|
|
|
85
86
|
defs: {},
|
|
86
87
|
cssNodes: {},
|
|
87
88
|
cssAnims: {},
|
|
88
|
-
|
|
89
|
+
cssStyleCache: {},
|
|
89
90
|
cssAnimIdx: 0,
|
|
90
91
|
shadowIdx: 0,
|
|
91
92
|
gradientIdx: 0,
|
package/lib/svg/cssAnimation.js
CHANGED
|
@@ -6,6 +6,7 @@ import { getPathPrecision, getSRTTransformString } from './helper.js';
|
|
|
6
6
|
import { each, extend, filter, isNumber, isString, keys } from '../core/util.js';
|
|
7
7
|
import CompoundPath from '../graphic/CompoundPath.js';
|
|
8
8
|
import { createCubicEasingFunc } from '../animation/cubicEasing.js';
|
|
9
|
+
import { getClassId } from './cssClassId.js';
|
|
9
10
|
export var EASING_MAP = {
|
|
10
11
|
cubicIn: '0.32,0,0.67,0',
|
|
11
12
|
cubicOut: '0.33,1,0.68,1',
|
|
@@ -266,7 +267,7 @@ export function createCSSAnimation(el, attrs, scope, onlyShape) {
|
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
if (cssAnimations.length) {
|
|
269
|
-
var className = scope.zrId + '-cls-' +
|
|
270
|
+
var className = scope.zrId + '-cls-' + getClassId();
|
|
270
271
|
scope.cssNodes['.' + className] = {
|
|
271
272
|
animation: cssAnimations.join(',')
|
|
272
273
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getClassId(): number;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { liftColor } from '../tool/color.js';
|
|
2
|
+
import { getClassId } from './cssClassId.js';
|
|
3
|
+
export function createCSSEmphasis(el, attrs, scope) {
|
|
4
|
+
if (!el.ignore) {
|
|
5
|
+
if (el.isSilent()) {
|
|
6
|
+
var style = {
|
|
7
|
+
'pointer-events': 'none'
|
|
8
|
+
};
|
|
9
|
+
setClassAttribute(style, attrs, scope, true);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
var emphasisStyle = el.states.emphasis && el.states.emphasis.style
|
|
13
|
+
? el.states.emphasis.style
|
|
14
|
+
: {};
|
|
15
|
+
var fill = emphasisStyle.fill;
|
|
16
|
+
if (!fill) {
|
|
17
|
+
var normalFill = el.style && el.style.fill;
|
|
18
|
+
var selectFill = el.states.select
|
|
19
|
+
&& el.states.select.style
|
|
20
|
+
&& el.states.select.style.fill;
|
|
21
|
+
var fromFill = el.currentStates.indexOf('select') >= 0
|
|
22
|
+
? (selectFill || normalFill)
|
|
23
|
+
: normalFill;
|
|
24
|
+
if (fromFill) {
|
|
25
|
+
fill = liftColor(fromFill);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
var lineWidth = emphasisStyle.lineWidth;
|
|
29
|
+
if (lineWidth) {
|
|
30
|
+
var scaleX = (!emphasisStyle.strokeNoScale && el.transform)
|
|
31
|
+
? el.transform[0]
|
|
32
|
+
: 1;
|
|
33
|
+
lineWidth = lineWidth / scaleX;
|
|
34
|
+
}
|
|
35
|
+
var style = {
|
|
36
|
+
cursor: 'pointer'
|
|
37
|
+
};
|
|
38
|
+
if (fill) {
|
|
39
|
+
style.fill = fill;
|
|
40
|
+
}
|
|
41
|
+
if (emphasisStyle.stroke) {
|
|
42
|
+
style.stroke = emphasisStyle.stroke;
|
|
43
|
+
}
|
|
44
|
+
if (lineWidth) {
|
|
45
|
+
style['stroke-width'] = lineWidth;
|
|
46
|
+
}
|
|
47
|
+
setClassAttribute(style, attrs, scope, true);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function setClassAttribute(style, attrs, scope, withHover) {
|
|
52
|
+
var styleKey = JSON.stringify(style);
|
|
53
|
+
var className = scope.cssStyleCache[styleKey];
|
|
54
|
+
if (!className) {
|
|
55
|
+
className = scope.zrId + '-cls-' + getClassId();
|
|
56
|
+
scope.cssStyleCache[styleKey] = className;
|
|
57
|
+
scope.cssNodes['.' + className + (withHover ? ':hover' : '')] = style;
|
|
58
|
+
}
|
|
59
|
+
attrs["class"] = attrs["class"] ? (attrs["class"] + ' ' + className) : className;
|
|
60
|
+
}
|
package/lib/svg/graphic.js
CHANGED
|
@@ -5,12 +5,14 @@ import { getLineHeight } from '../contain/text.js';
|
|
|
5
5
|
import TSpan from '../graphic/TSpan.js';
|
|
6
6
|
import SVGPathRebuilder from './SVGPathRebuilder.js';
|
|
7
7
|
import mapStyleToAttrs from './mapStyleToAttrs.js';
|
|
8
|
-
import { createVNode, vNodeToString } from './core.js';
|
|
8
|
+
import { createVNode, vNodeToString, META_DATA_PREFIX } from './core.js';
|
|
9
9
|
import { assert, clone, isFunction, isString, logError, map, retrieve2 } from '../core/util.js';
|
|
10
10
|
import { createOrUpdateImage } from '../graphic/helper/image.js';
|
|
11
11
|
import { createCSSAnimation } from './cssAnimation.js';
|
|
12
12
|
import { hasSeparateFont, parseFontSize } from '../graphic/Text.js';
|
|
13
13
|
import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform.js';
|
|
14
|
+
import { createCSSEmphasis } from './cssEmphasis.js';
|
|
15
|
+
import { getElementSSRData } from '../zrender.js';
|
|
14
16
|
var round = Math.round;
|
|
15
17
|
function isImageLike(val) {
|
|
16
18
|
return val && isString(val.src);
|
|
@@ -27,12 +29,27 @@ function setStyleAttrs(attrs, style, el, scope) {
|
|
|
27
29
|
else if (isFillStroke && isPattern(val)) {
|
|
28
30
|
setPattern(el, attrs, key, scope);
|
|
29
31
|
}
|
|
32
|
+
else if (isFillStroke && val === 'none') {
|
|
33
|
+
attrs[key] = 'transparent';
|
|
34
|
+
}
|
|
30
35
|
else {
|
|
31
36
|
attrs[key] = val;
|
|
32
37
|
}
|
|
33
38
|
}, style, el, false);
|
|
34
39
|
setShadow(el, attrs, scope);
|
|
35
40
|
}
|
|
41
|
+
function setMetaData(attrs, el) {
|
|
42
|
+
var metaData = getElementSSRData(el);
|
|
43
|
+
if (metaData) {
|
|
44
|
+
metaData.each(function (val, key) {
|
|
45
|
+
attrs[(META_DATA_PREFIX + key).toLowerCase()]
|
|
46
|
+
= val + '';
|
|
47
|
+
});
|
|
48
|
+
if (el.isSilent()) {
|
|
49
|
+
attrs[META_DATA_PREFIX + 'silent'] = 'true';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
36
53
|
function noRotateScale(m) {
|
|
37
54
|
return isAroundZero(m[0] - 1)
|
|
38
55
|
&& isAroundZero(m[1])
|
|
@@ -137,7 +154,9 @@ export function brushSVGPath(el, scope) {
|
|
|
137
154
|
}
|
|
138
155
|
setTransform(attrs, el.transform);
|
|
139
156
|
setStyleAttrs(attrs, style, el, scope);
|
|
157
|
+
setMetaData(attrs, el);
|
|
140
158
|
scope.animation && createCSSAnimation(el, attrs, scope);
|
|
159
|
+
scope.emphasis && createCSSEmphasis(el, attrs, scope);
|
|
141
160
|
return createVNode(svgElType, el.id + '', attrs);
|
|
142
161
|
}
|
|
143
162
|
export function brushSVGImage(el, scope) {
|
|
@@ -171,6 +190,7 @@ export function brushSVGImage(el, scope) {
|
|
|
171
190
|
}
|
|
172
191
|
setTransform(attrs, el.transform);
|
|
173
192
|
setStyleAttrs(attrs, style, el, scope);
|
|
193
|
+
setMetaData(attrs, el);
|
|
174
194
|
scope.animation && createCSSAnimation(el, attrs, scope);
|
|
175
195
|
return createVNode('image', el.id + '', attrs);
|
|
176
196
|
}
|
|
@@ -223,6 +243,7 @@ export function brushSVGTSpan(el, scope) {
|
|
|
223
243
|
}
|
|
224
244
|
setTransform(attrs, el.transform);
|
|
225
245
|
setStyleAttrs(attrs, style, el, scope);
|
|
246
|
+
setMetaData(attrs, el);
|
|
226
247
|
scope.animation && createCSSAnimation(el, attrs, scope);
|
|
227
248
|
return createVNode('text', el.id + '', attrs, undefined, text);
|
|
228
249
|
}
|
package/lib/tool/color.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GradientObject } from '../graphic/Gradient';
|
|
1
2
|
export declare function parse(colorStr: string, rgbaArr?: number[]): number[];
|
|
2
3
|
export declare function lift(color: string, level: number): string;
|
|
3
4
|
export declare function toHex(color: string): string;
|
|
@@ -17,4 +18,6 @@ export declare function modifyAlpha(color: string, alpha?: number): string;
|
|
|
17
18
|
export declare function stringify(arrColor: number[], type: string): string;
|
|
18
19
|
export declare function lum(color: string, backgroundLum: number): number;
|
|
19
20
|
export declare function random(): string;
|
|
21
|
+
export declare function liftColor(color: GradientObject): GradientObject;
|
|
22
|
+
export declare function liftColor(color: string): string;
|
|
20
23
|
export {};
|
package/lib/tool/color.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import LRU from '../core/LRU.js';
|
|
2
|
+
import { extend, isGradientObject, isString, map } from '../core/util.js';
|
|
2
3
|
var kCSSColorTable = {
|
|
3
4
|
'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1],
|
|
4
5
|
'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1],
|
|
@@ -406,3 +407,23 @@ export function random() {
|
|
|
406
407
|
Math.round(Math.random() * 255)
|
|
407
408
|
], 'rgb');
|
|
408
409
|
}
|
|
410
|
+
var liftedColorCache = new LRU(100);
|
|
411
|
+
export function liftColor(color) {
|
|
412
|
+
if (isString(color)) {
|
|
413
|
+
var liftedColor = liftedColorCache.get(color);
|
|
414
|
+
if (!liftedColor) {
|
|
415
|
+
liftedColor = lift(color, -0.1);
|
|
416
|
+
liftedColorCache.put(color, liftedColor);
|
|
417
|
+
}
|
|
418
|
+
return liftedColor;
|
|
419
|
+
}
|
|
420
|
+
else if (isGradientObject(color)) {
|
|
421
|
+
var ret = extend({}, color);
|
|
422
|
+
ret.colorStops = map(color.colorStops, function (stop) { return ({
|
|
423
|
+
offset: stop.offset,
|
|
424
|
+
color: lift(stop.color, -0.1)
|
|
425
|
+
}); });
|
|
426
|
+
return ret;
|
|
427
|
+
}
|
|
428
|
+
return color;
|
|
429
|
+
}
|
package/lib/zrender.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* LICENSE
|
|
8
8
|
* https://github.com/ecomfe/zrender/blob/master/LICENSE.txt
|
|
9
9
|
*/
|
|
10
|
+
import * as zrUtil from './core/util';
|
|
10
11
|
import Handler from './Handler';
|
|
11
12
|
import Storage from './Storage';
|
|
12
13
|
import { PainterBase } from './PainterBase';
|
|
@@ -84,7 +85,11 @@ export declare function dispose(zr: ZRender): void;
|
|
|
84
85
|
export declare function disposeAll(): void;
|
|
85
86
|
export declare function getInstance(id: number): ZRender;
|
|
86
87
|
export declare function registerPainter(name: string, Ctor: PainterBaseCtor): void;
|
|
87
|
-
export declare
|
|
88
|
+
export declare type ElementSSRData = zrUtil.HashMap<unknown>;
|
|
89
|
+
export declare type ElementSSRDataGetter<T> = (el: Element) => zrUtil.HashMap<T>;
|
|
90
|
+
export declare function getElementSSRData(el: Element): ElementSSRData;
|
|
91
|
+
export declare function registerSSRDataGetter<T>(getter: ElementSSRDataGetter<T>): void;
|
|
92
|
+
export declare const version = "5.4.4-dev.20231116";
|
|
88
93
|
export interface ZRenderType extends ZRender {
|
|
89
94
|
}
|
|
90
95
|
export {};
|
package/lib/zrender.js
CHANGED
|
@@ -261,5 +261,16 @@ export function getInstance(id) {
|
|
|
261
261
|
export function registerPainter(name, Ctor) {
|
|
262
262
|
painterCtors[name] = Ctor;
|
|
263
263
|
}
|
|
264
|
-
|
|
264
|
+
var ssrDataGetter = function (el) {
|
|
265
|
+
return null;
|
|
266
|
+
};
|
|
267
|
+
export function getElementSSRData(el) {
|
|
268
|
+
if (typeof ssrDataGetter === 'function') {
|
|
269
|
+
return ssrDataGetter(el);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export function registerSSRDataGetter(getter) {
|
|
273
|
+
ssrDataGetter = getter;
|
|
274
|
+
}
|
|
275
|
+
export var version = '5.4.4-dev.20231116';
|
|
265
276
|
;
|
package/package.json
CHANGED
package/src/Element.ts
CHANGED
|
@@ -1017,6 +1017,22 @@ class Element<Props extends ElementProps = ElementProps> {
|
|
|
1017
1017
|
}
|
|
1018
1018
|
}
|
|
1019
1019
|
|
|
1020
|
+
/**
|
|
1021
|
+
* Return if el.silent or any ancestor element has silent true.
|
|
1022
|
+
*/
|
|
1023
|
+
isSilent() {
|
|
1024
|
+
let isSilent = this.silent;
|
|
1025
|
+
let ancestor = this.parent;
|
|
1026
|
+
while (!isSilent && ancestor) {
|
|
1027
|
+
if (ancestor.silent) {
|
|
1028
|
+
isSilent = true;
|
|
1029
|
+
break;
|
|
1030
|
+
}
|
|
1031
|
+
ancestor = ancestor.parent;
|
|
1032
|
+
}
|
|
1033
|
+
return isSilent;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1020
1036
|
/**
|
|
1021
1037
|
* Update animation targets when reference is changed.
|
|
1022
1038
|
*/
|
package/src/svg/Painter.ts
CHANGED
|
@@ -124,10 +124,11 @@ class SVGPainter implements PainterBase {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
renderToVNode(opts?: {
|
|
127
|
-
animation?: boolean
|
|
128
|
-
willUpdate?: boolean
|
|
127
|
+
animation?: boolean,
|
|
128
|
+
willUpdate?: boolean,
|
|
129
129
|
compress?: boolean,
|
|
130
|
-
useViewBox?: boolean
|
|
130
|
+
useViewBox?: boolean,
|
|
131
|
+
emphasis?: boolean
|
|
131
132
|
}) {
|
|
132
133
|
|
|
133
134
|
opts = opts || {};
|
|
@@ -140,6 +141,7 @@ class SVGPainter implements PainterBase {
|
|
|
140
141
|
scope.animation = opts.animation;
|
|
141
142
|
scope.willUpdate = opts.willUpdate;
|
|
142
143
|
scope.compress = opts.compress;
|
|
144
|
+
scope.emphasis = opts.emphasis;
|
|
143
145
|
|
|
144
146
|
const children: SVGVNode[] = [];
|
|
145
147
|
|
|
@@ -173,7 +175,12 @@ class SVGPainter implements PainterBase {
|
|
|
173
175
|
* If add css animation.
|
|
174
176
|
* @default true
|
|
175
177
|
*/
|
|
176
|
-
cssAnimation?: boolean
|
|
178
|
+
cssAnimation?: boolean,
|
|
179
|
+
/**
|
|
180
|
+
* If add css emphasis.
|
|
181
|
+
* @default true
|
|
182
|
+
*/
|
|
183
|
+
cssEmphasis?: boolean,
|
|
177
184
|
/**
|
|
178
185
|
* If use viewBox
|
|
179
186
|
* @default true
|
|
@@ -183,6 +190,7 @@ class SVGPainter implements PainterBase {
|
|
|
183
190
|
opts = opts || {};
|
|
184
191
|
return vNodeToString(this.renderToVNode({
|
|
185
192
|
animation: retrieve2(opts.cssAnimation, true),
|
|
193
|
+
emphasis: retrieve2(opts.cssEmphasis, true),
|
|
186
194
|
willUpdate: false,
|
|
187
195
|
compress: true,
|
|
188
196
|
useViewBox: retrieve2(opts.useViewBox, true)
|
package/src/svg/core.ts
CHANGED
|
@@ -8,6 +8,7 @@ export const SVGNS = 'http://www.w3.org/2000/svg';
|
|
|
8
8
|
export const XLINKNS = 'http://www.w3.org/1999/xlink';
|
|
9
9
|
export const XMLNS = 'http://www.w3.org/2000/xmlns/';
|
|
10
10
|
export const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
11
|
+
export const META_DATA_PREFIX = 'ecmeta_';
|
|
11
12
|
|
|
12
13
|
export function createElement(name: string) {
|
|
13
14
|
return document.createElementNS(SVGNS, name);
|
|
@@ -128,8 +129,11 @@ export interface BrushScope {
|
|
|
128
129
|
|
|
129
130
|
cssNodes: Record<string, CSSSelectorVNode>
|
|
130
131
|
cssAnims: Record<string, Record<string, Record<string, string>>>
|
|
132
|
+
/**
|
|
133
|
+
* Cache for css style string, mapping from style string to class name.
|
|
134
|
+
*/
|
|
135
|
+
cssStyleCache: Record<string, string>
|
|
131
136
|
|
|
132
|
-
cssClassIdx: number
|
|
133
137
|
cssAnimIdx: number
|
|
134
138
|
|
|
135
139
|
shadowIdx: number
|
|
@@ -141,6 +145,10 @@ export interface BrushScope {
|
|
|
141
145
|
* If create animates nodes.
|
|
142
146
|
*/
|
|
143
147
|
animation?: boolean,
|
|
148
|
+
/**
|
|
149
|
+
* If create emphasis styles.
|
|
150
|
+
*/
|
|
151
|
+
emphasis?: boolean,
|
|
144
152
|
|
|
145
153
|
/**
|
|
146
154
|
* If will update. Some optimization for string generation can't be applied.
|
|
@@ -164,8 +172,8 @@ export function createBrushScope(zrId: string): BrushScope {
|
|
|
164
172
|
|
|
165
173
|
cssNodes: {},
|
|
166
174
|
cssAnims: {},
|
|
175
|
+
cssStyleCache: {},
|
|
167
176
|
|
|
168
|
-
cssClassIdx: 0,
|
|
169
177
|
cssAnimIdx: 0,
|
|
170
178
|
|
|
171
179
|
shadowIdx: 0,
|
package/src/svg/cssAnimation.ts
CHANGED
|
@@ -10,6 +10,7 @@ import Animator from '../animation/Animator';
|
|
|
10
10
|
import CompoundPath from '../graphic/CompoundPath';
|
|
11
11
|
import { AnimationEasing } from '../animation/easing';
|
|
12
12
|
import { createCubicEasingFunc } from '../animation/cubicEasing';
|
|
13
|
+
import { getClassId } from './cssClassId';
|
|
13
14
|
|
|
14
15
|
export const EASING_MAP: Record<string, string> = {
|
|
15
16
|
// From https://easings.net/
|
|
@@ -355,7 +356,7 @@ export function createCSSAnimation(
|
|
|
355
356
|
}
|
|
356
357
|
|
|
357
358
|
if (cssAnimations.length) {
|
|
358
|
-
const className = scope.zrId + '-cls-' +
|
|
359
|
+
const className = scope.zrId + '-cls-' + getClassId();
|
|
359
360
|
scope.cssNodes['.' + className] = {
|
|
360
361
|
animation: cssAnimations.join(',')
|
|
361
362
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Displayable from '../graphic/Displayable';
|
|
2
|
+
import { liftColor } from '../tool/color';
|
|
3
|
+
import { BrushScope, SVGVNodeAttrs } from './core';
|
|
4
|
+
import { getClassId } from './cssClassId';
|
|
5
|
+
|
|
6
|
+
export function createCSSEmphasis(
|
|
7
|
+
el: Displayable,
|
|
8
|
+
attrs: SVGVNodeAttrs,
|
|
9
|
+
scope: BrushScope
|
|
10
|
+
) {
|
|
11
|
+
if (!el.ignore) {
|
|
12
|
+
if (el.isSilent()) {
|
|
13
|
+
// If el is silent, it can not be hovered nor selected.
|
|
14
|
+
// So set pointer-events to pass through.
|
|
15
|
+
const style = {
|
|
16
|
+
'pointer-events': 'none'
|
|
17
|
+
};
|
|
18
|
+
setClassAttribute(style, attrs, scope, true);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const emphasisStyle = el.states.emphasis && el.states.emphasis.style
|
|
22
|
+
? el.states.emphasis.style
|
|
23
|
+
: {};
|
|
24
|
+
let fill = emphasisStyle.fill;
|
|
25
|
+
if (!fill) {
|
|
26
|
+
// No empahsis fill, lift color
|
|
27
|
+
const normalFill = el.style && el.style.fill;
|
|
28
|
+
const selectFill = el.states.select
|
|
29
|
+
&& el.states.select.style
|
|
30
|
+
&& el.states.select.style.fill;
|
|
31
|
+
const fromFill = el.currentStates.indexOf('select') >= 0
|
|
32
|
+
? (selectFill || normalFill)
|
|
33
|
+
: normalFill;
|
|
34
|
+
if (fromFill) {
|
|
35
|
+
fill = liftColor(fromFill);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
let lineWidth = emphasisStyle.lineWidth;
|
|
39
|
+
if (lineWidth) {
|
|
40
|
+
// Symbols use transform to set size, so lineWidth
|
|
41
|
+
// should be divided by scaleX
|
|
42
|
+
const scaleX = (!emphasisStyle.strokeNoScale && el.transform)
|
|
43
|
+
? el.transform[0]
|
|
44
|
+
: 1;
|
|
45
|
+
lineWidth = lineWidth / scaleX;
|
|
46
|
+
}
|
|
47
|
+
const style = {
|
|
48
|
+
cursor: 'pointer', // TODO: Should this be customized?
|
|
49
|
+
} as any;
|
|
50
|
+
if (fill) {
|
|
51
|
+
style.fill = fill;
|
|
52
|
+
}
|
|
53
|
+
if (emphasisStyle.stroke) {
|
|
54
|
+
style.stroke = emphasisStyle.stroke;
|
|
55
|
+
}
|
|
56
|
+
if (lineWidth) {
|
|
57
|
+
style['stroke-width'] = lineWidth;
|
|
58
|
+
}
|
|
59
|
+
setClassAttribute(style, attrs, scope, true);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function setClassAttribute(style: object, attrs: SVGVNodeAttrs, scope: BrushScope, withHover: boolean) {
|
|
65
|
+
const styleKey = JSON.stringify(style);
|
|
66
|
+
let className = scope.cssStyleCache[styleKey];
|
|
67
|
+
if (!className) {
|
|
68
|
+
className = scope.zrId + '-cls-' + getClassId();
|
|
69
|
+
scope.cssStyleCache[styleKey] = className;
|
|
70
|
+
scope.cssNodes['.' + className + (withHover ? ':hover' : '')] = style as any;
|
|
71
|
+
}
|
|
72
|
+
attrs.class = attrs.class ? (attrs.class + ' ' + className) : className;
|
|
73
|
+
}
|
package/src/svg/graphic.ts
CHANGED
|
@@ -26,7 +26,7 @@ import { getLineHeight } from '../contain/text';
|
|
|
26
26
|
import TSpan, { TSpanStyleProps } from '../graphic/TSpan';
|
|
27
27
|
import SVGPathRebuilder from './SVGPathRebuilder';
|
|
28
28
|
import mapStyleToAttrs from './mapStyleToAttrs';
|
|
29
|
-
import { SVGVNodeAttrs, createVNode, SVGVNode, vNodeToString, BrushScope } from './core';
|
|
29
|
+
import { SVGVNodeAttrs, createVNode, SVGVNode, vNodeToString, BrushScope, META_DATA_PREFIX } from './core';
|
|
30
30
|
import { MatrixArray } from '../core/matrix';
|
|
31
31
|
import Displayable from '../graphic/Displayable';
|
|
32
32
|
import { assert, clone, isFunction, isString, logError, map, retrieve2 } from '../core/util';
|
|
@@ -39,6 +39,8 @@ import { ImageLike } from '../core/types';
|
|
|
39
39
|
import { createCSSAnimation } from './cssAnimation';
|
|
40
40
|
import { hasSeparateFont, parseFontSize } from '../graphic/Text';
|
|
41
41
|
import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform';
|
|
42
|
+
import { createCSSEmphasis } from './cssEmphasis';
|
|
43
|
+
import { getElementSSRData } from '../zrender';
|
|
42
44
|
|
|
43
45
|
const round = Math.round;
|
|
44
46
|
|
|
@@ -61,6 +63,10 @@ function setStyleAttrs(attrs: SVGVNodeAttrs, style: AllStyleOption, el: Path | T
|
|
|
61
63
|
else if (isFillStroke && isPattern(val)) {
|
|
62
64
|
setPattern(el, attrs, key, scope);
|
|
63
65
|
}
|
|
66
|
+
else if (isFillStroke && val === 'none') {
|
|
67
|
+
// When is none, it cannot be interacted when ssr
|
|
68
|
+
attrs[key] = 'transparent';
|
|
69
|
+
}
|
|
64
70
|
else {
|
|
65
71
|
attrs[key] = val;
|
|
66
72
|
}
|
|
@@ -69,6 +75,19 @@ function setStyleAttrs(attrs: SVGVNodeAttrs, style: AllStyleOption, el: Path | T
|
|
|
69
75
|
setShadow(el, attrs, scope);
|
|
70
76
|
}
|
|
71
77
|
|
|
78
|
+
function setMetaData(attrs: SVGVNodeAttrs, el: Path | TSpan | ZRImage) {
|
|
79
|
+
const metaData = getElementSSRData(el);
|
|
80
|
+
if (metaData) {
|
|
81
|
+
metaData.each((val, key) => {
|
|
82
|
+
attrs[(META_DATA_PREFIX + key).toLowerCase()]
|
|
83
|
+
= val + '';
|
|
84
|
+
});
|
|
85
|
+
if (el.isSilent()) {
|
|
86
|
+
attrs[META_DATA_PREFIX + 'silent'] = 'true';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
72
91
|
function noRotateScale(m: MatrixArray) {
|
|
73
92
|
return isAroundZero(m[0] - 1)
|
|
74
93
|
&& isAroundZero(m[1])
|
|
@@ -204,8 +223,10 @@ export function brushSVGPath(el: Path, scope: BrushScope) {
|
|
|
204
223
|
|
|
205
224
|
setTransform(attrs, el.transform);
|
|
206
225
|
setStyleAttrs(attrs, style, el, scope);
|
|
226
|
+
setMetaData(attrs, el);
|
|
207
227
|
|
|
208
228
|
scope.animation && createCSSAnimation(el, attrs, scope);
|
|
229
|
+
scope.emphasis && createCSSEmphasis(el, attrs, scope);
|
|
209
230
|
|
|
210
231
|
return createVNode(svgElType, el.id + '', attrs);
|
|
211
232
|
}
|
|
@@ -248,6 +269,7 @@ export function brushSVGImage(el: ZRImage, scope: BrushScope) {
|
|
|
248
269
|
|
|
249
270
|
setTransform(attrs, el.transform);
|
|
250
271
|
setStyleAttrs(attrs, style, el, scope);
|
|
272
|
+
setMetaData(attrs, el);
|
|
251
273
|
|
|
252
274
|
scope.animation && createCSSAnimation(el, attrs, scope);
|
|
253
275
|
|
|
@@ -319,6 +341,7 @@ export function brushSVGTSpan(el: TSpan, scope: BrushScope) {
|
|
|
319
341
|
}
|
|
320
342
|
setTransform(attrs, el.transform);
|
|
321
343
|
setStyleAttrs(attrs, style, el, scope);
|
|
344
|
+
setMetaData(attrs, el);
|
|
322
345
|
|
|
323
346
|
scope.animation && createCSSAnimation(el, attrs, scope);
|
|
324
347
|
|