Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zrender

Package Overview
Dependencies
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zrender - npm Package Compare versions

Comparing version 4.0.4 to 4.0.5

.eslintignore

14

lib/core/env.js

@@ -20,3 +20,4 @@ /**

svgSupported: false,
touchEventsSupported: true
touchEventsSupported: true,
domSupported: false
};

@@ -30,3 +31,4 @@ } else if (typeof document === 'undefined' && typeof self !== 'undefined') {

worker: true,
canvasSupported: true
canvasSupported: true,
domSupported: false
};

@@ -42,3 +44,4 @@ } else if (typeof navigator === 'undefined') {

canvasSupported: true,
svgSupported: true
svgSupported: true,
domSupported: false
};

@@ -143,4 +146,5 @@ } else {

// standard. So we exclude that. (IE 10 is hardly used on touch device)
&& (browser.edge || browser.ie && browser.version >= 11) // passiveSupported: detectPassiveSupport()
&& (browser.edge || browser.ie && browser.version >= 11),
// passiveSupported: detectPassiveSupport()
domSupported: typeof document !== 'undefined'
};

@@ -147,0 +151,0 @@ } // See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection

@@ -216,3 +216,3 @@ var curve = require("./curve");

this._xi = mathCos(endAngle) * r + cx;
this._yi = mathSin(endAngle) * r + cx;
this._yi = mathSin(endAngle) * r + cy;
return this;

@@ -219,0 +219,0 @@ },

@@ -634,3 +634,6 @@ /**

function HashMap(obj) {
var isArr = isArray(obj);
var isArr = isArray(obj); // Key should not be set on this, otherwise
// methods get/set/... may be overrided.
this.data = {};
var thisMap = this;

@@ -642,5 +645,4 @@ obj instanceof HashMap ? obj.each(visit) : obj && each(obj, visit);

}
} // Add prefix to avoid conflict with Object.prototype.
}
HashMap.prototype = {

@@ -652,3 +654,3 @@ constructor: HashMap,

get: function (key) {
return this.hasOwnProperty(key) ? this[key] : null;
return this.data.hasOwnProperty(key) ? this.data[key] : null;
},

@@ -658,3 +660,3 @@ set: function (key, value) {

// used in this case: `var someVal = map.set('a', genVal());`
return this[key] = value;
return this.data[key] = value;
},

@@ -666,4 +668,4 @@ // Although util.each can be performed on this hashMap directly, user

for (var key in this) {
this.hasOwnProperty(key) && cb(this[key], key);
for (var key in this.data) {
this.data.hasOwnProperty(key) && cb(this.data[key], key);
}

@@ -673,3 +675,3 @@ },

removeKey: function (key) {
delete this[key];
delete this.data[key];
}

@@ -676,0 +678,0 @@ };

@@ -21,2 +21,7 @@ var zrUtil = require("./core/util");

var _parseSVG = require("./tool/parseSVG");
var parseSVG = _parseSVG.parseSVG;
exports.parseSVG = _parseSVG.parseSVG;
var _Group = require("./container/Group");

@@ -23,0 +28,0 @@

@@ -140,4 +140,8 @@ var zrUtil = require("../core/util");

incremental: false,
// inplace is used with incremental
inplace: false,
/**
* Scale ratio for global scale.
* @type {boolean}
*/
globalScaleRatio: 1,
beforeBrush: function (ctx) {},

@@ -197,3 +201,3 @@ afterBrush: function (ctx) {},

dirty: function () {
this.__dirty = true;
this.__dirty = this.__dirtyText = true;
this._rect = null;

@@ -200,0 +204,0 @@ this.__zr && this.__zr.refresh();

@@ -53,3 +53,3 @@ var LRU = require("../../core/LRU");

!image && (image = new Image());
image.onload = imageOnLoad;
image.onload = image.onerror = imageOnLoad;
globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {

@@ -71,3 +71,3 @@ image: image,

var cachedImgObj = this.__cachedImgObj;
this.onload = this.__cachedImgObj = null;
this.onload = this.onerror = this.__cachedImgObj = null;

@@ -74,0 +74,0 @@ for (var i = 0; i < cachedImgObj.pending.length; i++) {

@@ -9,2 +9,3 @@ var _util = require("../../core/util");

var isObject = _util.isObject;
var isFunction = _util.isFunction;

@@ -29,3 +30,6 @@ var textContain = require("../../contain/text");

middle: 1
};
}; // Different from `STYLE_COMMON_PROPS` of `graphic/Style`,
// the default value of shadowColor is `'transparent'`.
var SHADOW_STYLE_COMMON_PROPS = [['textShadowBlur', 'shadowBlur', 0], ['textShadowOffsetX', 'shadowOffsetX', 0], ['textShadowOffsetY', 'shadowOffsetY', 0], ['textShadowColor', 'shadowColor', 'transparent']];
/**

@@ -65,16 +69,39 @@ * @param {module:zrender/graphic/Style} style

* If set false, rect text is not used.
* @param {Element} [prevEl] For ctx prop cache.
*/
function renderText(hostEl, ctx, text, style, rect) {
style.rich ? renderRichText(hostEl, ctx, text, style, rect) : renderPlainText(hostEl, ctx, text, style, rect);
}
function renderText(hostEl, ctx, text, style, rect, prevEl) {
style.rich ? renderRichText(hostEl, ctx, text, style, rect) : renderPlainText(hostEl, ctx, text, style, rect, prevEl);
} // Avoid setting to ctx according to prevEl if possible for
// performance in scenarios of large amount text.
function renderPlainText(hostEl, ctx, text, style, rect) {
var font = setCtx(ctx, 'font', style.font || textContain.DEFAULT_FONT);
function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
'use strict';
var prevStyle = prevEl && prevEl.style; // Some cache only available on textEl.
var isPrevTextEl = prevStyle && prevEl.type === 'text';
var styleFont = style.font || textContain.DEFAULT_FONT;
if (!isPrevTextEl || styleFont !== (prevStyle.font || textContain.DEFAULT_FONT)) {
ctx.font = styleFont;
} // Use the final font from context-2d, because the final
// font might not be the style.font when it is illegal.
// But get `ctx.font` might be time consuming.
var computedFont = hostEl.__computedFont;
if (hostEl.__styleFont !== styleFont) {
hostEl.__styleFont = styleFont;
computedFont = hostEl.__computedFont = ctx.font;
}
var textPadding = style.textPadding;
var contentBlock = hostEl.__textCotentBlock;
if (!contentBlock || hostEl.__dirty) {
contentBlock = hostEl.__textCotentBlock = textContain.parsePlainText(text, font, textPadding, style.truncate);
if (!contentBlock || hostEl.__dirtyText) {
contentBlock = hostEl.__textCotentBlock = textContain.parsePlainText(text, computedFont, textPadding, style.truncate);
}

@@ -88,3 +115,3 @@

var baseY = boxPos.baseY;
var textAlign = boxPos.textAlign;
var textAlign = boxPos.textAlign || 'left';
var textVerticalAlign = boxPos.textVerticalAlign; // Origin of textRotation should be the base point of text drawing.

@@ -100,3 +127,3 @@

// Consider performance, do not call getTextWidth util necessary.
var textWidth = textContain.getWidth(text, font);
var textWidth = textContain.getWidth(text, computedFont);
var outerWidth = textWidth;

@@ -111,16 +138,29 @@ textPadding && (outerWidth += textPadding[1] + textPadding[3]);

}
}
} // Always set textAlign and textBase line, because it is difficute to calculate
// textAlign from prevEl, and we dont sure whether textAlign will be reset if
// font set happened.
setCtx(ctx, 'textAlign', textAlign || 'left'); // Force baseline to be "middle". Otherwise, if using "top", the
ctx.textAlign = textAlign; // Force baseline to be "middle". Otherwise, if using "top", the
// text will offset downward a little bit in font "Microsoft YaHei".
setCtx(ctx, 'textBaseline', 'middle'); // Always set shadowBlur and shadowOffset to avoid leak from displayable.
ctx.textBaseline = 'middle'; // Always set shadowBlur and shadowOffset to avoid leak from displayable.
setCtx(ctx, 'shadowBlur', style.textShadowBlur || 0);
setCtx(ctx, 'shadowColor', style.textShadowColor || 'transparent');
setCtx(ctx, 'shadowOffsetX', style.textShadowOffsetX || 0);
setCtx(ctx, 'shadowOffsetY', style.textShadowOffsetY || 0); // `textBaseline` is set as 'middle'.
for (var i = 0; i < SHADOW_STYLE_COMMON_PROPS.length; i++) {
var propItem = SHADOW_STYLE_COMMON_PROPS[i];
var styleProp = propItem[0];
var ctxProp = propItem[1];
var val = style[styleProp];
if (!isPrevTextEl || val !== prevStyle[styleProp]) {
ctx[ctxProp] = fixShadow(ctx, ctxProp, val || propItem[2]);
}
} // `textBaseline` is set as 'middle'.
textY += lineHeight / 2;
var textStrokeWidth = style.textStrokeWidth;
var textStrokeWidthPrev = isPrevTextEl ? prevStyle.textStrokeWidth : null;
var strokeWidthChanged = !isPrevTextEl || textStrokeWidth !== textStrokeWidthPrev;
var strokeChanged = !isPrevTextEl || strokeWidthChanged || style.textStroke !== prevStyle.textStroke;
var textStroke = getStroke(style.textStroke, textStrokeWidth);

@@ -130,15 +170,29 @@ var textFill = getFill(style.textFill);

if (textStroke) {
setCtx(ctx, 'lineWidth', textStrokeWidth);
setCtx(ctx, 'strokeStyle', textStroke);
if (strokeWidthChanged) {
ctx.lineWidth = textStrokeWidth;
}
if (strokeChanged) {
ctx.strokeStyle = textStroke;
}
}
if (textFill) {
setCtx(ctx, 'fillStyle', textFill);
}
if (!isPrevTextEl || style.textFill !== prevStyle.textFill || prevStyle.textBackgroundColor) {
ctx.fillStyle = textFill;
}
} // Optimize simply, in most cases only one line exists.
for (var i = 0; i < textLines.length; i++) {
if (textLines.length === 1) {
// Fill after stroke so the outline will not cover the main part.
textStroke && ctx.strokeText(textLines[i], textX, textY);
textFill && ctx.fillText(textLines[i], textX, textY);
textY += lineHeight;
textStroke && ctx.strokeText(textLines[0], textX, textY);
textFill && ctx.fillText(textLines[0], textX, textY);
} else {
for (var i = 0; i < textLines.length; i++) {
// Fill after stroke so the outline will not cover the main part.
textStroke && ctx.strokeText(textLines[i], textX, textY);
textFill && ctx.fillText(textLines[i], textX, textY);
textY += lineHeight;
}
}

@@ -150,3 +204,3 @@ }

if (!contentBlock || hostEl.__dirty) {
if (!contentBlock || hostEl.__dirtyText) {
contentBlock = hostEl.__textCotentBlock = textContain.parseRichText(text, style);

@@ -245,3 +299,4 @@ }

function placeToken(hostEl, ctx, token, style, lineHeight, lineTop, x, textAlign) {
var tokenStyle = style.rich[token.styleName] || {}; // 'ctx.textBaseline' is always set as 'middle', for sake of
var tokenStyle = style.rich[token.styleName] || {};
tokenStyle.text = token.text; // 'ctx.textBaseline' is always set as 'middle', for sake of
// the bias of "Microsoft YaHei".

@@ -293,3 +348,3 @@

return style.textBackgroundColor || style.textBorderWidth && style.textBorderColor;
} // style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius}
} // style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius, text}
// shape: {x, y, width, height}

@@ -329,2 +384,13 @@

setCtx(ctx, 'fillStyle', textBackgroundColor);
if (style.fillOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.fillOpacity * style.opacity;
ctx.fill();
ctx.globalAlpha = originalGlobalAlpha;
} else {
ctx.fill();
}
} else if (isFunction(textBackgroundColor)) {
setCtx(ctx, 'fillStyle', textBackgroundColor(style));
ctx.fill();

@@ -343,3 +409,11 @@ } else if (isObject(textBackgroundColor)) {

setCtx(ctx, 'strokeStyle', textBorderColor);
ctx.stroke();
if (style.strokeOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.strokeOpacity * style.opacity;
ctx.stroke();
ctx.globalAlpha = originalGlobalAlpha;
} else {
ctx.stroke();
}
}

@@ -346,0 +420,0 @@ }

@@ -33,2 +33,5 @@ var textHelper = require("../helper/text");

} // FIXME
// Do not provide prevEl to `textHelper.renderText` for ctx prop cache,
// but use `ctx.save()` and `ctx.restore()`. Because the cache for rect
// text propably break the cache for its host elements.

@@ -35,0 +38,0 @@

@@ -108,3 +108,12 @@ var Displayable = require("./Displayable");

hasFill && path.fill(ctx);
if (hasFill) {
if (style.fillOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.fillOpacity * style.opacity;
path.fill(ctx);
ctx.globalAlpha = originalGlobalAlpha;
} else {
path.fill(ctx);
}
}

@@ -116,3 +125,12 @@ if (lineDash && ctxLineDash) {

hasStroke && path.stroke(ctx);
if (hasStroke) {
if (style.strokeOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.strokeOpacity * style.opacity;
path.stroke(ctx);
ctx.globalAlpha = originalGlobalAlpha;
} else {
path.stroke(ctx);
}
}

@@ -242,3 +260,3 @@ if (lineDash && ctxLineDash) {

this.__dirty = true;
this.__dirty = this.__dirtyText = true;
this.__zr && this.__zr.refresh(); // Used as a clipping path

@@ -245,0 +263,0 @@

@@ -6,5 +6,4 @@ var fixShadow = require("./helper/fixShadow");

var Style = function (opts, host) {
var Style = function (opts) {
this.extendFrom(opts, false);
this.host = host;
};

@@ -56,7 +55,2 @@

/**
* @type {module:zrender/graphic/Displayable}
*/
host: null,
/**
* @type {string}

@@ -77,2 +71,12 @@ */

/**
* @type {number}
*/
fillOpacity: null,
/**
* @type {number}
*/
strokeOpacity: null,
/**
* @type {Array.<number>}

@@ -79,0 +83,0 @@ */

@@ -31,6 +31,7 @@ var Displayable = require("./Displayable");

text != null && (text += ''); // Always bind style
text != null && (text += ''); // Do not apply style.bind in Text node. Because the real bind job
// is in textHelper.renderText, and performance of text render should
// be considered.
// style.bind(ctx, this, prevEl);
style.bind(ctx, this, prevEl);
if (!textHelper.needDrawText(text, style)) {

@@ -41,3 +42,3 @@ return;

this.setTransform(ctx);
textHelper.renderText(this, ctx, text, style);
textHelper.renderText(this, ctx, text, style, null, prevEl);
this.restoreTransform(ctx);

@@ -44,0 +45,0 @@ },

@@ -9,2 +9,4 @@ var util = require("./core/util");

var eventTool = require("./core/event");
var SILENT = 'silent';

@@ -29,6 +31,11 @@

zrByTouch: event.zrByTouch,
which: event.which
which: event.which,
stop: stopEvent
};
}
function stopEvent(event) {
eventTool.stop(this.event);
}
function EmptyProxy() {}

@@ -35,0 +42,0 @@

@@ -136,120 +136,141 @@ var Animator = require("../animation/Animator");

animateTo: function (target, time, delay, easing, callback, forceAnimate) {
// animateTo(target, time, easing, callback);
if (isString(delay)) {
animateTo(this, target, time, delay, easing, callback, forceAnimate);
},
/**
* Animate from the target state to current state.
* The params and the return value are the same as `this.animateTo`.
*/
animateFrom: function (target, time, delay, easing, callback, forceAnimate) {
animateTo(this, target, time, delay, easing, callback, forceAnimate, true);
}
};
function animateTo(animatable, target, time, delay, easing, callback, forceAnimate, reverse) {
// animateTo(target, time, easing, callback);
if (isString(delay)) {
callback = easing;
easing = delay;
delay = 0;
} // animateTo(target, time, delay, callback);
else if (isFunction(easing)) {
callback = easing;
easing = delay;
easing = 'linear';
delay = 0;
} // animateTo(target, time, delay, callback);
else if (isFunction(easing)) {
callback = easing;
easing = 'linear';
} // animateTo(target, time, callback);
else if (isFunction(delay)) {
callback = delay;
delay = 0;
} // animateTo(target, time, callback);
else if (isFunction(delay)) {
callback = delay;
delay = 0;
} // animateTo(target, callback)
else if (isFunction(time)) {
callback = time;
} // animateTo(target, callback)
else if (isFunction(time)) {
callback = time;
time = 500;
} // animateTo(target)
else if (!time) {
time = 500;
} // animateTo(target)
else if (!time) {
time = 500;
} // Stop all previous animations
} // Stop all previous animations
this.stopAnimation();
animatable.stopAnimation();
animateToShallow(animatable, '', animatable, target, time, delay, reverse); // Animators may be removed immediately after start
// if there is nothing to animate
this._animateToShallow('', this, target, time, delay); // Animators may be removed immediately after start
// if there is nothing to animate
var animators = animatable.animators.slice();
var count = animators.length;
function done() {
count--;
var animators = this.animators.slice();
var count = animators.length;
if (!count) {
callback && callback();
}
} // No animators. This should be checked before animators[i].start(),
// because 'done' may be executed immediately if no need to animate.
function done() {
count--;
if (!count) {
callback && callback();
}
} // No animators. This should be checked before animators[i].start(),
// because 'done' may be executed immediately if no need to animate.
if (!count) {
callback && callback();
} // Start after all animators created
// Incase any animator is done immediately when all animation properties are not changed
if (!count) {
callback && callback();
} // Start after all animators created
// Incase any animator is done immediately when all animation properties are not changed
for (var i = 0; i < animators.length; i++) {
animators[i].done(done).start(easing, forceAnimate);
}
}
/**
* @param {string} path=''
* @param {Object} source=animatable
* @param {Object} target
* @param {number} [time=500]
* @param {number} [delay=0]
* @param {boolean} [reverse] If `true`, animate
* from the `target` to current state.
*
* @example
* // Animate position
* el._animateToShallow({
* position: [10, 10]
* })
*
* // Animate shape, style and position in 100ms, delayed 100ms
* el._animateToShallow({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100)
*/
for (var i = 0; i < animators.length; i++) {
animators[i].done(done).start(easing, forceAnimate);
function animateToShallow(animatable, path, source, target, time, delay, reverse) {
var objShallow = {};
var propertyCount = 0;
for (var name in target) {
if (!target.hasOwnProperty(name)) {
continue;
}
},
/**
* @private
* @param {string} path=''
* @param {Object} source=this
* @param {Object} target
* @param {number} [time=500]
* @param {number} [delay=0]
*
* @example
* // Animate position
* el._animateToShallow({
* position: [10, 10]
* })
*
* // Animate shape, style and position in 100ms, delayed 100ms
* el._animateToShallow({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100)
*/
_animateToShallow: function (path, source, target, time, delay) {
var objShallow = {};
var propertyCount = 0;
for (var name in target) {
if (!target.hasOwnProperty(name)) {
continue;
}
if (source[name] != null) {
if (isObject(target[name]) && !isArrayLike(target[name])) {
this._animateToShallow(path ? path + '.' + name : name, source[name], target[name], time, delay);
if (source[name] != null) {
if (isObject(target[name]) && !isArrayLike(target[name])) {
animateToShallow(animatable, path ? path + '.' + name : name, source[name], target[name], time, delay, reverse);
} else {
if (reverse) {
objShallow[name] = source[name];
setAttrByPath(animatable, path, name, target[name]);
} else {
objShallow[name] = target[name];
propertyCount++;
}
} else if (target[name] != null) {
// Attr directly if not has property
// FIXME, if some property not needed for element ?
if (!path) {
this.attr(name, target[name]);
} else {
// Shape or style
var props = {};
props[path] = {};
props[path][name] = target[name];
this.attr(props);
}
propertyCount++;
}
} else if (target[name] != null && !reverse) {
setAttrByPath(animatable, path, name, target[name]);
}
}
if (propertyCount > 0) {
this.animate(path, false).when(time == null ? 500 : time, objShallow).delay(delay || 0);
}
if (propertyCount > 0) {
animatable.animate(path, false).when(time == null ? 500 : time, objShallow).delay(delay || 0);
}
}
return this;
function setAttrByPath(el, path, name, value) {
// Attr directly if not has property
// FIXME, if some property not needed for element ?
if (!path) {
el.attr(name, value);
} else {
// Only support set shape or style
var props = {};
props[path] = {};
props[path][name] = value;
el.attr(props);
}
};
}
var _default = Animatable;
module.exports = _default;
/**
* 事件扩展
* Event Mixin
* @module zrender/mixin/Eventful

@@ -9,9 +9,23 @@ * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)

/**
* 事件分发器
* Event dispatcher.
*
* @alias module:zrender/mixin/Eventful
* @constructor
* @param {Object} [eventProcessor] The object eventProcessor is the scope when
* `eventProcessor.xxx` called.
* @param {Function} [eventProcessor.normalizeQuery]
* param: {string|Object} Raw query.
* return: {string|Object} Normalized query.
* @param {Function} [eventProcessor.filter] Event will be dispatched only
* if it returns `true`.
* param: {string} eventType
* param: {string|Object} query
* return: {boolean}
* @param {Function} [eventProcessor.afterTrigger] Call after all handlers called.
* param: {string} eventType
*/
var Eventful = function () {
var Eventful = function (eventProcessor) {
this._$handlers = {};
this._$eventProcessor = eventProcessor;
};

@@ -23,11 +37,18 @@

/**
* 单次触发绑定,trigger后销毁
* The handler can only be triggered once, then removed.
*
* @param {string} event 事件名
* @param {Function} handler 响应函数
* @param {string} event The event name.
* @param {string|Object} [query] Condition used on event filter.
* @param {Function} handler The event handler.
* @param {Object} context
*/
one: function (event, handler, context) {
one: function (event, query, handler, context) {
var _h = this._$handlers;
if (typeof query === 'function') {
context = handler;
handler = query;
query = null;
}
if (!handler || !event) {

@@ -37,2 +58,4 @@ return this;

query = normalizeQuery(this, query);
if (!_h[event]) {

@@ -51,2 +74,3 @@ _h[event] = [];

one: true,
query: query,
ctx: context || this

@@ -59,10 +83,18 @@ });

/**
* 绑定事件
* @param {string} event 事件名
* @param {Function} handler 事件处理函数
* Bind a handler.
*
* @param {string} event The event name.
* @param {string|Object} [query] Condition used on event filter.
* @param {Function} handler The event handler.
* @param {Object} [context]
*/
on: function (event, handler, context) {
on: function (event, query, handler, context) {
var _h = this._$handlers;
if (typeof query === 'function') {
context = handler;
handler = query;
query = null;
}
if (!handler || !event) {

@@ -72,2 +104,4 @@ return this;

query = normalizeQuery(this, query);
if (!_h[event]) {

@@ -86,2 +120,3 @@ _h[event] = [];

one: false,
query: query,
ctx: context || this

@@ -94,3 +129,4 @@ });

/**
* 是否绑定了事件
* Whether any handler has bound.
*
* @param {string} event

@@ -105,5 +141,6 @@ * @return {boolean}

/**
* 解绑事件
* @param {string} event 事件名
* @param {Function} [handler] 事件处理函数
* Unbind a event.
*
* @param {string} event The event name.
* @param {Function} [handler] The event handler.
*/

@@ -123,3 +160,3 @@ off: function (event, handler) {

for (var i = 0, l = _h[event].length; i < l; i++) {
if (_h[event][i]['h'] != handler) {
if (_h[event][i].h !== handler) {
newList.push(_h[event][i]);

@@ -143,8 +180,11 @@ }

/**
* 事件分发
* Dispatch a event.
*
* @param {string} type 事件类型
* @param {string} type The event name.
*/
trigger: function (type) {
if (this._$handlers[type]) {
var _h = this._$handlers[type];
var eventProcessor = this._$eventProcessor;
if (_h) {
var args = arguments;

@@ -157,21 +197,24 @@ var argLen = args.length;

var _h = this._$handlers[type];
var len = _h.length;
for (var i = 0; i < len;) {
// Optimize advise from backbone
var hItem = _h[i];
if (eventProcessor && eventProcessor.filter && hItem.query != null && !eventProcessor.filter(type, hItem.query)) {
i++;
continue;
} // Optimize advise from backbone
switch (argLen) {
case 1:
_h[i]['h'].call(_h[i]['ctx']);
hItem.h.call(hItem.ctx);
break;
case 2:
_h[i]['h'].call(_h[i]['ctx'], args[1]);
hItem.h.call(hItem.ctx, args[1]);
break;
case 3:
_h[i]['h'].call(_h[i]['ctx'], args[1], args[2]);
hItem.h.call(hItem.ctx, args[1], args[2]);
break;

@@ -181,8 +224,7 @@

// have more than 2 given arguments
_h[i]['h'].apply(_h[i]['ctx'], args);
hItem.h.apply(hItem.ctx, args);
break;
}
if (_h[i]['one']) {
if (hItem.one) {
_h.splice(i, 1);

@@ -197,2 +239,3 @@

eventProcessor && eventProcessor.afterTrigger && eventProcessor.afterTrigger(type);
return this;

@@ -202,7 +245,11 @@ },

/**
* 带有context的事件分发, 最后一个参数是事件回调的context
* @param {string} type 事件类型
* Dispatch a event with context, which is specified at the last parameter.
*
* @param {string} type The event name.
*/
triggerWithContext: function (type) {
if (this._$handlers[type]) {
var _h = this._$handlers[type];
var eventProcessor = this._$eventProcessor;
if (_h) {
var args = arguments;

@@ -216,21 +263,24 @@ var argLen = args.length;

var ctx = args[args.length - 1];
var _h = this._$handlers[type];
var len = _h.length;
for (var i = 0; i < len;) {
// Optimize advise from backbone
var hItem = _h[i];
if (eventProcessor && eventProcessor.filter && hItem.query != null && !eventProcessor.filter(type, hItem.query)) {
i++;
continue;
} // Optimize advise from backbone
switch (argLen) {
case 1:
_h[i]['h'].call(ctx);
hItem.h.call(ctx);
break;
case 2:
_h[i]['h'].call(ctx, args[1]);
hItem.h.call(ctx, args[1]);
break;
case 3:
_h[i]['h'].call(ctx, args[1], args[2]);
hItem.h.call(ctx, args[1], args[2]);
break;

@@ -240,8 +290,7 @@

// have more than 2 given arguments
_h[i]['h'].apply(ctx, args);
hItem.h.apply(ctx, args);
break;
}
if (_h[i]['one']) {
if (hItem.one) {
_h.splice(i, 1);

@@ -256,6 +305,19 @@

eventProcessor && eventProcessor.afterTrigger && eventProcessor.afterTrigger(type);
return this;
}
}; // 对象可以通过 onxxxx 绑定事件
};
function normalizeQuery(host, query) {
var eventProcessor = host._$eventProcessor;
if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
query = eventProcessor.normalizeQuery(query);
}
return query;
} // ----------------------
// The events in zrender
// ----------------------
/**

@@ -345,3 +407,4 @@ * @event module:zrender/mixin/Eventful#onclick

var _default = Eventful;
module.exports = _default;

@@ -72,2 +72,4 @@ var matrix = require("../core/matrix");

var scaleTmp = [];
transformableProto.updateTransform = function () {

@@ -103,2 +105,16 @@ var parent = this.parent;

this.transform = m;
var globalScaleRatio = this.globalScaleRatio;
if (globalScaleRatio != null && globalScaleRatio !== 1) {
this.getGlobalScale(scaleTmp);
var relX = scaleTmp[0] < 0 ? -1 : 1;
var relY = scaleTmp[1] < 0 ? -1 : 1;
var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;
m[0] *= sx;
m[1] *= sx;
m[2] *= sy;
m[3] *= sy;
}
this.invTransform = this.invTransform || matrix.create();

@@ -134,20 +150,10 @@ matrix.invert(this.invTransform, m);

var tmpTransform = [];
/**
* 分解`transform`矩阵到`position`, `rotation`, `scale`
*/
var originTransform = matrix.create();
transformableProto.decomposeTransform = function () {
if (!this.transform) {
transformableProto.setLocalTransform = function (m) {
if (!m) {
// TODO return or set identity?
return;
}
var parent = this.parent;
var m = this.transform;
if (parent && parent.transform) {
// Get local transform and decompose them to position, scale, rotation
matrix.mul(tmpTransform, parent.invTransform, m);
m = tmpTransform;
}
var sx = m[0] * m[0] + m[1] * m[1];

@@ -181,2 +187,34 @@ var sy = m[2] * m[2] + m[3] * m[3];

/**
* 分解`transform`矩阵到`position`, `rotation`, `scale`
*/
transformableProto.decomposeTransform = function () {
if (!this.transform) {
return;
}
var parent = this.parent;
var m = this.transform;
if (parent && parent.transform) {
// Get local transform and decompose them to position, scale, rotation
matrix.mul(tmpTransform, parent.invTransform, m);
m = tmpTransform;
}
var origin = this.origin;
if (origin && (origin[0] || origin[1])) {
originTransform[4] = origin[0];
originTransform[5] = origin[1];
matrix.mul(tmpTransform, m, originTransform);
tmpTransform[4] -= origin[0];
tmpTransform[5] -= origin[1];
m = tmpTransform;
}
this.setLocalTransform(m);
};
/**
* Get global scale

@@ -187,21 +225,24 @@ * @return {Array.<number>}

transformableProto.getGlobalScale = function () {
transformableProto.getGlobalScale = function (out) {
var m = this.transform;
out = out || [];
if (!m) {
return [1, 1];
out[0] = 1;
out[1] = 1;
return out;
}
var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
if (m[0] < 0) {
sx = -sx;
out[0] = -out[0];
}
if (m[3] < 0) {
sy = -sy;
out[1] = -out[1];
}
return [sx, sy];
return out;
};

@@ -208,0 +249,0 @@ /**

@@ -274,9 +274,14 @@ var _config = require("./config");

style: el.style,
shape: el.shape
shape: el.shape,
z: el.z,
z2: el.z2,
silent: el.silent
});
elMirror.__from = el;
el.__hoverMir = elMirror;
elMirror.setStyle(hoverStyle);
hoverStyle && elMirror.setStyle(hoverStyle);
this._hoverElements.push(elMirror);
return elMirror;
},

@@ -434,3 +439,3 @@ removeHover: function (el) {

el.__dirty = false;
el.__dirty = el.__dirtyText = false;

@@ -437,0 +442,0 @@ if (useTimer) {

@@ -70,3 +70,3 @@ var _core = require("./core");

function bindStyle(svgEl, style, isText) {
function bindStyle(svgEl, style, isText, el) {
if (pathHasFill(style, isText)) {

@@ -96,3 +96,3 @@ var fill = isText ? style.textFill : style.fill;

attr(svgEl, 'fill', fill);
attr(svgEl, 'fill-opacity', style.opacity);
attr(svgEl, 'fill-opacity', style.fillOpacity != null ? style.fillOpacity * style.opacity : style.opacity);
} else {

@@ -107,7 +107,7 @@ attr(svgEl, 'fill', NONE);

var strokeWidth = isText ? style.textStrokeWidth : style.lineWidth;
var strokeScale = !isText && style.strokeNoScale ? style.host.getLineScale() : 1;
var strokeScale = !isText && style.strokeNoScale ? el.getLineScale() : 1;
attr(svgEl, 'stroke-width', strokeWidth / strokeScale); // stroke then fill for text; fill then stroke for others
attr(svgEl, 'paint-order', isText ? 'stroke' : 'fill');
attr(svgEl, 'stroke-opacity', style.opacity);
attr(svgEl, 'stroke-opacity', style.strokeOpacity != null ? style.strokeOpacity : style.opacity);
var lineDash = style.lineDash;

@@ -271,3 +271,3 @@

bindStyle(svgEl, style);
bindStyle(svgEl, style, false, el);
setTransform(svgEl, el.transform);

@@ -389,3 +389,3 @@

attr(textSvgEl, 'y', y);
bindStyle(textSvgEl, style, true);
bindStyle(textSvgEl, style, true, el);

@@ -404,2 +404,3 @@ if (el instanceof Text || el.style.transformText) {

rect.y = pos[1];
el.transform = matrix.identity(matrix.create());
} // Text rotation, but no element transform

@@ -421,3 +422,5 @@

matrix.rotate(transform, el.transform, rotate);
matrix.rotate(transform, transform, rotate);
var pos = [el.transform[4], el.transform[5]];
matrix.translate(transform, transform, pos);
setTransform(textSvgEl, transform);

@@ -443,3 +446,3 @@ }

if (verticalAlign === 'baseline') {
if (verticalAlign === 'after-edge') {
dy = -textRect.height + lineHeight;

@@ -504,3 +507,3 @@ textPadding && (dy -= textPadding[2]);

} else if (verticalAlign === 'bottom') {
return 'baseline';
return 'after-edge';
} else {

@@ -507,0 +510,0 @@ return 'hanging';

@@ -8,3 +8,6 @@ var Path = require("../graphic/Path");

// command chars
var cc = ['m', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z', 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A'];
// var cc = [
// 'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z',
// 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A'
// ];
var mathSqrt = Math.sqrt;

@@ -67,44 +70,65 @@ var mathSin = Math.sin;

var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig; // Consider case:
// (1) delimiter can be comma or space, where continuous commas
// or spaces should be seen as one comma.
// (2) value can be like:
// '2e-4', 'l.5.9' (ignore 0), 'M-10-10', 'l-2.43e-1,34.9983',
// 'l-.5E1,54', '121-23-44-11' (no delimiter)
var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g; // var valueSplitReg = /[\s,]+/;
function createPathProxyFromString(data) {
if (!data) {
return [];
} // command string
return new PathProxy();
} // var data = data.replace(/-/g, ' -')
// .replace(/ /g, ' ')
// .replace(/ /g, ',')
// .replace(/,,/g, ',');
// var n;
// create pipes so that we can split the data
// for (n = 0; n < cc.length; n++) {
// cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
// }
// data = data.replace(/-/g, ',-');
// create array
// var arr = cs.split('|');
// init context point
var cs = data.replace(/-/g, ' -').replace(/ /g, ' ').replace(/ /g, ',').replace(/,,/g, ',');
var n; // create pipes so that we can split the data
for (n = 0; n < cc.length; n++) {
cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
} // create array
var arr = cs.split('|'); // init context point
var cpx = 0;
var cpy = 0;
var subpathX = cpx;
var subpathY = cpy;
var prevCmd;
var path = new PathProxy();
var CMD = PathProxy.CMD;
var prevCmd;
var CMD = PathProxy.CMD; // commandReg.lastIndex = 0;
// var cmdResult;
// while ((cmdResult = commandReg.exec(data)) != null) {
// var cmdStr = cmdResult[1];
// var cmdContent = cmdResult[2];
for (n = 1; n < arr.length; n++) {
var str = arr[n];
var c = str.charAt(0);
var off = 0;
var p = str.slice(1).replace(/e,-/g, 'e-').split(',');
var cmd;
var cmdList = data.match(commandReg);
if (p.length > 0 && p[0] === '') {
p.shift();
}
for (var l = 0; l < cmdList.length; l++) {
var cmdText = cmdList[l];
var cmdStr = cmdText.charAt(0);
var cmd; // String#split is faster a little bit than String#replace or RegExp#exec.
// var p = cmdContent.split(valueSplitReg);
// var pLen = 0;
// for (var i = 0; i < p.length; i++) {
// // '' and other invalid str => NaN
// var val = parseFloat(p[i]);
// !isNaN(val) && (p[pLen++] = val);
// }
for (var i = 0; i < p.length; i++) {
var p = cmdText.match(numberReg) || [];
var pLen = p.length;
for (var i = 0; i < pLen; i++) {
p[i] = parseFloat(p[i]);
}
while (off < p.length && !isNaN(p[off])) {
if (isNaN(p[0])) {
break;
}
var off = 0;
while (off < pLen) {
var ctlPtx;

@@ -120,3 +144,3 @@ var ctlPty;

switch (c) {
switch (cmdStr) {
case 'l':

@@ -141,3 +165,5 @@ cpx += p[off++];

path.addData(cmd, cpx, cpy);
c = 'l';
subpathX = cpx;
subpathY = cpy;
cmdStr = 'l';
break;

@@ -150,3 +176,5 @@

path.addData(cmd, cpx, cpy);
c = 'L';
subpathX = cpx;
subpathY = cpy;
cmdStr = 'L';
break;

@@ -310,5 +338,8 @@

if (c === 'z' || c === 'Z') {
if (cmdStr === 'z' || cmdStr === 'Z') {
cmd = CMD.Z;
path.addData(cmd);
path.addData(cmd); // z may be in the middle of the path.
cpx = subpathX;
cpy = subpathY;
}

@@ -315,0 +346,0 @@

@@ -36,3 +36,3 @@ var guid = require("./core/guid");

var version = '4.0.4';
var version = '4.0.5';
/**

@@ -283,4 +283,5 @@ * Initializing a zrender instance

if (this.painter.addHover) {
this.painter.addHover(el, style);
var elMirror = this.painter.addHover(el, style);
this.refreshHover();
return elMirror;
}

@@ -287,0 +288,0 @@ },

{
"name": "zrender",
"version": "4.0.4",
"version": "4.0.5",
"description": "A lightweight canvas library.",

@@ -9,8 +9,2 @@ "keywords": [

],
"contributors": [
{
"name": "erik",
"email": "errorrik@gmail.com"
}
],
"repository": {

@@ -17,0 +11,0 @@ "type": "git",

@@ -20,3 +20,4 @@ /**

svgSupported: false,
touchEventsSupported: true
touchEventsSupported: true,
domSupported: false
}

@@ -31,3 +32,4 @@ }

worker: true,
canvasSupported: true
canvasSupported: true,
domSupported: false
};

@@ -44,3 +46,4 @@ }

canvasSupported: true,
svgSupported: true
svgSupported: true,
domSupported: false
};

@@ -154,4 +157,5 @@ }

// standard. So we exclude that. (IE 10 is hardly used on touch device)
&& (browser.edge || (browser.ie && browser.version >= 11))
&& (browser.edge || (browser.ie && browser.version >= 11)),
// passiveSupported: detectPassiveSupport()
domSupported: typeof document !== 'undefined'
};

@@ -158,0 +162,0 @@ }

@@ -236,3 +236,3 @@ /**

this._xi = mathCos(endAngle) * r + cx;
this._yi = mathSin(endAngle) * r + cx;
this._yi = mathSin(endAngle) * r + cy;
return this;

@@ -239,0 +239,0 @@ },

@@ -613,2 +613,5 @@ /**

var isArr = isArray(obj);
// Key should not be set on this, otherwise
// methods get/set/... may be overrided.
this.data = {};
var thisMap = this;

@@ -625,4 +628,2 @@

// Add prefix to avoid conflict with Object.prototype.
HashMap.prototype = {

@@ -634,3 +635,3 @@ constructor: HashMap,

get: function (key) {
return this.hasOwnProperty(key) ? this[key] : null;
return this.data.hasOwnProperty(key) ? this.data[key] : null;
},

@@ -640,3 +641,3 @@ set: function (key, value) {

// used in this case: `var someVal = map.set('a', genVal());`
return (this[key] = value);
return (this.data[key] = value);
},

@@ -647,4 +648,4 @@ // Although util.each can be performed on this hashMap directly, user

context !== void 0 && (cb = bind(cb, context));
for (var key in this) {
this.hasOwnProperty(key) && cb(this[key], key);
for (var key in this.data) {
this.data.hasOwnProperty(key) && cb(this.data[key], key);
}

@@ -654,3 +655,3 @@ },

removeKey: function (key) {
delete this[key];
delete this.data[key];
}

@@ -657,0 +658,0 @@ };

@@ -10,2 +10,3 @@ /**

import * as pathTool from './tool/path';
import {parseSVG} from './tool/parseSVG';

@@ -47,1 +48,3 @@

export {zrUtil as util};
export {parseSVG};

@@ -148,4 +148,7 @@ /**

incremental: false,
// inplace is used with incremental
inplace: false,
/**
* Scale ratio for global scale.
* @type {boolean}
*/
globalScaleRatio: 1,

@@ -207,3 +210,3 @@ beforeBrush: function (ctx) {},

dirty: function () {
this.__dirty = true;
this.__dirty = this.__dirtyText = true;

@@ -210,0 +213,0 @@ this._rect = null;

@@ -54,3 +54,3 @@

!image && (image = new Image());
image.onload = imageOnLoad;
image.onload = image.onerror = imageOnLoad;

@@ -78,3 +78,3 @@ globalImageCache.put(

var cachedImgObj = this.__cachedImgObj;
this.onload = this.__cachedImgObj = null;
this.onload = this.onerror = this.__cachedImgObj = null;

@@ -81,0 +81,0 @@ for (var i = 0; i < cachedImgObj.pending.length; i++) {

@@ -8,3 +8,4 @@

isString,
isObject
isObject,
isFunction
} from '../../core/util';

@@ -19,2 +20,10 @@ import * as textContain from '../../contain/text';

var VALID_TEXT_VERTICAL_ALIGN = {top: 1, bottom: 1, middle: 1};
// Different from `STYLE_COMMON_PROPS` of `graphic/Style`,
// the default value of shadowColor is `'transparent'`.
var SHADOW_STYLE_COMMON_PROPS = [
['textShadowBlur', 'shadowBlur', 0],
['textShadowOffsetX', 'shadowOffsetX', 0],
['textShadowOffsetY', 'shadowOffsetY', 0],
['textShadowColor', 'shadowColor', 'transparent']
];

@@ -62,18 +71,38 @@ /**

* If set false, rect text is not used.
* @param {Element} [prevEl] For ctx prop cache.
*/
export function renderText(hostEl, ctx, text, style, rect) {
export function renderText(hostEl, ctx, text, style, rect, prevEl) {
style.rich
? renderRichText(hostEl, ctx, text, style, rect)
: renderPlainText(hostEl, ctx, text, style, rect);
: renderPlainText(hostEl, ctx, text, style, rect, prevEl);
}
function renderPlainText(hostEl, ctx, text, style, rect) {
var font = setCtx(ctx, 'font', style.font || textContain.DEFAULT_FONT);
// Avoid setting to ctx according to prevEl if possible for
// performance in scenarios of large amount text.
function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
'use strict';
var prevStyle = prevEl && prevEl.style;
// Some cache only available on textEl.
var isPrevTextEl = prevStyle && prevEl.type === 'text';
var styleFont = style.font || textContain.DEFAULT_FONT;
if (!isPrevTextEl || styleFont !== (prevStyle.font || textContain.DEFAULT_FONT)) {
ctx.font = styleFont;
}
// Use the final font from context-2d, because the final
// font might not be the style.font when it is illegal.
// But get `ctx.font` might be time consuming.
var computedFont = hostEl.__computedFont;
if (hostEl.__styleFont !== styleFont) {
hostEl.__styleFont = styleFont;
computedFont = hostEl.__computedFont = ctx.font;
}
var textPadding = style.textPadding;
var contentBlock = hostEl.__textCotentBlock;
if (!contentBlock || hostEl.__dirty) {
if (!contentBlock || hostEl.__dirtyText) {
contentBlock = hostEl.__textCotentBlock = textContain.parsePlainText(
text, font, textPadding, style.truncate
text, computedFont, textPadding, style.truncate
);

@@ -90,3 +119,3 @@ }

var baseY = boxPos.baseY;
var textAlign = boxPos.textAlign;
var textAlign = boxPos.textAlign || 'left';
var textVerticalAlign = boxPos.textVerticalAlign;

@@ -104,3 +133,3 @@

// Consider performance, do not call getTextWidth util necessary.
var textWidth = textContain.getWidth(text, font);
var textWidth = textContain.getWidth(text, computedFont);
var outerWidth = textWidth;

@@ -118,12 +147,20 @@ textPadding && (outerWidth += textPadding[1] + textPadding[3]);

setCtx(ctx, 'textAlign', textAlign || 'left');
// Always set textAlign and textBase line, because it is difficute to calculate
// textAlign from prevEl, and we dont sure whether textAlign will be reset if
// font set happened.
ctx.textAlign = textAlign;
// Force baseline to be "middle". Otherwise, if using "top", the
// text will offset downward a little bit in font "Microsoft YaHei".
setCtx(ctx, 'textBaseline', 'middle');
ctx.textBaseline = 'middle';
// Always set shadowBlur and shadowOffset to avoid leak from displayable.
setCtx(ctx, 'shadowBlur', style.textShadowBlur || 0);
setCtx(ctx, 'shadowColor', style.textShadowColor || 'transparent');
setCtx(ctx, 'shadowOffsetX', style.textShadowOffsetX || 0);
setCtx(ctx, 'shadowOffsetY', style.textShadowOffsetY || 0);
for (var i = 0; i < SHADOW_STYLE_COMMON_PROPS.length; i++) {
var propItem = SHADOW_STYLE_COMMON_PROPS[i];
var styleProp = propItem[0];
var ctxProp = propItem[1];
var val = style[styleProp];
if (!isPrevTextEl || val !== prevStyle[styleProp]) {
ctx[ctxProp] = fixShadow(ctx, ctxProp, val || propItem[2]);
}
}

@@ -134,2 +171,5 @@ // `textBaseline` is set as 'middle'.

var textStrokeWidth = style.textStrokeWidth;
var textStrokeWidthPrev = isPrevTextEl ? prevStyle.textStrokeWidth : null;
var strokeWidthChanged = !isPrevTextEl || textStrokeWidth !== textStrokeWidthPrev;
var strokeChanged = !isPrevTextEl || strokeWidthChanged || style.textStroke !== prevStyle.textStroke;
var textStroke = getStroke(style.textStroke, textStrokeWidth);

@@ -139,15 +179,29 @@ var textFill = getFill(style.textFill);

if (textStroke) {
setCtx(ctx, 'lineWidth', textStrokeWidth);
setCtx(ctx, 'strokeStyle', textStroke);
if (strokeWidthChanged) {
ctx.lineWidth = textStrokeWidth;
}
if (strokeChanged) {
ctx.strokeStyle = textStroke;
}
}
if (textFill) {
setCtx(ctx, 'fillStyle', textFill);
if (!isPrevTextEl || style.textFill !== prevStyle.textFill || prevStyle.textBackgroundColor) {
ctx.fillStyle = textFill;
}
}
for (var i = 0; i < textLines.length; i++) {
// Optimize simply, in most cases only one line exists.
if (textLines.length === 1) {
// Fill after stroke so the outline will not cover the main part.
textStroke && ctx.strokeText(textLines[i], textX, textY);
textFill && ctx.fillText(textLines[i], textX, textY);
textY += lineHeight;
textStroke && ctx.strokeText(textLines[0], textX, textY);
textFill && ctx.fillText(textLines[0], textX, textY);
}
else {
for (var i = 0; i < textLines.length; i++) {
// Fill after stroke so the outline will not cover the main part.
textStroke && ctx.strokeText(textLines[i], textX, textY);
textFill && ctx.fillText(textLines[i], textX, textY);
textY += lineHeight;
}
}
}

@@ -158,3 +212,3 @@

if (!contentBlock || hostEl.__dirty) {
if (!contentBlock || hostEl.__dirtyText) {
contentBlock = hostEl.__textCotentBlock = textContain.parseRichText(text, style);

@@ -264,2 +318,3 @@ }

var tokenStyle = style.rich[token.styleName] || {};
tokenStyle.text = token.text;

@@ -330,3 +385,3 @@ // 'ctx.textBaseline' is always set as 'middle', for sake of

// style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius}
// style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius, text}
// shape: {x, y, width, height}

@@ -360,2 +415,15 @@ function drawBackground(hostEl, ctx, style, x, y, width, height) {

setCtx(ctx, 'fillStyle', textBackgroundColor);
if (style.fillOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.fillOpacity * style.opacity;
ctx.fill();
ctx.globalAlpha = originalGlobalAlpha;
}
else {
ctx.fill();
}
}
else if (isFunction(textBackgroundColor)) {
setCtx(ctx, 'fillStyle', textBackgroundColor(style));
ctx.fill();

@@ -377,3 +445,12 @@ }

setCtx(ctx, 'strokeStyle', textBorderColor);
ctx.stroke();
if (style.strokeOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.strokeOpacity * style.opacity;
ctx.stroke();
ctx.globalAlpha = originalGlobalAlpha;
}
else {
ctx.stroke();
}
}

@@ -380,0 +457,0 @@ }

@@ -40,2 +40,5 @@ /**

// FIXME
// Do not provide prevEl to `textHelper.renderText` for ctx prop cache,
// but use `ctx.save()` and `ctx.restore()`. Because the cache for rect
// text propably break the cache for its host elements.
ctx.save();

@@ -42,0 +45,0 @@

@@ -118,3 +118,13 @@ import Displayable from './Displayable';

hasFill && path.fill(ctx);
if (hasFill) {
if (style.fillOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.fillOpacity * style.opacity;
path.fill(ctx);
ctx.globalAlpha = originalGlobalAlpha;
}
else {
path.fill(ctx);
}
}

@@ -126,3 +136,13 @@ if (lineDash && ctxLineDash) {

hasStroke && path.stroke(ctx);
if (hasStroke) {
if (style.strokeOpacity != null) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.strokeOpacity * style.opacity;
path.stroke(ctx);
ctx.globalAlpha = originalGlobalAlpha;
}
else {
path.stroke(ctx);
}
}

@@ -138,3 +158,3 @@ if (lineDash && ctxLineDash) {

// Only restore transform when needs draw text.
this.restoreTransform(ctx);
this.restoreTransform(ctx);
this.drawRectText(ctx, this.getBoundingRect());

@@ -248,3 +268,3 @@ }

this.__dirty = true;
this.__dirty = this.__dirtyText = true;

@@ -251,0 +271,0 @@ this.__zr && this.__zr.refresh();

@@ -19,3 +19,3 @@ /**

buildPath : function (ctx, shape, inBundle) {
buildPath: function (ctx, shape, inBundle) {
// Better stroking in ShapeBundle

@@ -22,0 +22,0 @@ // Always do it may have performence issue ( fill may be 2x more cost)

@@ -12,5 +12,4 @@

var Style = function (opts, host) {
var Style = function (opts) {
this.extendFrom(opts, false);
this.host = host;
};

@@ -67,7 +66,2 @@

/**
* @type {module:zrender/graphic/Displayable}
*/
host: null,
/**
* @type {string}

@@ -88,2 +82,12 @@ */

/**
* @type {number}
*/
fillOpacity: null,
/**
* @type {number}
*/
strokeOpacity: null,
/**
* @type {Array.<number>}

@@ -90,0 +94,0 @@ */

@@ -36,4 +36,6 @@ import Displayable from './Displayable';

// Always bind style
style.bind(ctx, this, prevEl);
// Do not apply style.bind in Text node. Because the real bind job
// is in textHelper.renderText, and performance of text render should
// be considered.
// style.bind(ctx, this, prevEl);

@@ -46,3 +48,3 @@ if (!textHelper.needDrawText(text, style)) {

textHelper.renderText(this, ctx, text, style);
textHelper.renderText(this, ctx, text, style, null, prevEl);

@@ -49,0 +51,0 @@ this.restoreTransform(ctx);

@@ -5,2 +5,3 @@ import * as util from './core/util';

import Eventful from './mixin/Eventful';
import * as eventTool from './core/event';

@@ -26,6 +27,11 @@ var SILENT = 'silent';

zrByTouch: event.zrByTouch,
which: event.which
which: event.which,
stop: stopEvent
};
}
function stopEvent(event) {
eventTool.stop(this.event);
}
function EmptyProxy () {}

@@ -32,0 +38,0 @@ EmptyProxy.prototype.dispose = function () {};

@@ -140,132 +140,156 @@ import Animator from '../animation/Animator';

*/
// TODO Return animation key
// TODO Return animation key
animateTo: function (target, time, delay, easing, callback, forceAnimate) {
// animateTo(target, time, easing, callback);
if (isString(delay)) {
callback = easing;
easing = delay;
delay = 0;
}
// animateTo(target, time, delay, callback);
else if (isFunction(easing)) {
callback = easing;
easing = 'linear';
delay = 0;
}
// animateTo(target, time, callback);
else if (isFunction(delay)) {
callback = delay;
delay = 0;
}
// animateTo(target, callback)
else if (isFunction(time)) {
callback = time;
time = 500;
}
// animateTo(target)
else if (!time) {
time = 500;
}
// Stop all previous animations
this.stopAnimation();
this._animateToShallow('', this, target, time, delay);
animateTo(this, target, time, delay, easing, callback, forceAnimate);
},
// Animators may be removed immediately after start
// if there is nothing to animate
var animators = this.animators.slice();
var count = animators.length;
function done() {
count--;
if (!count) {
callback && callback();
}
}
/**
* Animate from the target state to current state.
* The params and the return value are the same as `this.animateTo`.
*/
animateFrom: function (target, time, delay, easing, callback, forceAnimate) {
animateTo(this, target, time, delay, easing, callback, forceAnimate, true);
}
};
// No animators. This should be checked before animators[i].start(),
// because 'done' may be executed immediately if no need to animate.
function animateTo(animatable, target, time, delay, easing, callback, forceAnimate, reverse) {
// animateTo(target, time, easing, callback);
if (isString(delay)) {
callback = easing;
easing = delay;
delay = 0;
}
// animateTo(target, time, delay, callback);
else if (isFunction(easing)) {
callback = easing;
easing = 'linear';
delay = 0;
}
// animateTo(target, time, callback);
else if (isFunction(delay)) {
callback = delay;
delay = 0;
}
// animateTo(target, callback)
else if (isFunction(time)) {
callback = time;
time = 500;
}
// animateTo(target)
else if (!time) {
time = 500;
}
// Stop all previous animations
animatable.stopAnimation();
animateToShallow(animatable, '', animatable, target, time, delay, reverse);
// Animators may be removed immediately after start
// if there is nothing to animate
var animators = animatable.animators.slice();
var count = animators.length;
function done() {
count--;
if (!count) {
callback && callback();
}
// Start after all animators created
// Incase any animator is done immediately when all animation properties are not changed
for (var i = 0; i < animators.length; i++) {
animators[i]
.done(done)
.start(easing, forceAnimate);
}
// No animators. This should be checked before animators[i].start(),
// because 'done' may be executed immediately if no need to animate.
if (!count) {
callback && callback();
}
// Start after all animators created
// Incase any animator is done immediately when all animation properties are not changed
for (var i = 0; i < animators.length; i++) {
animators[i]
.done(done)
.start(easing, forceAnimate);
}
}
/**
* @param {string} path=''
* @param {Object} source=animatable
* @param {Object} target
* @param {number} [time=500]
* @param {number} [delay=0]
* @param {boolean} [reverse] If `true`, animate
* from the `target` to current state.
*
* @example
* // Animate position
* el._animateToShallow({
* position: [10, 10]
* })
*
* // Animate shape, style and position in 100ms, delayed 100ms
* el._animateToShallow({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100)
*/
function animateToShallow(animatable, path, source, target, time, delay, reverse) {
var objShallow = {};
var propertyCount = 0;
for (var name in target) {
if (!target.hasOwnProperty(name)) {
continue;
}
},
/**
* @private
* @param {string} path=''
* @param {Object} source=this
* @param {Object} target
* @param {number} [time=500]
* @param {number} [delay=0]
*
* @example
* // Animate position
* el._animateToShallow({
* position: [10, 10]
* })
*
* // Animate shape, style and position in 100ms, delayed 100ms
* el._animateToShallow({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100)
*/
_animateToShallow: function (path, source, target, time, delay) {
var objShallow = {};
var propertyCount = 0;
for (var name in target) {
if (!target.hasOwnProperty(name)) {
continue;
if (source[name] != null) {
if (isObject(target[name]) && !isArrayLike(target[name])) {
animateToShallow(
animatable,
path ? path + '.' + name : name,
source[name],
target[name],
time,
delay,
reverse
);
}
if (source[name] != null) {
if (isObject(target[name]) && !isArrayLike(target[name])) {
this._animateToShallow(
path ? path + '.' + name : name,
source[name],
target[name],
time,
delay
);
else {
if (reverse) {
objShallow[name] = source[name];
setAttrByPath(animatable, path, name, target[name]);
}
else {
objShallow[name] = target[name];
propertyCount++;
}
propertyCount++;
}
else if (target[name] != null) {
// Attr directly if not has property
// FIXME, if some property not needed for element ?
if (!path) {
this.attr(name, target[name]);
}
else { // Shape or style
var props = {};
props[path] = {};
props[path][name] = target[name];
this.attr(props);
}
}
}
if (propertyCount > 0) {
this.animate(path, false)
.when(time == null ? 500 : time, objShallow)
.delay(delay || 0);
else if (target[name] != null && !reverse) {
setAttrByPath(animatable, path, name, target[name]);
}
}
return this;
if (propertyCount > 0) {
animatable.animate(path, false)
.when(time == null ? 500 : time, objShallow)
.delay(delay || 0);
}
};
}
function setAttrByPath(el, path, name, value) {
// Attr directly if not has property
// FIXME, if some property not needed for element ?
if (!path) {
el.attr(name, value);
}
else {
// Only support set shape or style
var props = {};
props[path] = {};
props[path][name] = value;
el.attr(props);
}
}
export default Animatable;
/**
* 事件扩展
* Event Mixin
* @module zrender/mixin/Eventful

@@ -11,8 +11,22 @@ * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)

/**
* 事件分发器
* Event dispatcher.
*
* @alias module:zrender/mixin/Eventful
* @constructor
* @param {Object} [eventProcessor] The object eventProcessor is the scope when
* `eventProcessor.xxx` called.
* @param {Function} [eventProcessor.normalizeQuery]
* param: {string|Object} Raw query.
* return: {string|Object} Normalized query.
* @param {Function} [eventProcessor.filter] Event will be dispatched only
* if it returns `true`.
* param: {string} eventType
* param: {string|Object} query
* return: {boolean}
* @param {Function} [eventProcessor.afterTrigger] Call after all handlers called.
* param: {string} eventType
*/
var Eventful = function () {
var Eventful = function (eventProcessor) {
this._$handlers = {};
this._$eventProcessor = eventProcessor;
};

@@ -25,11 +39,18 @@

/**
* 单次触发绑定,trigger后销毁
* The handler can only be triggered once, then removed.
*
* @param {string} event 事件名
* @param {Function} handler 响应函数
* @param {string} event The event name.
* @param {string|Object} [query] Condition used on event filter.
* @param {Function} handler The event handler.
* @param {Object} context
*/
one: function (event, handler, context) {
one: function (event, query, handler, context) {
var _h = this._$handlers;
if (typeof query === 'function') {
context = handler;
handler = query;
query = null;
}
if (!handler || !event) {

@@ -39,2 +60,4 @@ return this;

query = normalizeQuery(this, query);
if (!_h[event]) {

@@ -53,2 +76,3 @@ _h[event] = [];

one: true,
query: query,
ctx: context || this

@@ -61,10 +85,18 @@ });

/**
* 绑定事件
* @param {string} event 事件名
* @param {Function} handler 事件处理函数
* Bind a handler.
*
* @param {string} event The event name.
* @param {string|Object} [query] Condition used on event filter.
* @param {Function} handler The event handler.
* @param {Object} [context]
*/
on: function (event, handler, context) {
on: function (event, query, handler, context) {
var _h = this._$handlers;
if (typeof query === 'function') {
context = handler;
handler = query;
query = null;
}
if (!handler || !event) {

@@ -74,2 +106,4 @@ return this;

query = normalizeQuery(this, query);
if (!_h[event]) {

@@ -88,2 +122,3 @@ _h[event] = [];

one: false,
query: query,
ctx: context || this

@@ -96,3 +131,4 @@ });

/**
* 是否绑定了事件
* Whether any handler has bound.
*
* @param {string} event

@@ -107,5 +143,6 @@ * @return {boolean}

/**
* 解绑事件
* @param {string} event 事件名
* @param {Function} [handler] 事件处理函数
* Unbind a event.
*
* @param {string} event The event name.
* @param {Function} [handler] The event handler.
*/

@@ -124,3 +161,3 @@ off: function (event, handler) {

for (var i = 0, l = _h[event].length; i < l; i++) {
if (_h[event][i]['h'] != handler) {
if (_h[event][i].h !== handler) {
newList.push(_h[event][i]);

@@ -144,8 +181,11 @@ }

/**
* 事件分发
* Dispatch a event.
*
* @param {string} type 事件类型
* @param {string} type The event name.
*/
trigger: function (type) {
if (this._$handlers[type]) {
var _h = this._$handlers[type];
var eventProcessor = this._$eventProcessor;
if (_h) {
var args = arguments;

@@ -158,23 +198,32 @@ var argLen = args.length;

var _h = this._$handlers[type];
var len = _h.length;
for (var i = 0; i < len;) {
var hItem = _h[i];
if (eventProcessor
&& eventProcessor.filter
&& hItem.query != null
&& !eventProcessor.filter(type, hItem.query)
) {
i++;
continue;
}
// Optimize advise from backbone
switch (argLen) {
case 1:
_h[i]['h'].call(_h[i]['ctx']);
hItem.h.call(hItem.ctx);
break;
case 2:
_h[i]['h'].call(_h[i]['ctx'], args[1]);
hItem.h.call(hItem.ctx, args[1]);
break;
case 3:
_h[i]['h'].call(_h[i]['ctx'], args[1], args[2]);
hItem.h.call(hItem.ctx, args[1], args[2]);
break;
default:
// have more than 2 given arguments
_h[i]['h'].apply(_h[i]['ctx'], args);
hItem.h.apply(hItem.ctx, args);
break;
}
if (_h[i]['one']) {
if (hItem.one) {
_h.splice(i, 1);

@@ -189,2 +238,5 @@ len--;

eventProcessor && eventProcessor.afterTrigger
&& eventProcessor.afterTrigger(type);
return this;

@@ -194,7 +246,11 @@ },

/**
* 带有context的事件分发, 最后一个参数是事件回调的context
* @param {string} type 事件类型
* Dispatch a event with context, which is specified at the last parameter.
*
* @param {string} type The event name.
*/
triggerWithContext: function (type) {
if (this._$handlers[type]) {
var _h = this._$handlers[type];
var eventProcessor = this._$eventProcessor;
if (_h) {
var args = arguments;

@@ -208,23 +264,32 @@ var argLen = args.length;

var _h = this._$handlers[type];
var len = _h.length;
for (var i = 0; i < len;) {
var hItem = _h[i];
if (eventProcessor
&& eventProcessor.filter
&& hItem.query != null
&& !eventProcessor.filter(type, hItem.query)
) {
i++;
continue;
}
// Optimize advise from backbone
switch (argLen) {
case 1:
_h[i]['h'].call(ctx);
hItem.h.call(ctx);
break;
case 2:
_h[i]['h'].call(ctx, args[1]);
hItem.h.call(ctx, args[1]);
break;
case 3:
_h[i]['h'].call(ctx, args[1], args[2]);
hItem.h.call(ctx, args[1], args[2]);
break;
default:
// have more than 2 given arguments
_h[i]['h'].apply(ctx, args);
hItem.h.apply(ctx, args);
break;
}
if (_h[i]['one']) {
if (hItem.one) {
_h.splice(i, 1);

@@ -239,2 +304,5 @@ len--;

eventProcessor && eventProcessor.afterTrigger
&& eventProcessor.afterTrigger(type);
return this;

@@ -244,3 +312,14 @@ }

// 对象可以通过 onxxxx 绑定事件
function normalizeQuery(host, query) {
var eventProcessor = host._$eventProcessor;
if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
query = eventProcessor.normalizeQuery(query);
}
return query;
}
// ----------------------
// The events in zrender
// ----------------------
/**

@@ -247,0 +326,0 @@ * @event module:zrender/mixin/Eventful#onclick

@@ -72,2 +72,3 @@ /**

var scaleTmp = [];
transformableProto.updateTransform = function () {

@@ -105,2 +106,16 @@ var parent = this.parent;

var globalScaleRatio = this.globalScaleRatio;
if (globalScaleRatio != null && globalScaleRatio !== 1) {
this.getGlobalScale(scaleTmp);
var relX = scaleTmp[0] < 0 ? -1 : 1;
var relY = scaleTmp[1] < 0 ? -1 : 1;
var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;
m[0] *= sx;
m[1] *= sx;
m[2] *= sy;
m[3] *= sy;
}
this.invTransform = this.invTransform || matrix.create();

@@ -135,17 +150,9 @@ matrix.invert(this.invTransform, m);

var tmpTransform = [];
var originTransform = matrix.create();
/**
* 分解`transform`矩阵到`position`, `rotation`, `scale`
*/
transformableProto.decomposeTransform = function () {
if (!this.transform) {
transformableProto.setLocalTransform = function (m) {
if (!m) {
// TODO return or set identity?
return;
}
var parent = this.parent;
var m = this.transform;
if (parent && parent.transform) {
// Get local transform and decompose them to position, scale, rotation
matrix.mul(tmpTransform, parent.invTransform, m);
m = tmpTransform;
}
var sx = m[0] * m[0] + m[1] * m[1];

@@ -167,2 +174,3 @@ var sy = m[2] * m[2] + m[3] * m[3];

}
position[0] = m[4];

@@ -174,3 +182,29 @@ position[1] = m[5];

};
/**
* 分解`transform`矩阵到`position`, `rotation`, `scale`
*/
transformableProto.decomposeTransform = function () {
if (!this.transform) {
return;
}
var parent = this.parent;
var m = this.transform;
if (parent && parent.transform) {
// Get local transform and decompose them to position, scale, rotation
matrix.mul(tmpTransform, parent.invTransform, m);
m = tmpTransform;
}
var origin = this.origin;
if (origin && (origin[0] || origin[1])) {
originTransform[4] = origin[0];
originTransform[5] = origin[1];
matrix.mul(tmpTransform, m, originTransform);
tmpTransform[4] -= origin[0];
tmpTransform[5] -= origin[1];
m = tmpTransform;
}
this.setLocalTransform(m);
};
/**

@@ -180,16 +214,19 @@ * Get global scale

*/
transformableProto.getGlobalScale = function () {
transformableProto.getGlobalScale = function (out) {
var m = this.transform;
out = out || [];
if (!m) {
return [1, 1];
out[0] = 1;
out[1] = 1;
return out;
}
var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
if (m[0] < 0) {
sx = -sx;
out[0] = -out[0];
}
if (m[3] < 0) {
sy = -sy;
out[1] = -out[1];
}
return [sx, sy];
return out;
};

@@ -196,0 +233,0 @@ /**

@@ -287,8 +287,13 @@ import {devicePixelRatio} from './config';

style: el.style,
shape: el.shape
shape: el.shape,
z: el.z,
z2: el.z2,
silent: el.silent
});
elMirror.__from = el;
el.__hoverMir = elMirror;
elMirror.setStyle(hoverStyle);
hoverStyle && elMirror.setStyle(hoverStyle);
this._hoverElements.push(elMirror);
return elMirror;
},

@@ -359,2 +364,3 @@

}
hoverLayer.ctx.restore();

@@ -448,3 +454,3 @@ },

this._doPaintEl(el, layer, paintAll, scope);
el.__dirty = false;
el.__dirty = el.__dirtyText = false;

@@ -451,0 +457,0 @@ if (useTimer) {

@@ -64,3 +64,3 @@ // TODO

function bindStyle(svgEl, style, isText) {
function bindStyle(svgEl, style, isText, el) {
if (pathHasFill(style, isText)) {

@@ -90,3 +90,3 @@ var fill = isText ? style.textFill : style.fill;

attr(svgEl, 'fill', fill);
attr(svgEl, 'fill-opacity', style.opacity);
attr(svgEl, 'fill-opacity', style.fillOpacity != null ? style.fillOpacity * style.opacity : style.opacity);
}

@@ -105,3 +105,3 @@ else {

var strokeScale = !isText && style.strokeNoScale
? style.host.getLineScale()
? el.getLineScale()
: 1;

@@ -111,3 +111,3 @@ attr(svgEl, 'stroke-width', strokeWidth / strokeScale);

attr(svgEl, 'paint-order', isText ? 'stroke' : 'fill');
attr(svgEl, 'stroke-opacity', style.opacity);
attr(svgEl, 'stroke-opacity', style.strokeOpacity != null ? style.strokeOpacity : style.opacity);
var lineDash = style.lineDash;

@@ -275,3 +275,3 @@ if (lineDash) {

bindStyle(svgEl, style);
bindStyle(svgEl, style, false, el);
setTransform(svgEl, el.transform);

@@ -412,3 +412,3 @@

bindStyle(textSvgEl, style, true);
bindStyle(textSvgEl, style, true, el);
if (el instanceof Text || el.style.transformText) {

@@ -428,2 +428,3 @@ // Transform text with element

rect.y = pos[1];
el.transform = matrix.identity(matrix.create());
}

@@ -444,3 +445,6 @@

// Apply textRotate to element matrix
matrix.rotate(transform, el.transform, rotate);
matrix.rotate(transform, transform, rotate);
var pos = [el.transform[4], el.transform[5]];
matrix.translate(transform, transform, pos);
setTransform(textSvgEl, transform);

@@ -467,3 +471,3 @@ }

var dy = 0;
if (verticalAlign === 'baseline') {
if (verticalAlign === 'after-edge') {
dy = -textRect.height + lineHeight;

@@ -527,3 +531,3 @@ textPadding && (dy -= textPadding[2]);

else if (verticalAlign === 'bottom') {
return 'baseline';
return 'after-edge';
}

@@ -530,0 +534,0 @@ else {

@@ -6,6 +6,6 @@ import Path from '../graphic/Path';

// command chars
var cc = [
'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z',
'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A'
];
// var cc = [
// 'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z',
// 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A'
// ];

@@ -80,24 +80,39 @@ var mathSqrt = Math.sqrt;

var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig;
// Consider case:
// (1) delimiter can be comma or space, where continuous commas
// or spaces should be seen as one comma.
// (2) value can be like:
// '2e-4', 'l.5.9' (ignore 0), 'M-10-10', 'l-2.43e-1,34.9983',
// 'l-.5E1,54', '121-23-44-11' (no delimiter)
var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
// var valueSplitReg = /[\s,]+/;
function createPathProxyFromString(data) {
if (!data) {
return [];
return new PathProxy();
}
// command string
var cs = data.replace(/-/g, ' -')
.replace(/ /g, ' ')
.replace(/ /g, ',')
.replace(/,,/g, ',');
// var data = data.replace(/-/g, ' -')
// .replace(/ /g, ' ')
// .replace(/ /g, ',')
// .replace(/,,/g, ',');
var n;
// var n;
// create pipes so that we can split the data
for (n = 0; n < cc.length; n++) {
cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
}
// for (n = 0; n < cc.length; n++) {
// cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
// }
// data = data.replace(/-/g, ',-');
// create array
var arr = cs.split('|');
// var arr = cs.split('|');
// init context point
var cpx = 0;
var cpy = 0;
var subpathX = cpx;
var subpathY = cpy;
var prevCmd;

@@ -107,21 +122,32 @@ var path = new PathProxy();

var prevCmd;
for (n = 1; n < arr.length; n++) {
var str = arr[n];
var c = str.charAt(0);
var off = 0;
var p = str.slice(1).replace(/e,-/g, 'e-').split(',');
// commandReg.lastIndex = 0;
// var cmdResult;
// while ((cmdResult = commandReg.exec(data)) != null) {
// var cmdStr = cmdResult[1];
// var cmdContent = cmdResult[2];
var cmdList = data.match(commandReg);
for (var l = 0; l < cmdList.length; l++) {
var cmdText = cmdList[l];
var cmdStr = cmdText.charAt(0);
var cmd;
if (p.length > 0 && p[0] === '') {
p.shift();
}
// String#split is faster a little bit than String#replace or RegExp#exec.
// var p = cmdContent.split(valueSplitReg);
// var pLen = 0;
// for (var i = 0; i < p.length; i++) {
// // '' and other invalid str => NaN
// var val = parseFloat(p[i]);
// !isNaN(val) && (p[pLen++] = val);
// }
for (var i = 0; i < p.length; i++) {
var p = cmdText.match(numberReg) || [];
var pLen = p.length;
for (var i = 0; i < pLen; i++) {
p[i] = parseFloat(p[i]);
}
while (off < p.length && !isNaN(p[off])) {
if (isNaN(p[0])) {
break;
}
var off = 0;
while (off < pLen) {
var ctlPtx;

@@ -140,3 +166,3 @@ var ctlPty;

// convert l, H, h, V, and v to L
switch (c) {
switch (cmdStr) {
case 'l':

@@ -159,3 +185,5 @@ cpx += p[off++];

path.addData(cmd, cpx, cpy);
c = 'l';
subpathX = cpx;
subpathY = cpy;
cmdStr = 'l';
break;

@@ -167,3 +195,5 @@ case 'M':

path.addData(cmd, cpx, cpy);
c = 'L';
subpathX = cpx;
subpathY = cpy;
cmdStr = 'L';
break;

@@ -318,5 +348,8 @@ case 'h':

if (c === 'z' || c === 'Z') {
if (cmdStr === 'z' || cmdStr === 'Z') {
cmd = CMD.Z;
path.addData(cmd);
// z may be in the middle of the path.
cpx = subpathX;
cpy = subpathY;
}

@@ -323,0 +356,0 @@

@@ -31,3 +31,3 @@ /*!

*/
export var version = '4.0.4';
export var version = '4.0.5';

@@ -278,4 +278,5 @@ /**

if (this.painter.addHover) {
this.painter.addHover(el, style);
var elMirror = this.painter.addHover(el, style);
this.refreshHover();
return elMirror;
}

@@ -282,0 +283,0 @@ },

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc