123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- import { createElement, normalizeColor } from './core';
- import ZRImage from '../graphic/Image';
- import { DEFAULT_FONT, getLineHeight } from '../contain/text';
- import { map } from '../core/util';
- import { normalizeLineDash } from '../graphic/helper/dashStyle';
- var NONE = 'none';
- var mathRound = Math.round;
- var mathSin = Math.sin;
- var mathCos = Math.cos;
- var PI = Math.PI;
- var PI2 = Math.PI * 2;
- var degree = 180 / PI;
- var EPSILON = 1e-4;
- function round3(val) {
- return mathRound(val * 1e3) / 1e3;
- }
- function round4(val) {
- return mathRound(val * 1e4) / 1e4;
- }
- function isAroundZero(val) {
- return val < EPSILON && val > -EPSILON;
- }
- function pathHasFill(style) {
- var fill = style.fill;
- return fill != null && fill !== NONE;
- }
- function pathHasStroke(style) {
- var stroke = style.stroke;
- return stroke != null && stroke !== NONE;
- }
- function setTransform(svgEl, m) {
- if (m) {
- attr(svgEl, 'transform', 'matrix('
- + round3(m[0]) + ','
- + round3(m[1]) + ','
- + round3(m[2]) + ','
- + round3(m[3]) + ','
- + round4(m[4]) + ','
- + round4(m[5])
- + ')');
- }
- }
- function attr(el, key, val) {
- if (!val || val.type !== 'linear' && val.type !== 'radial') {
- el.setAttribute(key, val);
- }
- }
- function attrXLink(el, key, val) {
- el.setAttributeNS('http://www.w3.org/1999/xlink', key, val);
- }
- function attrXML(el, key, val) {
- el.setAttributeNS('http://www.w3.org/XML/1998/namespace', key, val);
- }
- function bindStyle(svgEl, style, el) {
- var opacity = style.opacity == null ? 1 : style.opacity;
- if (el instanceof ZRImage) {
- attr(svgEl, 'opacity', opacity + '');
- return;
- }
- if (pathHasFill(style)) {
- var fill = normalizeColor(style.fill);
- attr(svgEl, 'fill', fill.color);
- attr(svgEl, 'fill-opacity', (style.fillOpacity != null
- ? style.fillOpacity * fill.opacity * opacity
- : fill.opacity * opacity) + '');
- }
- else {
- attr(svgEl, 'fill', NONE);
- }
- if (pathHasStroke(style)) {
- var stroke = normalizeColor(style.stroke);
- attr(svgEl, 'stroke', stroke.color);
- var strokeWidth = style.lineWidth;
- var strokeScale_1 = style.strokeNoScale
- ? el.getLineScale()
- : 1;
- attr(svgEl, 'stroke-width', (strokeScale_1 ? strokeWidth / strokeScale_1 : 0) + '');
- attr(svgEl, 'paint-order', style.strokeFirst ? 'stroke' : 'fill');
- attr(svgEl, 'stroke-opacity', (style.strokeOpacity != null
- ? style.strokeOpacity * stroke.opacity * opacity
- : stroke.opacity * opacity) + '');
- var lineDash = style.lineDash && strokeWidth > 0 && normalizeLineDash(style.lineDash, strokeWidth);
- if (lineDash) {
- var lineDashOffset = style.lineDashOffset;
- if (strokeScale_1 && strokeScale_1 !== 1) {
- lineDash = map(lineDash, function (rawVal) {
- return rawVal / strokeScale_1;
- });
- if (lineDashOffset) {
- lineDashOffset /= strokeScale_1;
- lineDashOffset = mathRound(lineDashOffset);
- }
- }
- attr(svgEl, 'stroke-dasharray', lineDash.join(','));
- attr(svgEl, 'stroke-dashoffset', (lineDashOffset || 0) + '');
- }
- else {
- attr(svgEl, 'stroke-dasharray', NONE);
- }
- style.lineCap && attr(svgEl, 'stroke-linecap', style.lineCap);
- style.lineJoin && attr(svgEl, 'stroke-linejoin', style.lineJoin);
- style.miterLimit && attr(svgEl, 'stroke-miterlimit', style.miterLimit + '');
- }
- else {
- attr(svgEl, 'stroke', NONE);
- }
- }
- var SVGPathRebuilder = (function () {
- function SVGPathRebuilder() {
- }
- SVGPathRebuilder.prototype.reset = function () {
- this._d = [];
- this._str = '';
- };
- SVGPathRebuilder.prototype.moveTo = function (x, y) {
- this._add('M', x, y);
- };
- SVGPathRebuilder.prototype.lineTo = function (x, y) {
- this._add('L', x, y);
- };
- SVGPathRebuilder.prototype.bezierCurveTo = function (x, y, x2, y2, x3, y3) {
- this._add('C', x, y, x2, y2, x3, y3);
- };
- SVGPathRebuilder.prototype.quadraticCurveTo = function (x, y, x2, y2) {
- this._add('Q', x, y, x2, y2);
- };
- SVGPathRebuilder.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
- this.ellipse(cx, cy, r, r, 0, startAngle, endAngle, anticlockwise);
- };
- SVGPathRebuilder.prototype.ellipse = function (cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise) {
- var firstCmd = this._d.length === 0;
- var dTheta = endAngle - startAngle;
- var clockwise = !anticlockwise;
- var dThetaPositive = Math.abs(dTheta);
- var isCircle = isAroundZero(dThetaPositive - PI2)
- || (clockwise ? dTheta >= PI2 : -dTheta >= PI2);
- var unifiedTheta = dTheta > 0 ? dTheta % PI2 : (dTheta % PI2 + PI2);
- var large = false;
- if (isCircle) {
- large = true;
- }
- else if (isAroundZero(dThetaPositive)) {
- large = false;
- }
- else {
- large = (unifiedTheta >= PI) === !!clockwise;
- }
- var x0 = round4(cx + rx * mathCos(startAngle));
- var y0 = round4(cy + ry * mathSin(startAngle));
- if (isCircle) {
- if (clockwise) {
- dTheta = PI2 - 1e-4;
- }
- else {
- dTheta = -PI2 + 1e-4;
- }
- large = true;
- if (firstCmd) {
- this._d.push('M', x0, y0);
- }
- }
- var x = round4(cx + rx * mathCos(startAngle + dTheta));
- var y = round4(cy + ry * mathSin(startAngle + dTheta));
- if (isNaN(x0) || isNaN(y0) || isNaN(rx) || isNaN(ry) || isNaN(psi) || isNaN(degree) || isNaN(x) || isNaN(y)) {
- return '';
- }
- this._d.push('A', round4(rx), round4(ry), mathRound(psi * degree), +large, +clockwise, x, y);
- };
- SVGPathRebuilder.prototype.rect = function (x, y, w, h) {
- this._add('M', x, y);
- this._add('L', x + w, y);
- this._add('L', x + w, y + h);
- this._add('L', x, y + h);
- this._add('L', x, y);
- this._add('Z');
- };
- SVGPathRebuilder.prototype.closePath = function () {
- if (this._d.length > 0) {
- this._add('Z');
- }
- };
- SVGPathRebuilder.prototype._add = function (cmd, a, b, c, d, e, f, g, h) {
- this._d.push(cmd);
- for (var i = 1; i < arguments.length; i++) {
- var val = arguments[i];
- if (isNaN(val)) {
- this._invalid = true;
- return;
- }
- this._d.push(round4(val));
- }
- };
- SVGPathRebuilder.prototype.generateStr = function () {
- this._str = this._invalid ? '' : this._d.join(' ');
- this._d = [];
- };
- SVGPathRebuilder.prototype.getStr = function () {
- return this._str;
- };
- return SVGPathRebuilder;
- }());
- var svgPath = {
- brush: function (el) {
- var style = el.style;
- var svgEl = el.__svgEl;
- if (!svgEl) {
- svgEl = createElement('path');
- el.__svgEl = svgEl;
- }
- if (!el.path) {
- el.createPathProxy();
- }
- var path = el.path;
- if (el.shapeChanged()) {
- path.beginPath();
- el.buildPath(path, el.shape);
- el.pathUpdated();
- }
- var pathVersion = path.getVersion();
- var elExt = el;
- var svgPathBuilder = elExt.__svgPathBuilder;
- if (elExt.__svgPathVersion !== pathVersion || !svgPathBuilder || el.style.strokePercent < 1) {
- if (!svgPathBuilder) {
- svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder();
- }
- svgPathBuilder.reset();
- path.rebuildPath(svgPathBuilder, el.style.strokePercent);
- svgPathBuilder.generateStr();
- elExt.__svgPathVersion = pathVersion;
- }
- attr(svgEl, 'd', svgPathBuilder.getStr());
- bindStyle(svgEl, style, el);
- setTransform(svgEl, el.transform);
- }
- };
- export { svgPath as path };
- var svgImage = {
- brush: function (el) {
- var style = el.style;
- var image = style.image;
- if (image instanceof HTMLImageElement) {
- image = image.src;
- }
- else if (image instanceof HTMLCanvasElement) {
- image = image.toDataURL();
- }
- if (!image) {
- return;
- }
- var x = style.x || 0;
- var y = style.y || 0;
- var dw = style.width;
- var dh = style.height;
- var svgEl = el.__svgEl;
- if (!svgEl) {
- svgEl = createElement('image');
- el.__svgEl = svgEl;
- }
- if (image !== el.__imageSrc) {
- attrXLink(svgEl, 'href', image);
- el.__imageSrc = image;
- }
- attr(svgEl, 'width', dw + '');
- attr(svgEl, 'height', dh + '');
- attr(svgEl, 'x', x + '');
- attr(svgEl, 'y', y + '');
- bindStyle(svgEl, style, el);
- setTransform(svgEl, el.transform);
- }
- };
- export { svgImage as image };
- var TEXT_ALIGN_TO_ANCHOR = {
- left: 'start',
- right: 'end',
- center: 'middle',
- middle: 'middle'
- };
- function adjustTextY(y, lineHeight, textBaseline) {
- if (textBaseline === 'top') {
- y += lineHeight / 2;
- }
- else if (textBaseline === 'bottom') {
- y -= lineHeight / 2;
- }
- return y;
- }
- var svgText = {
- brush: function (el) {
- var style = el.style;
- var text = style.text;
- text != null && (text += '');
- if (!text || isNaN(style.x) || isNaN(style.y)) {
- return;
- }
- var textSvgEl = el.__svgEl;
- if (!textSvgEl) {
- textSvgEl = createElement('text');
- attrXML(textSvgEl, 'xml:space', 'preserve');
- el.__svgEl = textSvgEl;
- }
- var font = style.font || DEFAULT_FONT;
- var textSvgElStyle = textSvgEl.style;
- textSvgElStyle.font = font;
- textSvgEl.textContent = text;
- bindStyle(textSvgEl, style, el);
- setTransform(textSvgEl, el.transform);
- var x = style.x || 0;
- var y = adjustTextY(style.y || 0, getLineHeight(font), style.textBaseline);
- var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign]
- || style.textAlign;
- attr(textSvgEl, 'dominant-baseline', 'central');
- attr(textSvgEl, 'text-anchor', textAlign);
- attr(textSvgEl, 'x', x + '');
- attr(textSvgEl, 'y', y + '');
- }
- };
- export { svgText as text };
|