123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- import Path, { DEFAULT_PATH_STYLE, PathStyleProps } from '../graphic/Path';
- import ZRImage, { ImageStyleProps } from '../graphic/Image';
- import TSpan, { TSpanStyleProps } from '../graphic/TSpan';
- import { getLineDash } from '../canvas/dashStyle';
- import { map } from '../core/util';
- import { normalizeColor } from './helper';
- type AllStyleOption = PathStyleProps | TSpanStyleProps | ImageStyleProps;
- const NONE = 'none';
- const mathRound = Math.round;
- function pathHasFill(style: AllStyleOption): style is PathStyleProps {
- const fill = (style as PathStyleProps).fill;
- return fill != null && fill !== NONE;
- }
- function pathHasStroke(style: AllStyleOption): style is PathStyleProps {
- const stroke = (style as PathStyleProps).stroke;
- return stroke != null && stroke !== NONE;
- }
- const strokeProps = ['lineCap', 'miterLimit', 'lineJoin'] as const;
- const svgStrokeProps = map(strokeProps, prop => `stroke-${prop.toLowerCase()}`);
- export default function mapStyleToAttrs(
- updateAttr: (key: string, val: string | number) => void,
- style: AllStyleOption,
- el: Path | TSpan | ZRImage,
- /**
- * Will try not to set the attribute if it's using default value if not using forceUpdate.
- * Mainly for reduce the generated size in svg-ssr mode.
- */
- forceUpdate: boolean
- ): void {
- const opacity = style.opacity == null ? 1 : style.opacity;
- // only set opacity. stroke and fill cannot be applied to svg image
- if (el instanceof ZRImage) {
- updateAttr('opacity', opacity);
- return;
- }
- if (pathHasFill(style)) {
- const fill = normalizeColor(style.fill as string);
- updateAttr('fill', fill.color);
- const fillOpacity = style.fillOpacity != null
- ? style.fillOpacity * fill.opacity * opacity
- : fill.opacity * opacity;
- if (forceUpdate || fillOpacity < 1) {
- updateAttr('fill-opacity', fillOpacity);
- }
- }
- else {
- updateAttr('fill', NONE);
- }
- if (pathHasStroke(style)) {
- const stroke = normalizeColor(style.stroke as string);
- updateAttr('stroke', stroke.color);
- const strokeScale = style.strokeNoScale
- ? (el as Path).getLineScale()
- : 1;
- const strokeWidth = (strokeScale ? (style.lineWidth || 0) / strokeScale : 0);
- const strokeOpacity = style.strokeOpacity != null
- ? style.strokeOpacity * stroke.opacity * opacity
- : stroke.opacity * opacity;
- const strokeFirst = style.strokeFirst;
- if (forceUpdate || strokeWidth !== 1) {
- updateAttr('stroke-width', strokeWidth);
- }
- // stroke then fill for text; fill then stroke for others
- if (forceUpdate || strokeFirst) {
- updateAttr('paint-order', strokeFirst ? 'stroke' : 'fill');
- }
- if (forceUpdate || strokeOpacity < 1) {
- updateAttr('stroke-opacity', strokeOpacity);
- }
- if (style.lineDash) {
- let [lineDash, lineDashOffset] = getLineDash(el);
- if (lineDash) {
- lineDashOffset = mathRound(lineDashOffset || 0);
- updateAttr('stroke-dasharray', lineDash.join(','));
- if (lineDashOffset || forceUpdate) {
- updateAttr('stroke-dashoffset', lineDashOffset);
- }
- }
- }
- else if (forceUpdate) {
- // Reset if force update.
- updateAttr('stroke-dasharray', NONE);
- }
- // PENDING reset
- for (let i = 0; i < strokeProps.length; i++) {
- const propName = strokeProps[i];
- if (forceUpdate || style[propName] !== DEFAULT_PATH_STYLE[propName]) {
- const val = style[propName] || DEFAULT_PATH_STYLE[propName];
- // TODO reset
- val && updateAttr(svgStrokeProps[i], val);
- }
- }
- }
- else if (forceUpdate) {
- updateAttr('stroke', NONE);
- }
- }
|