mapStyleToAttrs.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import Path, { DEFAULT_PATH_STYLE, PathStyleProps } from '../graphic/Path';
  2. import ZRImage, { ImageStyleProps } from '../graphic/Image';
  3. import TSpan, { TSpanStyleProps } from '../graphic/TSpan';
  4. import { getLineDash } from '../canvas/dashStyle';
  5. import { map } from '../core/util';
  6. import { normalizeColor } from './helper';
  7. type AllStyleOption = PathStyleProps | TSpanStyleProps | ImageStyleProps;
  8. const NONE = 'none';
  9. const mathRound = Math.round;
  10. function pathHasFill(style: AllStyleOption): style is PathStyleProps {
  11. const fill = (style as PathStyleProps).fill;
  12. return fill != null && fill !== NONE;
  13. }
  14. function pathHasStroke(style: AllStyleOption): style is PathStyleProps {
  15. const stroke = (style as PathStyleProps).stroke;
  16. return stroke != null && stroke !== NONE;
  17. }
  18. const strokeProps = ['lineCap', 'miterLimit', 'lineJoin'] as const;
  19. const svgStrokeProps = map(strokeProps, prop => `stroke-${prop.toLowerCase()}`);
  20. export default function mapStyleToAttrs(
  21. updateAttr: (key: string, val: string | number) => void,
  22. style: AllStyleOption,
  23. el: Path | TSpan | ZRImage,
  24. /**
  25. * Will try not to set the attribute if it's using default value if not using forceUpdate.
  26. * Mainly for reduce the generated size in svg-ssr mode.
  27. */
  28. forceUpdate: boolean
  29. ): void {
  30. const opacity = style.opacity == null ? 1 : style.opacity;
  31. // only set opacity. stroke and fill cannot be applied to svg image
  32. if (el instanceof ZRImage) {
  33. updateAttr('opacity', opacity);
  34. return;
  35. }
  36. if (pathHasFill(style)) {
  37. const fill = normalizeColor(style.fill as string);
  38. updateAttr('fill', fill.color);
  39. const fillOpacity = style.fillOpacity != null
  40. ? style.fillOpacity * fill.opacity * opacity
  41. : fill.opacity * opacity;
  42. if (forceUpdate || fillOpacity < 1) {
  43. updateAttr('fill-opacity', fillOpacity);
  44. }
  45. }
  46. else {
  47. updateAttr('fill', NONE);
  48. }
  49. if (pathHasStroke(style)) {
  50. const stroke = normalizeColor(style.stroke as string);
  51. updateAttr('stroke', stroke.color);
  52. const strokeScale = style.strokeNoScale
  53. ? (el as Path).getLineScale()
  54. : 1;
  55. const strokeWidth = (strokeScale ? (style.lineWidth || 0) / strokeScale : 0);
  56. const strokeOpacity = style.strokeOpacity != null
  57. ? style.strokeOpacity * stroke.opacity * opacity
  58. : stroke.opacity * opacity;
  59. const strokeFirst = style.strokeFirst;
  60. if (forceUpdate || strokeWidth !== 1) {
  61. updateAttr('stroke-width', strokeWidth);
  62. }
  63. // stroke then fill for text; fill then stroke for others
  64. if (forceUpdate || strokeFirst) {
  65. updateAttr('paint-order', strokeFirst ? 'stroke' : 'fill');
  66. }
  67. if (forceUpdate || strokeOpacity < 1) {
  68. updateAttr('stroke-opacity', strokeOpacity);
  69. }
  70. if (style.lineDash) {
  71. let [lineDash, lineDashOffset] = getLineDash(el);
  72. if (lineDash) {
  73. lineDashOffset = mathRound(lineDashOffset || 0);
  74. updateAttr('stroke-dasharray', lineDash.join(','));
  75. if (lineDashOffset || forceUpdate) {
  76. updateAttr('stroke-dashoffset', lineDashOffset);
  77. }
  78. }
  79. }
  80. else if (forceUpdate) {
  81. // Reset if force update.
  82. updateAttr('stroke-dasharray', NONE);
  83. }
  84. // PENDING reset
  85. for (let i = 0; i < strokeProps.length; i++) {
  86. const propName = strokeProps[i];
  87. if (forceUpdate || style[propName] !== DEFAULT_PATH_STYLE[propName]) {
  88. const val = style[propName] || DEFAULT_PATH_STYLE[propName];
  89. // TODO reset
  90. val && updateAttr(svgStrokeProps[i], val);
  91. }
  92. }
  93. }
  94. else if (forceUpdate) {
  95. updateAttr('stroke', NONE);
  96. }
  97. }