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 3.1.0 to 3.1.1

lib/animation/requestAnimationFrame.js

9

lib/animation/Animation.js

@@ -16,10 +16,3 @@ 'use strict';

var requestAnimationFrame = (typeof window !== 'undefined' &&
(window.requestAnimationFrame
|| window.msRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame))
|| function (func) {
setTimeout(func, 16);
};
var requestAnimationFrame = require('./requestAnimationFrame');

@@ -26,0 +19,0 @@ var Animator = require('./Animator');

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

// Start from next key
// PENDING start from lastFrame ?
start = Math.min(lastFrame + 1, trackLen - 1);

@@ -326,2 +327,3 @@ for (frame = start; frame >= 0; frame--) {

}
// PENDING really need to do this ?
frame = Math.min(frame, trackLen - 2);

@@ -328,0 +330,0 @@ }

@@ -52,2 +52,6 @@ 'use strict';

var t = roots[i];
// Avoid winding error when intersection point is the connect point of two line of polygon
var unit = (t === 0 || t === 1) ? 0.5 : 1;
var x_ = curve.cubicAt(x0, x1, x2, x3, t);

@@ -70,9 +74,9 @@ if (x_ < x) { // Quick reject

if (t < extrema[0]) {
w += y0_ < y0 ? 1 : -1;
w += y0_ < y0 ? unit : -unit;
}
else if (t < extrema[1]) {
w += y1_ < y0_ ? 1 : -1;
w += y1_ < y0_ ? unit : -unit;
}
else {
w += y3 < y1_ ? 1 : -1;
w += y3 < y1_ ? unit : -unit;
}

@@ -83,6 +87,6 @@ }

if (t < extrema[0]) {
w += y0_ < y0 ? 1 : -1;
w += y0_ < y0 ? unit : -unit;
}
else {
w += y3 < y0_ ? 1 : -1;
w += y3 < y0_ ? unit : -unit;
}

@@ -113,2 +117,5 @@ }

for (var i = 0; i < nRoots; i++) {
// Remove one endpoint.
var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;
var x_ = curve.quadraticAt(x0, x1, x2, roots[i]);

@@ -119,6 +126,6 @@ if (x_ < x) { // Quick reject

if (roots[i] < t) {
w += y_ < y0 ? 1 : -1;
w += y_ < y0 ? unit : -unit;
}
else {
w += y2 < y_ ? 1 : -1;
w += y2 < y_ ? unit : -unit;
}

@@ -129,2 +136,5 @@ }

else {
// Remove one endpoint.
var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;
var x_ = curve.quadraticAt(x0, x1, x2, roots[0]);

@@ -134,3 +144,3 @@ if (x_ < x) { // Quick reject

}
return y2 < y0 ? 1 : -1;
return y2 < y0 ? unit : -unit;
}

@@ -221,5 +231,5 @@ }

// 如果被任何一个 subpath 包含
if (w !== 0) {
return true;
}
// if (w !== 0) {
// return true;
// }
}

@@ -351,3 +361,3 @@

|| containStroke(x1, y1, x0, y1, lineWidth, x, y)
|| containStroke(x0, y1, x1, y1, lineWidth, x, y)
|| containStroke(x0, y1, x0, y0, lineWidth, x, y)
) {

@@ -375,5 +385,6 @@ return true;

// 如果被任何一个 subpath 包含
if (w !== 0) {
return true;
}
// FIXME subpaths may overlap
// if (w !== 0) {
// return true;
// }
}

@@ -380,0 +391,0 @@ xi = x0;

@@ -6,2 +6,3 @@

}
// Ignore horizontal line
if (y1 === y0) {

@@ -12,2 +13,8 @@ return 0;

var t = (y - y0) / (y1 - y0);
// Avoid winding error when intersection point is the connect point of two line of polygon
if (t === 1 || t === 0) {
dir = y1 < y0 ? 0.5 : -0.5;
}
var x_ = t * (x1 - x0) + x0;

@@ -14,0 +21,0 @@

@@ -52,2 +52,4 @@ /**

isGroup: true,
/**

@@ -54,0 +56,0 @@ * @type {string}

@@ -33,19 +33,19 @@ /**

var browser = {};
var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
var touchpad = webos && ua.match(/TouchPad/);
var kindle = ua.match(/Kindle\/([\d.]+)/);
var silk = ua.match(/Silk\/([\d._]+)/);
var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
var playbook = ua.match(/PlayBook/);
var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
var firefox = ua.match(/Firefox\/([\d.]+)/);
var safari = webkit && ua.match(/Mobile\//) && !chrome;
var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
// var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
// var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
// var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
// var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
// var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
// var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
// var touchpad = webos && ua.match(/TouchPad/);
// var kindle = ua.match(/Kindle\/([\d.]+)/);
// var silk = ua.match(/Silk\/([\d._]+)/);
// var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
// var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
// var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
// var playbook = ua.match(/PlayBook/);
// var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
// var firefox = ua.match(/Firefox\/([\d.]+)/);
// var safari = webkit && ua.match(/Mobile\//) && !chrome;
// var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
var ie = ua.match(/MSIE\s([\d.]+)/)

@@ -62,30 +62,38 @@ // IE 11 Trident/7.0; rv:11.0

if (browser.webkit = !!webkit) browser.version = webkit[1];
// if (browser.webkit = !!webkit) browser.version = webkit[1];
if (android) os.android = true, os.version = android[2];
if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
if (webos) os.webos = true, os.version = webos[2];
if (touchpad) os.touchpad = true;
if (blackberry) os.blackberry = true, os.version = blackberry[2];
if (bb10) os.bb10 = true, os.version = bb10[2];
if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
if (playbook) browser.playbook = true;
if (kindle) os.kindle = true, os.version = kindle[1];
if (silk) browser.silk = true, browser.version = silk[1];
if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
if (chrome) browser.chrome = true, browser.version = chrome[1];
if (firefox) browser.firefox = true, browser.version = firefox[1];
if (ie) browser.ie = true, browser.version = ie[1];
if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
if (webview) browser.webview = true;
if (ie) browser.ie = true, browser.version = ie[1];
if (edge) browser.edge = true, browser.version = edge[1];
// if (android) os.android = true, os.version = android[2];
// if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
// if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
// if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
// if (webos) os.webos = true, os.version = webos[2];
// if (touchpad) os.touchpad = true;
// if (blackberry) os.blackberry = true, os.version = blackberry[2];
// if (bb10) os.bb10 = true, os.version = bb10[2];
// if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
// if (playbook) browser.playbook = true;
// if (kindle) os.kindle = true, os.version = kindle[1];
// if (silk) browser.silk = true, browser.version = silk[1];
// if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
// if (chrome) browser.chrome = true, browser.version = chrome[1];
// if (firefox) browser.firefox = true, browser.version = firefox[1];
// if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
// if (webview) browser.webview = true;
if (ie) {
browser.ie = true; browser.version = ie[1];
}
if (ie) {
browser.ie = true;
browser.version = ie[1];
}
if (edge) {
browser.edge = true;
browser.version = edge[1];
}
os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
(firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||
(chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
(firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));
// os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
// (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
// os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos ||
// (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
// (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));

@@ -92,0 +100,0 @@ return {

@@ -15,4 +15,14 @@ 'use strict';

// BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect
return el.getBoundingClientRect ? el.getBoundingClientRect() : { left: 0, top: 0};
return el.getBoundingClientRect ? el.getBoundingClientRect() : {left: 0, top: 0};
}
function clientToLocal(el, e, out) {
// clientX/clientY is according to view port.
var box = getBoundingClientRect(el);
out = out || {};
out.zrX = e.clientX - box.left;
out.zrY = e.clientY - box.top;
return out;
}
/**

@@ -33,5 +43,3 @@ * 如果存在第三方嵌入的一些dom触发的事件,或touch事件,需要转换一下事件坐标

if (!isTouch) {
var box = getBoundingClientRect(el);
e.zrX = e.clientX - box.left;
e.zrY = e.clientY - box.top;
clientToLocal(el, e, e);
e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;

@@ -41,10 +49,5 @@ }

var touch = eventType != 'touchend'
? e.targetTouches[0]
: e.changedTouches[0];
if (touch) {
var rBounding = getBoundingClientRect(el);
// touch事件坐标是全屏的~
e.zrX = touch.clientX - rBounding.left;
e.zrY = touch.clientY - rBounding.top;
}
? e.targetTouches[0]
: e.changedTouches[0];
touch && clientToLocal(el, touch, e);
}

@@ -91,2 +94,3 @@

module.exports = {
clientToLocal: clientToLocal,
normalizeEvent: normalizeEvent,

@@ -93,0 +97,0 @@ addEventListener: addEventListener,

@@ -7,2 +7,4 @@ 'use strict';

var eventUtil = require('./event');
var GestureMgr = function () {

@@ -21,4 +23,4 @@

recognize: function (event, target) {
this._doTrack(event, target);
recognize: function (event, target, root) {
this._doTrack(event, target, root);
return this._recognize(event);

@@ -32,3 +34,3 @@ },

_doTrack: function (event, target) {
_doTrack: function (event, target, root) {
var touches = event.touches;

@@ -49,3 +51,4 @@

var touch = touches[i];
trackItem.points.push([touch.clientX, touch.clientY]);
var pos = eventUtil.clientToLocal(root, touch);
trackItem.points.push([pos.zrX, pos.zrY]);
trackItem.touches.push(touch);

@@ -52,0 +55,0 @@ }

@@ -8,7 +8,7 @@ /**

var idStart = 0x0907;
var idStart = 0x0907;
module.exports = function () {
return 'zr_' + (idStart++);
};
module.exports = function () {
return idStart++;
};

@@ -150,3 +150,3 @@ 'use strict';

// Force draw the first segment
|| this._len === 0;
|| this._len < 5;

@@ -427,3 +427,4 @@ this.addData(CMD.L, x, y);

while ((dx >= 0 && x <= x1) || (dx < 0 && x > x1)) {
while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1)
|| (dx == 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
idx = this._dashIdx;

@@ -435,3 +436,3 @@ dash = lineDash[idx];

// Skip positive offset
if ((dx > 0 && x < x0) || (dx < 0 && x > x0)) {
if ((dx > 0 && x < x0) || (dx < 0 && x > x0) || (dy > 0 && y < y0) || (dy < 0 && y > y0)) {
continue;

@@ -438,0 +439,0 @@ }

@@ -5,3 +5,3 @@ /**

var Gradient = require('../graphic/Gradient');
// 用于处理merge时无法遍历Date等对象的问题

@@ -13,3 +13,6 @@ var BUILTIN_OBJECT = {

'[object Error]': 1,
'[object CanvasGradient]': 1
'[object CanvasGradient]': 1,
'[object CanvasPattern]': 1,
// In node-canvas Image can be Canvas.Image
'[object Image]': 1
};

@@ -411,4 +414,3 @@

function isBuildInObject(value) {
return !!BUILTIN_OBJECT[objToString.call(value)]
|| (value instanceof Gradient);
return !!BUILTIN_OBJECT[objToString.call(value)];
}

@@ -415,0 +417,0 @@

@@ -22,4 +22,10 @@

var out = new ArrayCtor(2);
out[0] = x || 0;
out[1] = y || 0;
if (x == null) {
x = 0;
}
if (y == null) {
y = 0;
}
out[0] = x;
out[1] = y;
return out;

@@ -26,0 +32,0 @@ },

@@ -98,3 +98,3 @@ 'use strict';

this.decomposeTransform();
this.dirty();
this.dirty(false);
},

@@ -174,4 +174,5 @@

}
this.dirty();
this.dirty(false);
return this;

@@ -198,3 +199,3 @@ },

this.dirty();
this.dirty(false);
},

@@ -215,3 +216,3 @@

this.dirty();
this.dirty(false);
}

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

@@ -38,3 +38,3 @@ // CompoundPath to improve performance

for (var i = 0; i < paths.length; i++) {
paths[i].buildPath(ctx, paths[i].shape);
paths[i].buildPath(ctx, paths[i].shape, true);
}

@@ -41,0 +41,0 @@ },

@@ -141,2 +141,9 @@ /**

/**
* Render the element progressively when the value >= 0,
* usefull for large data.
* @type {number}
*/
progressive: -1,
beforeBrush: function (ctx) {},

@@ -151,3 +158,3 @@

// Interface
brush: function (ctx) {},
brush: function (ctx, prevEl) {},

@@ -154,0 +161,0 @@ /**

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

brush: function (ctx) {
brush: function (ctx, prevEl) {
var style = this.style;

@@ -37,2 +37,5 @@ var src = style.image;

// Must bind each time
style.bind(ctx, this, prevEl);
// style.image is a url string

@@ -97,6 +100,2 @@ if (typeof src === 'string') {

ctx.save();
style.bind(ctx);
// 设置transform

@@ -145,2 +144,4 @@ this.setTransform(ctx);

this.restoreTransform(ctx);
// Draw rect text

@@ -151,3 +152,2 @@ if (style.text != null) {

ctx.restore();
}

@@ -154,0 +154,0 @@ },

@@ -15,4 +15,5 @@ 'use strict';

* @param {Array.<Object>} colorStops
* @param {boolean} [globalCoord=false]
*/
var LinearGradient = function (x, y, x2, y2, colorStops) {
var LinearGradient = function (x, y, x2, y2, colorStops, globalCoord) {
this.x = x == null ? 0 : x;

@@ -26,2 +27,8 @@

// Can be cloned
this.type = 'linear';
// If use global coord
this.global = globalCoord || false;
Gradient.call(this, colorStops);

@@ -32,5 +39,3 @@ };

constructor: LinearGradient,
type: 'linear'
constructor: LinearGradient
};

@@ -37,0 +42,0 @@

@@ -47,2 +47,6 @@ /**

}
// FIXME
ctx.save();
var x;

@@ -61,3 +65,2 @@ var y;

var transform = this.transform;
var invTransform = this.invTransform;
if (transform) {

@@ -67,4 +70,2 @@ tmpRect.copy(rect);

rect = tmpRect;
// Transform back
setTransform(ctx, invTransform);
}

@@ -106,4 +107,6 @@

ctx.textAlign = align;
ctx.textBaseline = baseline;
// Use canvas default left textAlign. Giving invalid value will cause state not change
ctx.textAlign = align || 'left';
// Use canvas default alphabetic baseline
ctx.textBaseline = baseline || 'alphabetic';

@@ -117,4 +120,5 @@ var textFill = style.textFill;

// Text shadow
ctx.shadowColor = style.textShadowColor;
// Always set shadowBlur and shadowOffset to avoid leak from displayable
ctx.shadowBlur = style.textShadowBlur;
ctx.shadowColor = style.textShadowColor || 'transparent';
ctx.shadowOffsetX = style.textShadowOffsetX;

@@ -130,4 +134,3 @@ ctx.shadowOffsetY = style.textShadowOffsetY;

// Transform again
transform && setTransform(ctx, transform);
ctx.restore();
}

@@ -134,0 +137,0 @@ };

@@ -13,14 +13,5 @@ /**

var Gradient = require('./Gradient');
var Pattern = require('./Pattern');
var getCanvasPattern = Pattern.prototype.getCanvasPattern;
function pathHasFill(style) {
var fill = style.fill;
return fill != null && fill !== 'none';
}
function pathHasStroke(style) {
var stroke = style.stroke;
return stroke != null && stroke !== 'none' && style.lineWidth > 0;
}
var abs = Math.abs;

@@ -54,32 +45,41 @@

brush: function (ctx) {
ctx.save();
brush: function (ctx, prevEl) {
var style = this.style;
var path = this.path;
var hasStroke = pathHasStroke(style);
var hasFill = pathHasFill(style);
var hasFillGradient = hasFill && !!(style.fill.colorStops);
var hasStrokeGradient = hasStroke && !!(style.stroke.colorStops);
var hasStroke = style.hasStroke();
var hasFill = style.hasFill();
var fill = style.fill;
var stroke = style.stroke;
var hasFillGradient = hasFill && !!(fill.colorStops);
var hasStrokeGradient = hasStroke && !!(stroke.colorStops);
var hasFillPattern = hasFill && !!(fill.image);
var hasStrokePattern = hasStroke && !!(stroke.image);
style.bind(ctx, this);
style.bind(ctx, this, prevEl);
this.setTransform(ctx);
if (this.__dirtyPath) {
if (this.__dirty) {
var rect = this.getBoundingRect();
// Update gradient because bounding rect may changed
if (hasFillGradient) {
this._fillGradient = style.getGradient(ctx, style.fill, rect);
this._fillGradient = style.getGradient(ctx, fill, rect);
}
if (hasStrokeGradient) {
this._strokeGradient = style.getGradient(ctx, style.stroke, rect);
this._strokeGradient = style.getGradient(ctx, stroke, rect);
}
}
// Use the gradient
// Use the gradient or pattern
if (hasFillGradient) {
// PENDING If may have affect the state
ctx.fillStyle = this._fillGradient;
}
else if (hasFillPattern) {
ctx.fillStyle = getCanvasPattern.call(fill, ctx);
}
if (hasStrokeGradient) {
ctx.strokeStyle = this._strokeGradient;
}
else if (hasStrokePattern) {
ctx.strokeStyle = getCanvasPattern.call(stroke, ctx);
}

@@ -111,3 +111,3 @@ var lineDash = style.lineDash;

this.buildPath(path, this.shape);
this.buildPath(path, this.shape, false);

@@ -132,12 +132,21 @@ // Clear path dirty flag

if (lineDash && ctxLineDash) {
// PENDING
// Remove lineDash
ctx.setLineDash([]);
}
this.restoreTransform(ctx);
// Draw rect text
if (style.text != null) {
if (style.text || style.text === 0) {
// var rect = this.getBoundingRect();
this.drawRectText(ctx, this.getBoundingRect());
}
ctx.restore();
},
buildPath: function (ctx, shapeCfg) {},
// When bundling path, some shape may decide if use moveTo to begin a new subpath or closePath
// Like in circle
buildPath: function (ctx, shapeCfg, inBundle) {},

@@ -152,3 +161,3 @@ getBoundingRect: function () {

path.beginPath();
this.buildPath(path, this.shape);
this.buildPath(path, this.shape, false);
}

@@ -159,3 +168,3 @@ rect = path.getBoundingRect();

if (pathHasStroke(style)) {
if (style.hasStroke()) {
// Needs update rect with stroke lineWidth when

@@ -173,3 +182,3 @@ // 1. Element changes scale or lineWidth

// Only add extra hover lineWidth when there are no fill
if (!pathHasFill(style)) {
if (!style.hasFill()) {
w = Math.max(w, this.strokeContainThreshold);

@@ -203,3 +212,3 @@ }

var pathData = this.path.data;
if (pathHasStroke(style)) {
if (style.hasStroke()) {
var lineWidth = style.lineWidth;

@@ -210,3 +219,3 @@ var lineScale = style.strokeNoScale ? this.getLineScale() : 1;

// Only add extra hover lineWidth when there are no fill
if (!pathHasFill(style)) {
if (!style.hasFill()) {
lineWidth = Math.max(lineWidth, this.strokeContainThreshold);

@@ -221,3 +230,3 @@ }

}
if (pathHasFill(style)) {
if (style.hasFill()) {
return pathContain.contain(pathData, x, y);

@@ -233,3 +242,3 @@ }

dirty: function (dirtyPath) {
if (arguments.length ===0) {
if (dirtyPath == null) {
dirtyPath = true;

@@ -266,2 +275,4 @@ }

this.setShape(value);
this.__dirtyPath = true;
this._rect = null;
}

@@ -268,0 +279,0 @@ else {

@@ -14,4 +14,5 @@ 'use strict';

* @param {Array.<Object>} [colorStops]
* @param {boolean} [globalCoord=false]
*/
var RadialGradient = function (x, y, r, colorStops) {
var RadialGradient = function (x, y, r, colorStops, globalCoord) {
this.x = x == null ? 0.5 : x;

@@ -23,2 +24,8 @@

// Can be cloned
this.type = 'radial';
// If use global coord
this.global = globalCoord || false;
Gradient.call(this, colorStops);

@@ -29,5 +36,3 @@ };

constructor: RadialGradient,
type: 'radial'
constructor: RadialGradient
};

@@ -34,0 +39,0 @@

@@ -10,3 +10,3 @@ 'use strict';

module.exports = require('../Path').extend({
type: 'circle',

@@ -20,9 +20,14 @@

buildPath : function (ctx, shape) {
buildPath : function (ctx, shape, inBundle) {
// Better stroking in ShapeBundle
ctx.moveTo(shape.cx + shape.r, shape.cy);
// Always do it may have performence issue ( fill may be 2x more cost)
if (inBundle) {
ctx.moveTo(shape.cx + shape.r, shape.cy);
}
// Better stroking in ShapeBundle
// ctx.moveTo(shape.cx + shape.r, shape.cy);
ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);
return;
}
});

@@ -6,8 +6,10 @@ /**

var STYLE_LIST_COMMON = [
'lineCap', 'lineJoin', 'miterLimit',
'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'shadowColor'
var STYLE_COMMON_PROPS = [
['shadowBlur', 0], ['shadowOffsetX', 0], ['shadowOffsetY', 0], ['shadowColor', '#000'],
['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
];
// var SHADOW_PROPS = STYLE_COMMON_PROPS.slice(0, 4);
// var LINE_PROPS = STYLE_COMMON_PROPS.slice(4);
var Style = function (opts) {

@@ -17,2 +19,41 @@ this.extendFrom(opts);

function createLinearGradient(ctx, obj, rect) {
// var size =
var x = obj.x;
var x2 = obj.x2;
var y = obj.y;
var y2 = obj.y2;
if (!obj.global) {
x = x * rect.width + rect.x;
x2 = x2 * rect.width + rect.x;
y = y * rect.height + rect.y;
y2 = y2 * rect.height + rect.y;
}
var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
return canvasGradient;
}
function createRadialGradient(ctx, obj, rect) {
var width = rect.width;
var height = rect.height;
var min = Math.min(width, height);
var x = obj.x;
var y = obj.y;
var r = obj.r;
if (!obj.global) {
x = x * width + rect.x;
y = y * height + rect.y;
r = r * min;
}
var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
return canvasGradient;
}
Style.prototype = {

@@ -134,16 +175,40 @@

/**
* @type {string}
* https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
*/
blend: null,
/**
* @param {CanvasRenderingContext2D} ctx
*/
bind: function (ctx, el) {
var fill = this.fill;
var stroke = this.stroke;
for (var i = 0; i < STYLE_LIST_COMMON.length; i++) {
var styleName = STYLE_LIST_COMMON[i];
bind: function (ctx, el, prevEl) {
var style = this;
var prevStyle = prevEl && prevEl.style;
var firstDraw = !prevStyle;
if (this[styleName] != null) {
ctx[styleName] = this[styleName];
for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
var prop = STYLE_COMMON_PROPS[i];
var styleName = prop[0];
if (firstDraw || style[styleName] !== prevStyle[styleName]) {
// FIXME Invalid property value will cause style leak from previous element.
ctx[styleName] = style[styleName] || prop[1];
}
}
if (stroke != null) {
var lineWidth = this.lineWidth;
if ((firstDraw || style.fill !== prevStyle.fill)) {
ctx.fillStyle = style.fill;
}
if ((firstDraw || style.stroke !== prevStyle.stroke)) {
ctx.strokeStyle = style.stroke;
}
if ((firstDraw || style.opacity !== prevStyle.opacity)) {
ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
}
if ((firstDraw || style.blend !== prevStyle.blend)) {
ctx.globalCompositeOperation = style.blend || 'source-over';
}
if (this.hasStroke()) {
var lineWidth = style.lineWidth;
ctx.lineWidth = lineWidth / (

@@ -153,13 +218,14 @@ (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1

}
// Gradient will be created and set in Path#brush. So ignore it here
if (fill != null && fill !== 'none' && !fill.colorStops) {
ctx.fillStyle = fill;
}
if (stroke != null && stroke !== 'none' && !stroke.colorStops) {
// Use canvas gradient if has
ctx.strokeStyle = stroke;
}
this.opacity != null && (ctx.globalAlpha = this.opacity);
},
hasFill: function () {
var fill = this.fill;
return fill != null && fill !== 'none';
},
hasStroke: function () {
var stroke = this.stroke;
return stroke != null && stroke !== 'none' && this.lineWidth > 0;
},
/**

@@ -207,31 +273,5 @@ * Extend from other style

createLinearGradient: function (ctx, obj, rect) {
// var size =
var x = obj.x * rect.width + rect.x;
var x2 = obj.x2 * rect.width + rect.x;
var y = obj.y * rect.height + rect.y;
var y2 = obj.y2 * rect.height + rect.y;
var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
return canvasGradient;
},
createRadialGradient: function (ctx, obj, rect) {
var width = rect.width;
var height = rect.height;
var min = Math.min(width, height);
var x = obj.x * width + rect.x;
var y = obj.y * height + rect.y;
var r = obj.r * min;
var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
return canvasGradient;
},
getGradient: function (ctx, obj, rect) {
var method = obj.type === 'radial' ? 'createRadialGradient' : 'createLinearGradient';
var canvasGradient = this[method](ctx, obj, rect);
var method = obj.type === 'radial' ? createRadialGradient : createLinearGradient;
var canvasGradient = method(ctx, obj, rect);
var colorStops = obj.colorStops;

@@ -248,11 +288,12 @@ for (var i = 0; i < colorStops.length; i++) {

var styleProto = Style.prototype;
var name;
var i;
for (i = 0; i < STYLE_LIST_COMMON.length; i++) {
name = STYLE_LIST_COMMON[i];
if (!(name in styleProto)) {
styleProto[name] = null;
for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
var prop = STYLE_COMMON_PROPS[i];
if (!(prop[0] in styleProto)) {
styleProto[prop[0]] = prop[1];
}
}
// Provide for others
Style.getGradient = styleProto.getGradient;
module.exports = Style;

@@ -32,3 +32,3 @@ /**

brush: function (ctx) {
brush: function (ctx, prevEl) {
var style = this.style;

@@ -39,4 +39,2 @@ var x = style.x || 0;

var text = style.text;
var textFill = style.fill;
var textStroke = style.stroke;

@@ -46,14 +44,11 @@ // Convert to string

// Always bind style
style.bind(ctx, this, prevEl);
if (text) {
ctx.save();
this.style.bind(ctx);
this.setTransform(ctx);
textFill && (ctx.fillStyle = textFill);
textStroke && (ctx.strokeStyle = textStroke);
ctx.font = style.textFont || style.font;
ctx.textAlign = style.textAlign;
var textBaseline;
var textAlign = style.textAlign;
if (style.textVerticalAlign) {

@@ -64,3 +59,3 @@ var rect = textContain.getBoundingRect(

// Ignore textBaseline
ctx.textBaseline = 'middle';
textBaseline = 'middle';
switch (style.textVerticalAlign) {

@@ -78,4 +73,17 @@ case 'middle':

else {
ctx.textBaseline = style.textBaseline;
textBaseline = style.textBaseline;
}
ctx.font = style.textFont || style.font;
ctx.textAlign = textAlign || 'left';
// Use canvas default left textAlign. Giving invalid value will cause state not change
if (ctx.textAlign !== textAlign) {
ctx.textAlign = 'left';
}
ctx.textBaseline = textBaseline || 'alphabetic';
// Use canvas default alphabetic baseline
if (ctx.textBaseline !== textBaseline) {
ctx.textBaseline = 'alphabetic';
}
var lineHeight = textContain.measureText('国', ctx.font).width;

@@ -85,8 +93,8 @@

for (var i = 0; i < textLines.length; i++) {
textFill && ctx.fillText(textLines[i], x, y);
textStroke && ctx.strokeText(textLines[i], x, y);
style.hasFill() && ctx.fillText(textLines[i], x, y);
style.hasStroke() && ctx.strokeText(textLines[i], x, y);
y += lineHeight;
}
ctx.restore();
this.restoreTransform(ctx);
}

@@ -93,0 +101,0 @@ },

@@ -73,3 +73,3 @@ 'use strict';

this.root.style.cursor = hovered ? hovered.cursor : this._defaultCursorStyle;
this.root.style.cursor = hovered ? hovered.cursor : 'default';
// Mouse out on previous hovered element

@@ -224,3 +224,4 @@ if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {

event,
zrHandler.findHover(event.zrX, event.zrY, null)
zrHandler.findHover(event.zrX, event.zrY, null),
zrHandler.root
);

@@ -308,8 +309,2 @@

* @private
* @type {string}
*/
this._defaultCursorStyle = 'default';
/**
* @private
* @type {module:zrender/core/GestureMgr}

@@ -404,6 +399,6 @@ */

* 设置默认的cursor style
* @param {string} cursorStyle 例如 crosshair
* @param {string} [cursorStyle='default'] 例如 crosshair
*/
setDefaultCursorStyle: function (cursorStyle) {
this._defaultCursorStyle = cursorStyle;
setCursorStyle: function (cursorStyle) {
this.root.style.cursor = cursorStyle || 'default';
},

@@ -410,0 +405,0 @@

@@ -9,2 +9,4 @@ /**

var config = require('./config');
var Style = require('./graphic/Style');
var Pattern = require('./graphic/Pattern');

@@ -178,3 +180,3 @@ function returnFalse() {

var haveClearColor = this.clearColor;
var clearColor = this.clearColor;
var haveMotionBLur = this.motionBlur && !clearAll;

@@ -199,5 +201,22 @@ var lastFrameAlpha = this.lastFrameAlpha;

ctx.clearRect(0, 0, width / dpr, height / dpr);
if (haveClearColor) {
if (clearColor) {
var clearColorGradientOrPattern;
// Gradient
if (clearColor.colorStops) {
// Cache canvas gradient
clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
x: 0,
y: 0,
width: width / dpr,
height: height / dpr
});
clearColor.__canvasGradient = clearColorGradientOrPattern;
}
// Pattern
else if (clearColor.image) {
clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
}
ctx.save();
ctx.fillStyle = this.clearColor;
ctx.fillStyle = clearColorGradientOrPattern || clearColor;
ctx.fillRect(0, 0, width / dpr, height / dpr);

@@ -204,0 +223,0 @@ ctx.restore();

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

var arrySlice = Array.prototype.slice;
var zrUtil = require('../core/util');
var indexOf = zrUtil.indexOf;

@@ -45,4 +43,6 @@ /**

if (indexOf(_h[event], event) >= 0) {
return this;
for (var i = 0; i < _h[event].length; i++) {
if (_h[event][i].h === handler) {
return this;
}
}

@@ -76,2 +76,8 @@

for (var i = 0; i < _h[event].length; i++) {
if (_h[event][i].h === handler) {
return this;
}
}
_h[event].push({

@@ -78,0 +84,0 @@ h: handler,

@@ -149,2 +149,9 @@ 'use strict';

transformableProto.restoreTransform = function (ctx) {
var m = this.invTransform;
if (m) {
ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
}
}
var tmpTransform = [];

@@ -151,0 +158,0 @@

@@ -15,5 +15,14 @@ 'use strict';

var BoundingRect = require('./core/BoundingRect');
var timsort = require('./core/timsort');
var Layer = require('./Layer');
var requestAnimationFrame = require('./animation/requestAnimationFrame');
// PENDIGN
// Layer exceeds MAX_PROGRESSIVE_LAYER_NUMBER may have some problem when flush directly second time.
//
// Maximum progressive layer. When exceeding this number. All elements will be drawed in the last layer.
var MAX_PROGRESSIVE_LAYER_NUMBER = 5;
function parseInt10(val) {

@@ -46,3 +55,2 @@ return parseInt(val, 10);

function postProcessLayer(layer) {
layer.__dirty = false;
if (layer.__unusedCount == 1) {

@@ -66,2 +74,6 @@ layer.clear();

function isClipPathChanged(clipPaths, prevClipPaths) {
if (clipPaths == prevClipPaths) { // Can both be null or undefined
return false;
}
if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {

@@ -105,2 +117,14 @@ return true;

function createRoot(width, height) {
var domRoot = document.createElement('div');
var domRootStyle = domRoot.style;
// domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
domRootStyle.position = 'relative';
domRootStyle.overflow = 'hidden';
domRootStyle.width = width + 'px';
domRootStyle.height = height + 'px';
return domRoot;
}
/**

@@ -114,2 +138,3 @@ * @alias module:zrender/Painter

var Painter = function (root, storage, opts) {
// In node environment using node-canvas
var singleCanvas = !root.nodeName // In node ?

@@ -137,7 +162,6 @@ || root.nodeName.toUpperCase() === 'CANVAS';

// In node environment using node-canvas
if (rootStyle) {
rootStyle['-webkit-tap-highlight-color'] = 'transparent';
rootStyle['-webkit-user-select'] = 'none';
rootStyle['user-select'] = 'none';
rootStyle['-webkit-user-select'] =
rootStyle['user-select'] =
rootStyle['-webkit-touch-callout'] = 'none';

@@ -153,29 +177,28 @@

/**
* @type {Array.<number>}
* @private
*/
var zlevelList = this._zlevelList = [];
/**
* @type {Object.<string, module:zrender/Layer>}
* @private
*/
var layers = this._layers = {};
/**
* @type {Object.<string, Object>}
* @type {private}
*/
this._layerConfig = {};
if (!singleCanvas) {
var width = this._getWidth();
var height = this._getHeight();
this._width = width;
this._height = height;
this._width = this._getWidth();
this._height = this._getHeight();
var domRoot = document.createElement('div');
this._domRoot = domRoot;
var domRootStyle = domRoot.style;
// domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
domRootStyle.position = 'relative';
domRootStyle.overflow = 'hidden';
domRootStyle.width = this._width + 'px';
domRootStyle.height = this._height + 'px';
var domRoot = this._domRoot = createRoot(
this._width, this._height
);
root.appendChild(domRoot);
/**
* @type {Object.<key, module:zrender/Layer>}
* @private
*/
this._layers = {};
/**
* @type {Array.<number>}
* @private
*/
this._zlevelList = [];
}

@@ -195,11 +218,18 @@ else {

// mainLayer.resize(width, height);
this._layers = {
0: mainLayer
};
this._zlevelList = [0];
layers[0] = mainLayer;
zlevelList.push(0);
}
this._layerConfig = {};
this.pathToImage = this._createPathToImage();
this.pathToImage = this._createPathToImage();
// Layers for progressive rendering
this._progressiveLayers = [];
/**
* @type {module:zrender/Layer}
* @private
*/
this._hoverlayer;
this._hoverElements = [];
};

@@ -230,3 +260,5 @@

refresh: function (paintAll) {
var list = this.storage.getDisplayList(true);
var zlevelList = this._zlevelList;

@@ -245,5 +277,130 @@

this.refreshHover();
if (this._progressiveLayers.length) {
this._startProgessive();
}
return this;
},
addHover: function (el, hoverStyle) {
if (el.__hoverMir) {
return;
}
var elMirror = new el.constructor({
style: el.style,
shape: el.shape
});
elMirror.__from = el;
el.__hoverMir = elMirror;
elMirror.setStyle(hoverStyle);
this._hoverElements.push(elMirror);
},
removeHover: function (el) {
var elMirror = el.__hoverMir;
var hoverElements = this._hoverElements;
var idx = util.indexOf(hoverElements, elMirror);
if (idx >= 0) {
hoverElements.splice(idx, 1);
}
el.__hoverMir = null;
},
clearHover: function (el) {
var hoverElements = this._hoverElements;
for (var i = 0; i < hoverElements.length; i++) {
var from = hoverElements[i].__from;
if (from) {
from.__hoverMir = null;
}
}
hoverElements.length = 0;
},
refreshHover: function () {
var hoverElements = this._hoverElements;
var len = hoverElements.length;
var hoverLayer = this._hoverlayer;
hoverLayer && hoverLayer.clear();
if (!len) {
return;
}
timsort(hoverElements, this.storage.displayableSortFunc);
// Use a extream large zlevel
// FIXME?
if (!hoverLayer) {
hoverLayer = this._hoverlayer = this.getLayer(1e5);
}
var scope = {};
hoverLayer.ctx.save();
for (var i = 0; i < len;) {
var el = hoverElements[i];
var originalEl = el.__from;
// Original el is removed
// PENDING
if (!(originalEl && originalEl.__zr)) {
hoverElements.splice(i, 1);
originalEl.__hoverMir = null;
len--;
continue;
}
i++;
// Use transform
// FIXME style and shape ?
if (!originalEl.invisible) {
el.transform = originalEl.transform;
el.invTransform = originalEl.invTransform;
el.__clipPaths = originalEl.__clipPaths;
// el.
this._doPaintEl(el, hoverLayer, true, scope);
}
}
hoverLayer.ctx.restore();
},
_startProgessive: function () {
var self = this;
if (!self._furtherProgressive) {
return;
}
// Use a token to stop progress steps triggered by
// previous zr.refresh calling.
var token = self._progressiveToken = +new Date();
self._progress++;
requestAnimationFrame(step);
function step() {
// In case refreshed or disposed
if (token === self._progressiveToken && self.storage) {
self._doPaintList(self.storage.getDisplayList());
if (self._furtherProgressive) {
self._progress++;
requestAnimationFrame(step);
}
else {
self._progressiveToken = -1;
}
}
}
},
_clearProgressive: function () {
this._progressiveToken = -1;
this._progress = 0;
util.each(this._progressiveLayers, function (layer) {
layer.__dirty && layer.clear();
});
},
_paintList: function (list, paintAll) {

@@ -257,2 +414,12 @@

this._clearProgressive();
this.eachBuildinLayer(preProcessLayer);
this._doPaintList(list, paintAll);
this.eachBuildinLayer(postProcessLayer);
},
_doPaintList: function (list, paintAll) {
var currentLayer;

@@ -262,15 +429,46 @@ var currentZLevel;

var viewWidth = this._width;
var viewHeight = this._height;
// var invTransform = [];
var scope;
this.eachBuildinLayer(preProcessLayer);
var progressiveLayerIdx = 0;
var currentProgressiveLayer;
// var invTransform = [];
var prevElClipPaths = null;
var width = this._width;
var height = this._height;
var layerProgress;
var frame = this._progress;
function flushProgressiveLayer(layer) {
ctx.save();
ctx.globalAlpha = 1;
ctx.shadowBlur = 0;
// Avoid layer don't clear in next progressive frame
currentLayer.__dirty = true;
ctx.drawImage(layer.dom, 0, 0, width, height);
ctx.restore();
currentLayer.ctx.restore();
}
for (var i = 0, l = list.length; i < l; i++) {
var el = list[i];
var elZLevel = this._singleCanvas ? 0 : el.zlevel;
var elFrame = el.__frame;
// Flush at current context
// PENDING
if (elFrame < 0 && currentProgressiveLayer) {
flushProgressiveLayer(currentProgressiveLayer);
currentProgressiveLayer = null;
}
// Change draw layer
if (currentZLevel !== elZLevel) {
if (ctx) {
ctx.restore();
}
// Reset scope
scope = {};
// Only 0 zlevel if only has one canvas

@@ -288,2 +486,3 @@ currentZLevel = elZLevel;

ctx = currentLayer.ctx;
ctx.save();

@@ -298,33 +497,43 @@ // Reset the count

if (
(currentLayer.__dirty || paintAll)
// Ignore invisible element
&& !el.invisible
// Ignore transparent element
&& el.style.opacity !== 0
// Ignore scale 0 element, in some environment like node-canvas
// Draw a scale 0 element can cause all following draw wrong
&& el.scale[0] && el.scale[1]
// Ignore culled element
&& !(el.culling && isDisplayableCulled(el, viewWidth, viewHeight))
) {
var clipPaths = el.__clipPaths;
if (!(currentLayer.__dirty || paintAll)) {
continue;
}
if (elFrame >= 0) {
// Progressive layer changed
if (!currentProgressiveLayer) {
currentProgressiveLayer = this._progressiveLayers[
Math.min(progressiveLayerIdx++, MAX_PROGRESSIVE_LAYER_NUMBER - 1)
];
// Optimize when clipping on group with several elements
if (isClipPathChanged(clipPaths, prevElClipPaths)) {
// If has previous clipping state, restore from it
if (prevElClipPaths) {
ctx.restore();
currentProgressiveLayer.ctx.save();
currentProgressiveLayer.renderScope = {};
if (currentProgressiveLayer
&& (currentProgressiveLayer.__progress > currentProgressiveLayer.__maxProgress)
) {
// flushProgressiveLayer(currentProgressiveLayer);
// Quick jump all progressive elements
// All progressive element are not dirty, jump over and flush directly
i = currentProgressiveLayer.__nextIdxNotProg - 1;
// currentProgressiveLayer = null;
continue;
}
// New clipping state
if (clipPaths) {
ctx.save();
doClip(clipPaths, ctx);
layerProgress = currentProgressiveLayer.__progress;
if (!currentProgressiveLayer.__dirty) {
// Keep rendering
frame = layerProgress;
}
prevElClipPaths = clipPaths;
currentProgressiveLayer.__progress = frame + 1;
}
el.beforeBrush && el.beforeBrush(ctx);
el.brush(ctx, false);
el.afterBrush && el.afterBrush(ctx);
if (elFrame === frame) {
this._doPaintEl(el, currentProgressiveLayer, true, currentProgressiveLayer.renderScope);
}
}
else {
this._doPaintEl(el, currentLayer, paintAll, scope);
}

@@ -334,10 +543,68 @@ el.__dirty = false;

// If still has clipping state
if (prevElClipPaths) {
ctx.restore();
if (currentProgressiveLayer) {
flushProgressiveLayer(currentProgressiveLayer);
}
this.eachBuildinLayer(postProcessLayer);
// Restore the lastLayer ctx
ctx && ctx.restore();
// If still has clipping state
// if (scope.prevElClipPaths) {
// ctx.restore();
// }
this._furtherProgressive = false;
util.each(this._progressiveLayers, function (layer) {
if (layer.__maxProgress >= layer.__progress) {
this._furtherProgressive = true;
}
}, this);
},
_doPaintEl: function (el, currentLayer, forcePaint, scope) {
var ctx = currentLayer.ctx;
if (
(currentLayer.__dirty || forcePaint)
// Ignore invisible element
&& !el.invisible
// Ignore transparent element
&& el.style.opacity !== 0
// Ignore scale 0 element, in some environment like node-canvas
// Draw a scale 0 element can cause all following draw wrong
&& el.scale[0] && el.scale[1]
// Ignore culled element
&& !(el.culling && isDisplayableCulled(el, this._width, this._height))
) {
var clipPaths = el.__clipPaths;
// Optimize when clipping on group with several elements
if (scope.prevClipLayer !== currentLayer
|| isClipPathChanged(clipPaths, scope.prevElClipPaths)
) {
// If has previous clipping state, restore from it
if (scope.prevElClipPaths) {
scope.prevClipLayer.ctx.restore();
scope.prevClipLayer = scope.prevElClipPaths = null;
// Reset prevEl since context has been restored
scope.prevEl = null;
}
// New clipping state
if (clipPaths) {
ctx.save();
doClip(clipPaths, ctx);
scope.prevClipLayer = currentLayer;
scope.prevElClipPaths = clipPaths;
}
}
el.beforeBrush && el.beforeBrush(ctx);
el.brush(ctx, scope.prevEl || null);
scope.prevEl = el;
el.afterBrush && el.afterBrush(ctx);
}
},
/**

@@ -481,10 +748,23 @@ * 获取 zlevel 所在层,如果不存在则会创建一个新的层

var layers = this._layers;
var progressiveLayers = this._progressiveLayers;
var elCounts = {};
var elCountsLastFrame = {};
var progressiveElCountsLastFrame = {};
this.eachBuildinLayer(function (layer, z) {
elCounts[z] = layer.elCount;
elCountsLastFrame[z] = layer.elCount;
layer.elCount = 0;
layer.__dirty = false;
});
util.each(progressiveLayers, function (layer, idx) {
progressiveElCountsLastFrame[idx] = layer.elCount;
layer.elCount = 0;
layer.__dirty = false;
});
var progressiveLayerCount = 0;
var currentProgressiveLayer;
var lastProgressiveKey;
var frameCount = 0;
for (var i = 0, l = list.length; i < l; i++) {

@@ -494,18 +774,71 @@ var el = list[i];

var layer = layers[zlevel];
var elProgress = el.progressive;
if (layer) {
layer.elCount++;
// 已经被标记为需要刷新
if (layer.__dirty) {
continue;
layer.__dirty = layer.__dirty || el.__dirty;
}
/////// Update progressive
if (elProgress >= 0) {
// Fix wrong progressive sequence problem.
if (lastProgressiveKey !== elProgress) {
lastProgressiveKey = elProgress;
frameCount++;
}
layer.__dirty = el.__dirty;
var elFrame = el.__frame = frameCount - 1;
if (!currentProgressiveLayer) {
var idx = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER - 1);
currentProgressiveLayer = progressiveLayers[idx];
if (!currentProgressiveLayer) {
currentProgressiveLayer = progressiveLayers[idx] = new Layer(
'progressive', this, this.dpr
);
currentProgressiveLayer.initContext();
}
currentProgressiveLayer.__maxProgress = 0;
}
currentProgressiveLayer.__dirty = currentProgressiveLayer.__dirty || el.__dirty;
currentProgressiveLayer.elCount++;
currentProgressiveLayer.__maxProgress = Math.max(
currentProgressiveLayer.__maxProgress, elFrame
);
if (currentProgressiveLayer.__maxProgress >= currentProgressiveLayer.__progress) {
// Should keep rendering this layer because progressive rendering is not finished yet
layer.__dirty = true;
}
}
else {
el.__frame = -1;
if (currentProgressiveLayer) {
currentProgressiveLayer.__nextIdxNotProg = i;
progressiveLayerCount++;
currentProgressiveLayer = null;
}
}
}
if (currentProgressiveLayer) {
progressiveLayerCount++;
currentProgressiveLayer.__nextIdxNotProg = i;
}
// 层中的元素数量有发生变化
this.eachBuildinLayer(function (layer, z) {
if (elCounts[z] !== layer.elCount) {
if (elCountsLastFrame[z] !== layer.elCount) {
layer.__dirty = true;
}
});
progressiveLayers.length = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER);
util.each(progressiveLayers, function (layer, idx) {
if (progressiveElCountsLastFrame[idx] !== layer.elCount) {
el.__dirty = true;
}
if (layer.__dirty) {
layer.__progress = 0;
}
});
},

@@ -639,3 +972,2 @@

var ctx = imageLayer.ctx;
imageLayer.clearColor = opts.backgroundColor;

@@ -646,10 +978,6 @@ imageLayer.clear();

var scope = {};
for (var i = 0; i < displayList.length; i++) {
var el = displayList[i];
if (!el.invisible) {
el.beforeBrush && el.beforeBrush(ctx);
// TODO Check image cross origin
el.brush(ctx, false);
el.afterBrush && el.afterBrush(ctx);
}
this._doPaintEl(el, imageLayer, true, scope);
}

@@ -656,0 +984,0 @@

@@ -12,11 +12,19 @@ 'use strict';

var util = require('./core/util');
var env = require('./core/env');
var Group = require('./container/Group');
// Use timsort because in most case elements are partially sorted
// https://jsfiddle.net/pissang/jr4x7mdm/8/
var timsort = require('./core/timsort');
function shapeCompareFunc(a, b) {
if (a.zlevel === b.zlevel) {
if (a.z === b.z) {
if (a.z2 === b.z2) {
return a.__renderidx - b.__renderidx;
}
// if (a.z2 === b.z2) {
// // FIXME Slow has renderidx compare
// // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement
// // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012
// return a.__renderidx - b.__renderidx;
// }
return a.z2 - b.z2;

@@ -49,2 +57,12 @@ }

/**
* @param {Function} cb
*
*/
traverse: function (cb, context) {
for (var i = 0; i < this._roots.length; i++) {
this._roots[i].traverse(cb, context);
}
},
/**
* 返回所有图形的绘制队列

@@ -80,7 +98,8 @@ * @param {boolean} [update=false] 是否在返回前更新该数组

for (var i = 0, len = displayList.length; i < len; i++) {
displayList[i].__renderidx = i;
}
// for (var i = 0, len = displayList.length; i < len; i++) {
// displayList[i].__renderidx = i;
// }
displayList.sort(shapeCompareFunc);
// displayList.sort(shapeCompareFunc);
env.canvasSupported && timsort(displayList, shapeCompareFunc);
},

@@ -96,4 +115,8 @@

el.update();
if (el.__dirty) {
el.update();
}
el.afterUpdate();

@@ -117,3 +140,3 @@

if (el.type == 'group') {
if (el.isGroup) {
var children = el._children;

@@ -126,3 +149,5 @@

// FIXME __dirtyPath ?
child.__dirty = el.__dirty || child.__dirty;
if (el.__dirty) {
child.__dirty = true;
}

@@ -243,3 +268,5 @@ this._updateAndAddDisplayable(child, clipPaths, includeIgnore);

this._roots = null;
}
},
displayableSortFunc: shapeCompareFunc
};

@@ -246,0 +273,0 @@

@@ -459,6 +459,7 @@ /**

function stringify(arrColor, type) {
if (type === 'rgb' || type === 'hsv' || type === 'hsl') {
arrColor = arrColor.slice(0, 3);
var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
colorStr += ',' + arrColor[3];
}
return type + '(' + arrColor.join(',') + ')';
return type + '(' + colorStr + ')';
}

@@ -465,0 +466,0 @@

@@ -381,8 +381,6 @@

var len = pathEls.length;
var pathEl;
var i;
for (i = 0; i < len; i++) {
pathEl = pathEls[i];
for (var i = 0; i < len; i++) {
var pathEl = pathEls[i];
if (pathEl.__dirty) {
pathEl.buildPath(pathEl.path, pathEl.shape);
pathEl.buildPath(pathEl.path, pathEl.shape, true);
}

@@ -389,0 +387,0 @@ pathList.push(pathEl.path);

@@ -217,11 +217,11 @@ // http://www.w3.org/TR/NOTE-VML

var updateStrokeNode = function (el, style) {
if (style.lineJoin != null) {
el.joinstyle = style.lineJoin;
}
if (style.miterLimit != null) {
el.miterlimit = style.miterLimit * Z;
}
if (style.lineCap != null) {
el.endcap = style.lineCap;
}
// if (style.lineJoin != null) {
// el.joinstyle = style.lineJoin;
// }
// if (style.miterLimit != null) {
// el.miterlimit = style.miterLimit * Z;
// }
// if (style.lineCap != null) {
// el.endcap = style.lineCap;
// }
if (style.lineDash != null) {

@@ -836,2 +836,3 @@ el.dashstyle = style.lineDash.join(' ');

+ fontStyle.size + 'px "' + fontStyle.family + '"';
var baseline = style.textBaseline;

@@ -838,0 +839,0 @@ var verticalAlign = style.textVerticalAlign;

@@ -151,2 +151,6 @@ /**

clear: function () {
this.root.removeChild(this.vmlViewport);
},
_getWidth: function () {

@@ -153,0 +157,0 @@ var root = this.root;

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

*/
zrender.version = '3.1.0';
zrender.version = '3.1.1';

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

}
if (self._needsRefreshHover) {
self.refreshHoverImmediately();
}
}

@@ -184,3 +187,3 @@ }

* 添加元素
* @param {string|module:zrender/Element} el
* @param {module:zrender/Element} el
*/

@@ -194,3 +197,3 @@ add: function (el) {

* 删除元素
* @param {string|module:zrender/Element} el
* @param {module:zrender/Element} el
*/

@@ -237,2 +240,51 @@ remove: function (el) {

/**
* Add element to hover layer
* @param {module:zrender/Element} el
* @param {Object} style
*/
addHover: function (el, style) {
if (this.painter.addHover) {
this.painter.addHover(el, style);
this.refreshHover();
}
},
/**
* Add element from hover layer
* @param {module:zrender/Element} el
*/
removeHover: function (el) {
if (this.painter.removeHover) {
this.painter.removeHover(el);
this.refreshHover();
}
},
/**
* Clear all hover elements in hover layer
* @param {module:zrender/Element} el
*/
clearHover: function () {
if (this.painter.clearHover) {
this.painter.clearHover();
this.refreshHover();
}
},
/**
* Refresh hover in next frame
*/
refreshHover: function () {
this._needsRefreshHover = true;
},
/**
* Refresh hover immediately
*/
refreshHoverImmediately: function () {
this._needsRefreshHover = false;
this.painter.refreshHover && this.painter.refreshHover();
},
/**
* Resize the canvas.

@@ -293,6 +345,6 @@ * Should be invoked when container size is changed

* Set default cursor
* @param {string} cursorStyle 例如 crosshair
* @param {string} [cursorStyle='default'] 例如 crosshair
*/
setDefaultCursorStyle: function (cursorStyle) {
this.handler.setDefaultCursorStyle(cursorStyle);
setCursorStyle: function (cursorStyle) {
this.handler && this.handler.setCursorStyle(cursorStyle);
},

@@ -299,0 +351,0 @@

{
"name": "zrender",
"version": "3.1.0",
"version": "3.1.1",
"description": "A lightweight canvas library.",

@@ -5,0 +5,0 @@ "keywords": [

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

var requestAnimationFrame = (typeof window !== 'undefined' &&
(window.requestAnimationFrame
|| window.msRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame))
|| function (func) {
setTimeout(func, 16);
};
var requestAnimationFrame = require('./requestAnimationFrame');

@@ -27,0 +20,0 @@ var Animator = require('./Animator');

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

// Start from next key
// PENDING start from lastFrame ?
start = Math.min(lastFrame + 1, trackLen - 1);

@@ -326,2 +327,3 @@ for (frame = start; frame >= 0; frame--) {

}
// PENDING really need to do this ?
frame = Math.min(frame, trackLen - 2);

@@ -328,0 +330,0 @@ }

@@ -53,2 +53,6 @@ define(function (require) {

var t = roots[i];
// Avoid winding error when intersection point is the connect point of two line of polygon
var unit = (t === 0 || t === 1) ? 0.5 : 1;
var x_ = curve.cubicAt(x0, x1, x2, x3, t);

@@ -71,9 +75,9 @@ if (x_ < x) { // Quick reject

if (t < extrema[0]) {
w += y0_ < y0 ? 1 : -1;
w += y0_ < y0 ? unit : -unit;
}
else if (t < extrema[1]) {
w += y1_ < y0_ ? 1 : -1;
w += y1_ < y0_ ? unit : -unit;
}
else {
w += y3 < y1_ ? 1 : -1;
w += y3 < y1_ ? unit : -unit;
}

@@ -84,6 +88,6 @@ }

if (t < extrema[0]) {
w += y0_ < y0 ? 1 : -1;
w += y0_ < y0 ? unit : -unit;
}
else {
w += y3 < y0_ ? 1 : -1;
w += y3 < y0_ ? unit : -unit;
}

@@ -114,2 +118,5 @@ }

for (var i = 0; i < nRoots; i++) {
// Remove one endpoint.
var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;
var x_ = curve.quadraticAt(x0, x1, x2, roots[i]);

@@ -120,6 +127,6 @@ if (x_ < x) { // Quick reject

if (roots[i] < t) {
w += y_ < y0 ? 1 : -1;
w += y_ < y0 ? unit : -unit;
}
else {
w += y2 < y_ ? 1 : -1;
w += y2 < y_ ? unit : -unit;
}

@@ -130,2 +137,5 @@ }

else {
// Remove one endpoint.
var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;
var x_ = curve.quadraticAt(x0, x1, x2, roots[0]);

@@ -135,3 +145,3 @@ if (x_ < x) { // Quick reject

}
return y2 < y0 ? 1 : -1;
return y2 < y0 ? unit : -unit;
}

@@ -222,5 +232,5 @@ }

// 如果被任何一个 subpath 包含
if (w !== 0) {
return true;
}
// if (w !== 0) {
// return true;
// }
}

@@ -352,3 +362,3 @@

|| containStroke(x1, y1, x0, y1, lineWidth, x, y)
|| containStroke(x0, y1, x1, y1, lineWidth, x, y)
|| containStroke(x0, y1, x0, y0, lineWidth, x, y)
) {

@@ -376,5 +386,6 @@ return true;

// 如果被任何一个 subpath 包含
if (w !== 0) {
return true;
}
// FIXME subpaths may overlap
// if (w !== 0) {
// return true;
// }
}

@@ -381,0 +392,0 @@ xi = x0;

@@ -6,2 +6,3 @@ define(function () {

}
// Ignore horizontal line
if (y1 === y0) {

@@ -12,2 +13,8 @@ return 0;

var t = (y - y0) / (y1 - y0);
// Avoid winding error when intersection point is the connect point of two line of polygon
if (t === 1 || t === 0) {
dir = y1 < y0 ? 0.5 : -0.5;
}
var x_ = t * (x1 - x0) + x0;

@@ -14,0 +21,0 @@

@@ -52,2 +52,4 @@ /**

isGroup: true,
/**

@@ -54,0 +56,0 @@ * @type {string}

@@ -33,19 +33,19 @@ /**

var browser = {};
var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
var touchpad = webos && ua.match(/TouchPad/);
var kindle = ua.match(/Kindle\/([\d.]+)/);
var silk = ua.match(/Silk\/([\d._]+)/);
var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
var playbook = ua.match(/PlayBook/);
var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
var firefox = ua.match(/Firefox\/([\d.]+)/);
var safari = webkit && ua.match(/Mobile\//) && !chrome;
var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
// var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
// var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
// var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
// var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
// var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
// var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
// var touchpad = webos && ua.match(/TouchPad/);
// var kindle = ua.match(/Kindle\/([\d.]+)/);
// var silk = ua.match(/Silk\/([\d._]+)/);
// var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
// var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
// var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
// var playbook = ua.match(/PlayBook/);
// var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
// var firefox = ua.match(/Firefox\/([\d.]+)/);
// var safari = webkit && ua.match(/Mobile\//) && !chrome;
// var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
var ie = ua.match(/MSIE\s([\d.]+)/)

@@ -62,30 +62,38 @@ // IE 11 Trident/7.0; rv:11.0

if (browser.webkit = !!webkit) browser.version = webkit[1];
// if (browser.webkit = !!webkit) browser.version = webkit[1];
if (android) os.android = true, os.version = android[2];
if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
if (webos) os.webos = true, os.version = webos[2];
if (touchpad) os.touchpad = true;
if (blackberry) os.blackberry = true, os.version = blackberry[2];
if (bb10) os.bb10 = true, os.version = bb10[2];
if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
if (playbook) browser.playbook = true;
if (kindle) os.kindle = true, os.version = kindle[1];
if (silk) browser.silk = true, browser.version = silk[1];
if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
if (chrome) browser.chrome = true, browser.version = chrome[1];
if (firefox) browser.firefox = true, browser.version = firefox[1];
if (ie) browser.ie = true, browser.version = ie[1];
if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
if (webview) browser.webview = true;
if (ie) browser.ie = true, browser.version = ie[1];
if (edge) browser.edge = true, browser.version = edge[1];
// if (android) os.android = true, os.version = android[2];
// if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
// if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
// if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
// if (webos) os.webos = true, os.version = webos[2];
// if (touchpad) os.touchpad = true;
// if (blackberry) os.blackberry = true, os.version = blackberry[2];
// if (bb10) os.bb10 = true, os.version = bb10[2];
// if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
// if (playbook) browser.playbook = true;
// if (kindle) os.kindle = true, os.version = kindle[1];
// if (silk) browser.silk = true, browser.version = silk[1];
// if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
// if (chrome) browser.chrome = true, browser.version = chrome[1];
// if (firefox) browser.firefox = true, browser.version = firefox[1];
// if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
// if (webview) browser.webview = true;
if (ie) {
browser.ie = true; browser.version = ie[1];
}
if (ie) {
browser.ie = true;
browser.version = ie[1];
}
if (edge) {
browser.edge = true;
browser.version = edge[1];
}
os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
(firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||
(chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
(firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));
// os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
// (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
// os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos ||
// (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
// (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));

@@ -92,0 +100,0 @@ return {

@@ -16,4 +16,14 @@ /**

// BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect
return el.getBoundingClientRect ? el.getBoundingClientRect() : { left: 0, top: 0};
return el.getBoundingClientRect ? el.getBoundingClientRect() : {left: 0, top: 0};
}
function clientToLocal(el, e, out) {
// clientX/clientY is according to view port.
var box = getBoundingClientRect(el);
out = out || {};
out.zrX = e.clientX - box.left;
out.zrY = e.clientY - box.top;
return out;
}
/**

@@ -34,5 +44,3 @@ * 如果存在第三方嵌入的一些dom触发的事件,或touch事件,需要转换一下事件坐标

if (!isTouch) {
var box = getBoundingClientRect(el);
e.zrX = e.clientX - box.left;
e.zrY = e.clientY - box.top;
clientToLocal(el, e, e);
e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;

@@ -42,10 +50,5 @@ }

var touch = eventType != 'touchend'
? e.targetTouches[0]
: e.changedTouches[0];
if (touch) {
var rBounding = getBoundingClientRect(el);
// touch事件坐标是全屏的~
e.zrX = touch.clientX - rBounding.left;
e.zrY = touch.clientY - rBounding.top;
}
? e.targetTouches[0]
: e.changedTouches[0];
touch && clientToLocal(el, touch, e);
}

@@ -92,2 +95,3 @@

return {
clientToLocal: clientToLocal,
normalizeEvent: normalizeEvent,

@@ -94,0 +98,0 @@ addEventListener: addEventListener,

@@ -8,2 +8,4 @@ /**

var eventUtil = require('./event');
var GestureMgr = function () {

@@ -22,4 +24,4 @@

recognize: function (event, target) {
this._doTrack(event, target);
recognize: function (event, target, root) {
this._doTrack(event, target, root);
return this._recognize(event);

@@ -33,3 +35,3 @@ },

_doTrack: function (event, target) {
_doTrack: function (event, target, root) {
var touches = event.touches;

@@ -50,3 +52,4 @@

var touch = touches[i];
trackItem.points.push([touch.clientX, touch.clientY]);
var pos = eventUtil.clientToLocal(root, touch);
trackItem.points.push([pos.zrX, pos.zrY]);
trackItem.touches.push(touch);

@@ -53,0 +56,0 @@ }

@@ -7,10 +7,8 @@ /**

define(
function() {
var idStart = 0x0907;
define(function() {
var idStart = 0x0907;
return function () {
return 'zr_' + (idStart++);
};
}
);
return function () {
return idStart++;
};
});

@@ -150,3 +150,3 @@ /**

// Force draw the first segment
|| this._len === 0;
|| this._len < 5;

@@ -427,3 +427,4 @@ this.addData(CMD.L, x, y);

while ((dx >= 0 && x <= x1) || (dx < 0 && x > x1)) {
while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1)
|| (dx == 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
idx = this._dashIdx;

@@ -435,3 +436,3 @@ dash = lineDash[idx];

// Skip positive offset
if ((dx > 0 && x < x0) || (dx < 0 && x > x0)) {
if ((dx > 0 && x < x0) || (dx < 0 && x > x0) || (dy > 0 && y < y0) || (dy < 0 && y > y0)) {
continue;

@@ -438,0 +439,0 @@ }

@@ -5,3 +5,3 @@ /**

define(function(require) {
var Gradient = require('../graphic/Gradient');
// 用于处理merge时无法遍历Date等对象的问题

@@ -13,3 +13,6 @@ var BUILTIN_OBJECT = {

'[object Error]': 1,
'[object CanvasGradient]': 1
'[object CanvasGradient]': 1,
'[object CanvasPattern]': 1,
// In node-canvas Image can be Canvas.Image
'[object Image]': 1
};

@@ -411,4 +414,3 @@

function isBuildInObject(value) {
return !!BUILTIN_OBJECT[objToString.call(value)]
|| (value instanceof Gradient);
return !!BUILTIN_OBJECT[objToString.call(value)];
}

@@ -415,0 +417,0 @@

@@ -22,4 +22,10 @@ define(function () {

var out = new ArrayCtor(2);
out[0] = x || 0;
out[1] = y || 0;
if (x == null) {
x = 0;
}
if (y == null) {
y = 0;
}
out[0] = x;
out[1] = y;
return out;

@@ -26,0 +32,0 @@ },

@@ -98,3 +98,3 @@ /**

this.decomposeTransform();
this.dirty();
this.dirty(false);
},

@@ -174,4 +174,5 @@

}
this.dirty();
this.dirty(false);
return this;

@@ -198,3 +199,3 @@ },

this.dirty();
this.dirty(false);
},

@@ -215,3 +216,3 @@

this.dirty();
this.dirty(false);
}

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

@@ -38,3 +38,3 @@ // CompoundPath to improve performance

for (var i = 0; i < paths.length; i++) {
paths[i].buildPath(ctx, paths[i].shape);
paths[i].buildPath(ctx, paths[i].shape, true);
}

@@ -41,0 +41,0 @@ },

@@ -141,2 +141,9 @@ /**

/**
* Render the element progressively when the value >= 0,
* usefull for large data.
* @type {number}
*/
progressive: -1,
beforeBrush: function (ctx) {},

@@ -151,3 +158,3 @@

// Interface
brush: function (ctx) {},
brush: function (ctx, prevEl) {},

@@ -154,0 +161,0 @@ /**

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

brush: function (ctx) {
brush: function (ctx, prevEl) {
var style = this.style;

@@ -37,2 +37,5 @@ var src = style.image;

// Must bind each time
style.bind(ctx, this, prevEl);
// style.image is a url string

@@ -97,6 +100,2 @@ if (typeof src === 'string') {

ctx.save();
style.bind(ctx);
// 设置transform

@@ -145,2 +144,4 @@ this.setTransform(ctx);

this.restoreTransform(ctx);
// Draw rect text

@@ -151,3 +152,2 @@ if (style.text != null) {

ctx.restore();
}

@@ -154,0 +154,0 @@ },

@@ -15,4 +15,5 @@ define(function(require) {

* @param {Array.<Object>} colorStops
* @param {boolean} [globalCoord=false]
*/
var LinearGradient = function (x, y, x2, y2, colorStops) {
var LinearGradient = function (x, y, x2, y2, colorStops, globalCoord) {
this.x = x == null ? 0 : x;

@@ -26,2 +27,8 @@

// Can be cloned
this.type = 'linear';
// If use global coord
this.global = globalCoord || false;
Gradient.call(this, colorStops);

@@ -32,5 +39,3 @@ };

constructor: LinearGradient,
type: 'linear'
constructor: LinearGradient
};

@@ -37,0 +42,0 @@

@@ -47,2 +47,6 @@ /**

}
// FIXME
ctx.save();
var x;

@@ -61,3 +65,2 @@ var y;

var transform = this.transform;
var invTransform = this.invTransform;
if (transform) {

@@ -67,4 +70,2 @@ tmpRect.copy(rect);

rect = tmpRect;
// Transform back
setTransform(ctx, invTransform);
}

@@ -106,4 +107,6 @@

ctx.textAlign = align;
ctx.textBaseline = baseline;
// Use canvas default left textAlign. Giving invalid value will cause state not change
ctx.textAlign = align || 'left';
// Use canvas default alphabetic baseline
ctx.textBaseline = baseline || 'alphabetic';

@@ -117,4 +120,5 @@ var textFill = style.textFill;

// Text shadow
ctx.shadowColor = style.textShadowColor;
// Always set shadowBlur and shadowOffset to avoid leak from displayable
ctx.shadowBlur = style.textShadowBlur;
ctx.shadowColor = style.textShadowColor || 'transparent';
ctx.shadowOffsetX = style.textShadowOffsetX;

@@ -130,4 +134,3 @@ ctx.shadowOffsetY = style.textShadowOffsetY;

// Transform again
transform && setTransform(ctx, transform);
ctx.restore();
}

@@ -134,0 +137,0 @@ };

@@ -13,14 +13,5 @@ /**

var Gradient = require('./Gradient');
var Pattern = require('./Pattern');
var getCanvasPattern = Pattern.prototype.getCanvasPattern;
function pathHasFill(style) {
var fill = style.fill;
return fill != null && fill !== 'none';
}
function pathHasStroke(style) {
var stroke = style.stroke;
return stroke != null && stroke !== 'none' && style.lineWidth > 0;
}
var abs = Math.abs;

@@ -54,32 +45,41 @@

brush: function (ctx) {
ctx.save();
brush: function (ctx, prevEl) {
var style = this.style;
var path = this.path;
var hasStroke = pathHasStroke(style);
var hasFill = pathHasFill(style);
var hasFillGradient = hasFill && !!(style.fill.colorStops);
var hasStrokeGradient = hasStroke && !!(style.stroke.colorStops);
var hasStroke = style.hasStroke();
var hasFill = style.hasFill();
var fill = style.fill;
var stroke = style.stroke;
var hasFillGradient = hasFill && !!(fill.colorStops);
var hasStrokeGradient = hasStroke && !!(stroke.colorStops);
var hasFillPattern = hasFill && !!(fill.image);
var hasStrokePattern = hasStroke && !!(stroke.image);
style.bind(ctx, this);
style.bind(ctx, this, prevEl);
this.setTransform(ctx);
if (this.__dirtyPath) {
if (this.__dirty) {
var rect = this.getBoundingRect();
// Update gradient because bounding rect may changed
if (hasFillGradient) {
this._fillGradient = style.getGradient(ctx, style.fill, rect);
this._fillGradient = style.getGradient(ctx, fill, rect);
}
if (hasStrokeGradient) {
this._strokeGradient = style.getGradient(ctx, style.stroke, rect);
this._strokeGradient = style.getGradient(ctx, stroke, rect);
}
}
// Use the gradient
// Use the gradient or pattern
if (hasFillGradient) {
// PENDING If may have affect the state
ctx.fillStyle = this._fillGradient;
}
else if (hasFillPattern) {
ctx.fillStyle = getCanvasPattern.call(fill, ctx);
}
if (hasStrokeGradient) {
ctx.strokeStyle = this._strokeGradient;
}
else if (hasStrokePattern) {
ctx.strokeStyle = getCanvasPattern.call(stroke, ctx);
}

@@ -111,3 +111,3 @@ var lineDash = style.lineDash;

this.buildPath(path, this.shape);
this.buildPath(path, this.shape, false);

@@ -132,12 +132,21 @@ // Clear path dirty flag

if (lineDash && ctxLineDash) {
// PENDING
// Remove lineDash
ctx.setLineDash([]);
}
this.restoreTransform(ctx);
// Draw rect text
if (style.text != null) {
if (style.text || style.text === 0) {
// var rect = this.getBoundingRect();
this.drawRectText(ctx, this.getBoundingRect());
}
ctx.restore();
},
buildPath: function (ctx, shapeCfg) {},
// When bundling path, some shape may decide if use moveTo to begin a new subpath or closePath
// Like in circle
buildPath: function (ctx, shapeCfg, inBundle) {},

@@ -152,3 +161,3 @@ getBoundingRect: function () {

path.beginPath();
this.buildPath(path, this.shape);
this.buildPath(path, this.shape, false);
}

@@ -159,3 +168,3 @@ rect = path.getBoundingRect();

if (pathHasStroke(style)) {
if (style.hasStroke()) {
// Needs update rect with stroke lineWidth when

@@ -173,3 +182,3 @@ // 1. Element changes scale or lineWidth

// Only add extra hover lineWidth when there are no fill
if (!pathHasFill(style)) {
if (!style.hasFill()) {
w = Math.max(w, this.strokeContainThreshold);

@@ -203,3 +212,3 @@ }

var pathData = this.path.data;
if (pathHasStroke(style)) {
if (style.hasStroke()) {
var lineWidth = style.lineWidth;

@@ -210,3 +219,3 @@ var lineScale = style.strokeNoScale ? this.getLineScale() : 1;

// Only add extra hover lineWidth when there are no fill
if (!pathHasFill(style)) {
if (!style.hasFill()) {
lineWidth = Math.max(lineWidth, this.strokeContainThreshold);

@@ -221,3 +230,3 @@ }

}
if (pathHasFill(style)) {
if (style.hasFill()) {
return pathContain.contain(pathData, x, y);

@@ -233,3 +242,3 @@ }

dirty: function (dirtyPath) {
if (arguments.length ===0) {
if (dirtyPath == null) {
dirtyPath = true;

@@ -266,2 +275,4 @@ }

this.setShape(value);
this.__dirtyPath = true;
this._rect = null;
}

@@ -268,0 +279,0 @@ else {

@@ -14,4 +14,5 @@ define(function(require) {

* @param {Array.<Object>} [colorStops]
* @param {boolean} [globalCoord=false]
*/
var RadialGradient = function (x, y, r, colorStops) {
var RadialGradient = function (x, y, r, colorStops, globalCoord) {
this.x = x == null ? 0.5 : x;

@@ -23,2 +24,8 @@

// Can be cloned
this.type = 'radial';
// If use global coord
this.global = globalCoord || false;
Gradient.call(this, colorStops);

@@ -29,5 +36,3 @@ };

constructor: RadialGradient,
type: 'radial'
constructor: RadialGradient
};

@@ -34,0 +39,0 @@

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

return require('../Path').extend({
type: 'circle',

@@ -20,9 +20,14 @@

buildPath : function (ctx, shape) {
buildPath : function (ctx, shape, inBundle) {
// Better stroking in ShapeBundle
ctx.moveTo(shape.cx + shape.r, shape.cy);
// Always do it may have performence issue ( fill may be 2x more cost)
if (inBundle) {
ctx.moveTo(shape.cx + shape.r, shape.cy);
}
// Better stroking in ShapeBundle
// ctx.moveTo(shape.cx + shape.r, shape.cy);
ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);
return;
}
});
});
/**
* @module zrender/graphic/Style
*/
define(function (require) {
var STYLE_LIST_COMMON = [
'lineCap', 'lineJoin', 'miterLimit',
'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'shadowColor'
var STYLE_COMMON_PROPS = [
['shadowBlur', 0], ['shadowOffsetX', 0], ['shadowOffsetY', 0], ['shadowColor', '#000'],
['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
];
// var SHADOW_PROPS = STYLE_COMMON_PROPS.slice(0, 4);
// var LINE_PROPS = STYLE_COMMON_PROPS.slice(4);
var Style = function (opts) {

@@ -16,2 +18,41 @@ this.extendFrom(opts);

function createLinearGradient(ctx, obj, rect) {
// var size =
var x = obj.x;
var x2 = obj.x2;
var y = obj.y;
var y2 = obj.y2;
if (!obj.global) {
x = x * rect.width + rect.x;
x2 = x2 * rect.width + rect.x;
y = y * rect.height + rect.y;
y2 = y2 * rect.height + rect.y;
}
var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
return canvasGradient;
}
function createRadialGradient(ctx, obj, rect) {
var width = rect.width;
var height = rect.height;
var min = Math.min(width, height);
var x = obj.x;
var y = obj.y;
var r = obj.r;
if (!obj.global) {
x = x * width + rect.x;
y = y * height + rect.y;
r = r * min;
}
var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
return canvasGradient;
}
Style.prototype = {

@@ -133,16 +174,40 @@

/**
* @type {string}
* https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
*/
blend: null,
/**
* @param {CanvasRenderingContext2D} ctx
*/
bind: function (ctx, el) {
var fill = this.fill;
var stroke = this.stroke;
for (var i = 0; i < STYLE_LIST_COMMON.length; i++) {
var styleName = STYLE_LIST_COMMON[i];
bind: function (ctx, el, prevEl) {
var style = this;
var prevStyle = prevEl && prevEl.style;
var firstDraw = !prevStyle;
if (this[styleName] != null) {
ctx[styleName] = this[styleName];
for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
var prop = STYLE_COMMON_PROPS[i];
var styleName = prop[0];
if (firstDraw || style[styleName] !== prevStyle[styleName]) {
// FIXME Invalid property value will cause style leak from previous element.
ctx[styleName] = style[styleName] || prop[1];
}
}
if (stroke != null) {
var lineWidth = this.lineWidth;
if ((firstDraw || style.fill !== prevStyle.fill)) {
ctx.fillStyle = style.fill;
}
if ((firstDraw || style.stroke !== prevStyle.stroke)) {
ctx.strokeStyle = style.stroke;
}
if ((firstDraw || style.opacity !== prevStyle.opacity)) {
ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
}
if ((firstDraw || style.blend !== prevStyle.blend)) {
ctx.globalCompositeOperation = style.blend || 'source-over';
}
if (this.hasStroke()) {
var lineWidth = style.lineWidth;
ctx.lineWidth = lineWidth / (

@@ -152,13 +217,14 @@ (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1

}
// Gradient will be created and set in Path#brush. So ignore it here
if (fill != null && fill !== 'none' && !fill.colorStops) {
ctx.fillStyle = fill;
}
if (stroke != null && stroke !== 'none' && !stroke.colorStops) {
// Use canvas gradient if has
ctx.strokeStyle = stroke;
}
this.opacity != null && (ctx.globalAlpha = this.opacity);
},
hasFill: function () {
var fill = this.fill;
return fill != null && fill !== 'none';
},
hasStroke: function () {
var stroke = this.stroke;
return stroke != null && stroke !== 'none' && this.lineWidth > 0;
},
/**

@@ -206,31 +272,5 @@ * Extend from other style

createLinearGradient: function (ctx, obj, rect) {
// var size =
var x = obj.x * rect.width + rect.x;
var x2 = obj.x2 * rect.width + rect.x;
var y = obj.y * rect.height + rect.y;
var y2 = obj.y2 * rect.height + rect.y;
var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
return canvasGradient;
},
createRadialGradient: function (ctx, obj, rect) {
var width = rect.width;
var height = rect.height;
var min = Math.min(width, height);
var x = obj.x * width + rect.x;
var y = obj.y * height + rect.y;
var r = obj.r * min;
var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
return canvasGradient;
},
getGradient: function (ctx, obj, rect) {
var method = obj.type === 'radial' ? 'createRadialGradient' : 'createLinearGradient';
var canvasGradient = this[method](ctx, obj, rect);
var method = obj.type === 'radial' ? createRadialGradient : createLinearGradient;
var canvasGradient = method(ctx, obj, rect);
var colorStops = obj.colorStops;

@@ -247,12 +287,13 @@ for (var i = 0; i < colorStops.length; i++) {

var styleProto = Style.prototype;
var name;
var i;
for (i = 0; i < STYLE_LIST_COMMON.length; i++) {
name = STYLE_LIST_COMMON[i];
if (!(name in styleProto)) {
styleProto[name] = null;
for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
var prop = STYLE_COMMON_PROPS[i];
if (!(prop[0] in styleProto)) {
styleProto[prop[0]] = prop[1];
}
}
// Provide for others
Style.getGradient = styleProto.getGradient;
return Style;
});

@@ -32,3 +32,3 @@ /**

brush: function (ctx) {
brush: function (ctx, prevEl) {
var style = this.style;

@@ -39,4 +39,2 @@ var x = style.x || 0;

var text = style.text;
var textFill = style.fill;
var textStroke = style.stroke;

@@ -46,14 +44,11 @@ // Convert to string

// Always bind style
style.bind(ctx, this, prevEl);
if (text) {
ctx.save();
this.style.bind(ctx);
this.setTransform(ctx);
textFill && (ctx.fillStyle = textFill);
textStroke && (ctx.strokeStyle = textStroke);
ctx.font = style.textFont || style.font;
ctx.textAlign = style.textAlign;
var textBaseline;
var textAlign = style.textAlign;
if (style.textVerticalAlign) {

@@ -64,3 +59,3 @@ var rect = textContain.getBoundingRect(

// Ignore textBaseline
ctx.textBaseline = 'middle';
textBaseline = 'middle';
switch (style.textVerticalAlign) {

@@ -78,4 +73,17 @@ case 'middle':

else {
ctx.textBaseline = style.textBaseline;
textBaseline = style.textBaseline;
}
ctx.font = style.textFont || style.font;
ctx.textAlign = textAlign || 'left';
// Use canvas default left textAlign. Giving invalid value will cause state not change
if (ctx.textAlign !== textAlign) {
ctx.textAlign = 'left';
}
ctx.textBaseline = textBaseline || 'alphabetic';
// Use canvas default alphabetic baseline
if (ctx.textBaseline !== textBaseline) {
ctx.textBaseline = 'alphabetic';
}
var lineHeight = textContain.measureText('国', ctx.font).width;

@@ -85,8 +93,8 @@

for (var i = 0; i < textLines.length; i++) {
textFill && ctx.fillText(textLines[i], x, y);
textStroke && ctx.strokeText(textLines[i], x, y);
style.hasFill() && ctx.fillText(textLines[i], x, y);
style.hasStroke() && ctx.strokeText(textLines[i], x, y);
y += lineHeight;
}
ctx.restore();
this.restoreTransform(ctx);
}

@@ -93,0 +101,0 @@ },

@@ -74,3 +74,3 @@ /**

this.root.style.cursor = hovered ? hovered.cursor : this._defaultCursorStyle;
this.root.style.cursor = hovered ? hovered.cursor : 'default';
// Mouse out on previous hovered element

@@ -225,3 +225,4 @@ if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {

event,
zrHandler.findHover(event.zrX, event.zrY, null)
zrHandler.findHover(event.zrX, event.zrY, null),
zrHandler.root
);

@@ -309,8 +310,2 @@

* @private
* @type {string}
*/
this._defaultCursorStyle = 'default';
/**
* @private
* @type {module:zrender/core/GestureMgr}

@@ -405,6 +400,6 @@ */

* 设置默认的cursor style
* @param {string} cursorStyle 例如 crosshair
* @param {string} [cursorStyle='default'] 例如 crosshair
*/
setDefaultCursorStyle: function (cursorStyle) {
this._defaultCursorStyle = cursorStyle;
setCursorStyle: function (cursorStyle) {
this.root.style.cursor = cursorStyle || 'default';
},

@@ -411,0 +406,0 @@

@@ -9,2 +9,4 @@ /**

var config = require('./config');
var Style = require('./graphic/Style');
var Pattern = require('./graphic/Pattern');

@@ -178,3 +180,3 @@ function returnFalse() {

var haveClearColor = this.clearColor;
var clearColor = this.clearColor;
var haveMotionBLur = this.motionBlur && !clearAll;

@@ -199,5 +201,22 @@ var lastFrameAlpha = this.lastFrameAlpha;

ctx.clearRect(0, 0, width / dpr, height / dpr);
if (haveClearColor) {
if (clearColor) {
var clearColorGradientOrPattern;
// Gradient
if (clearColor.colorStops) {
// Cache canvas gradient
clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
x: 0,
y: 0,
width: width / dpr,
height: height / dpr
});
clearColor.__canvasGradient = clearColorGradientOrPattern;
}
// Pattern
else if (clearColor.image) {
clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
}
ctx.save();
ctx.fillStyle = this.clearColor;
ctx.fillStyle = clearColorGradientOrPattern || clearColor;
ctx.fillRect(0, 0, width / dpr, height / dpr);

@@ -204,0 +223,0 @@ ctx.restore();

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

var arrySlice = Array.prototype.slice;
var zrUtil = require('../core/util');
var indexOf = zrUtil.indexOf;

@@ -45,4 +43,6 @@ /**

if (indexOf(_h[event], event) >= 0) {
return this;
for (var i = 0; i < _h[event].length; i++) {
if (_h[event][i].h === handler) {
return this;
}
}

@@ -76,2 +76,8 @@

for (var i = 0; i < _h[event].length; i++) {
if (_h[event][i].h === handler) {
return this;
}
}
_h[event].push({

@@ -78,0 +84,0 @@ h: handler,

@@ -150,2 +150,9 @@ /**

transformableProto.restoreTransform = function (ctx) {
var m = this.invTransform;
if (m) {
ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
}
}
var tmpTransform = [];

@@ -152,0 +159,0 @@

@@ -15,5 +15,14 @@ /**

var BoundingRect = require('./core/BoundingRect');
var timsort = require('./core/timsort');
var Layer = require('./Layer');
var requestAnimationFrame = require('./animation/requestAnimationFrame');
// PENDIGN
// Layer exceeds MAX_PROGRESSIVE_LAYER_NUMBER may have some problem when flush directly second time.
//
// Maximum progressive layer. When exceeding this number. All elements will be drawed in the last layer.
var MAX_PROGRESSIVE_LAYER_NUMBER = 5;
function parseInt10(val) {

@@ -46,3 +55,2 @@ return parseInt(val, 10);

function postProcessLayer(layer) {
layer.__dirty = false;
if (layer.__unusedCount == 1) {

@@ -66,2 +74,6 @@ layer.clear();

function isClipPathChanged(clipPaths, prevClipPaths) {
if (clipPaths == prevClipPaths) { // Can both be null or undefined
return false;
}
if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {

@@ -105,2 +117,14 @@ return true;

function createRoot(width, height) {
var domRoot = document.createElement('div');
var domRootStyle = domRoot.style;
// domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
domRootStyle.position = 'relative';
domRootStyle.overflow = 'hidden';
domRootStyle.width = width + 'px';
domRootStyle.height = height + 'px';
return domRoot;
}
/**

@@ -114,2 +138,3 @@ * @alias module:zrender/Painter

var Painter = function (root, storage, opts) {
// In node environment using node-canvas
var singleCanvas = !root.nodeName // In node ?

@@ -137,7 +162,6 @@ || root.nodeName.toUpperCase() === 'CANVAS';

// In node environment using node-canvas
if (rootStyle) {
rootStyle['-webkit-tap-highlight-color'] = 'transparent';
rootStyle['-webkit-user-select'] = 'none';
rootStyle['user-select'] = 'none';
rootStyle['-webkit-user-select'] =
rootStyle['user-select'] =
rootStyle['-webkit-touch-callout'] = 'none';

@@ -153,29 +177,28 @@

/**
* @type {Array.<number>}
* @private
*/
var zlevelList = this._zlevelList = [];
/**
* @type {Object.<string, module:zrender/Layer>}
* @private
*/
var layers = this._layers = {};
/**
* @type {Object.<string, Object>}
* @type {private}
*/
this._layerConfig = {};
if (!singleCanvas) {
var width = this._getWidth();
var height = this._getHeight();
this._width = width;
this._height = height;
this._width = this._getWidth();
this._height = this._getHeight();
var domRoot = document.createElement('div');
this._domRoot = domRoot;
var domRootStyle = domRoot.style;
// domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
domRootStyle.position = 'relative';
domRootStyle.overflow = 'hidden';
domRootStyle.width = this._width + 'px';
domRootStyle.height = this._height + 'px';
var domRoot = this._domRoot = createRoot(
this._width, this._height
);
root.appendChild(domRoot);
/**
* @type {Object.<key, module:zrender/Layer>}
* @private
*/
this._layers = {};
/**
* @type {Array.<number>}
* @private
*/
this._zlevelList = [];
}

@@ -195,11 +218,18 @@ else {

// mainLayer.resize(width, height);
this._layers = {
0: mainLayer
};
this._zlevelList = [0];
layers[0] = mainLayer;
zlevelList.push(0);
}
this._layerConfig = {};
this.pathToImage = this._createPathToImage();
this.pathToImage = this._createPathToImage();
// Layers for progressive rendering
this._progressiveLayers = [];
/**
* @type {module:zrender/Layer}
* @private
*/
this._hoverlayer;
this._hoverElements = [];
};

@@ -230,3 +260,5 @@

refresh: function (paintAll) {
var list = this.storage.getDisplayList(true);
var zlevelList = this._zlevelList;

@@ -245,5 +277,130 @@

this.refreshHover();
if (this._progressiveLayers.length) {
this._startProgessive();
}
return this;
},
addHover: function (el, hoverStyle) {
if (el.__hoverMir) {
return;
}
var elMirror = new el.constructor({
style: el.style,
shape: el.shape
});
elMirror.__from = el;
el.__hoverMir = elMirror;
elMirror.setStyle(hoverStyle);
this._hoverElements.push(elMirror);
},
removeHover: function (el) {
var elMirror = el.__hoverMir;
var hoverElements = this._hoverElements;
var idx = util.indexOf(hoverElements, elMirror);
if (idx >= 0) {
hoverElements.splice(idx, 1);
}
el.__hoverMir = null;
},
clearHover: function (el) {
var hoverElements = this._hoverElements;
for (var i = 0; i < hoverElements.length; i++) {
var from = hoverElements[i].__from;
if (from) {
from.__hoverMir = null;
}
}
hoverElements.length = 0;
},
refreshHover: function () {
var hoverElements = this._hoverElements;
var len = hoverElements.length;
var hoverLayer = this._hoverlayer;
hoverLayer && hoverLayer.clear();
if (!len) {
return;
}
timsort(hoverElements, this.storage.displayableSortFunc);
// Use a extream large zlevel
// FIXME?
if (!hoverLayer) {
hoverLayer = this._hoverlayer = this.getLayer(1e5);
}
var scope = {};
hoverLayer.ctx.save();
for (var i = 0; i < len;) {
var el = hoverElements[i];
var originalEl = el.__from;
// Original el is removed
// PENDING
if (!(originalEl && originalEl.__zr)) {
hoverElements.splice(i, 1);
originalEl.__hoverMir = null;
len--;
continue;
}
i++;
// Use transform
// FIXME style and shape ?
if (!originalEl.invisible) {
el.transform = originalEl.transform;
el.invTransform = originalEl.invTransform;
el.__clipPaths = originalEl.__clipPaths;
// el.
this._doPaintEl(el, hoverLayer, true, scope);
}
}
hoverLayer.ctx.restore();
},
_startProgessive: function () {
var self = this;
if (!self._furtherProgressive) {
return;
}
// Use a token to stop progress steps triggered by
// previous zr.refresh calling.
var token = self._progressiveToken = +new Date();
self._progress++;
requestAnimationFrame(step);
function step() {
// In case refreshed or disposed
if (token === self._progressiveToken && self.storage) {
self._doPaintList(self.storage.getDisplayList());
if (self._furtherProgressive) {
self._progress++;
requestAnimationFrame(step);
}
else {
self._progressiveToken = -1;
}
}
}
},
_clearProgressive: function () {
this._progressiveToken = -1;
this._progress = 0;
util.each(this._progressiveLayers, function (layer) {
layer.__dirty && layer.clear();
});
},
_paintList: function (list, paintAll) {

@@ -257,2 +414,12 @@

this._clearProgressive();
this.eachBuildinLayer(preProcessLayer);
this._doPaintList(list, paintAll);
this.eachBuildinLayer(postProcessLayer);
},
_doPaintList: function (list, paintAll) {
var currentLayer;

@@ -262,15 +429,46 @@ var currentZLevel;

var viewWidth = this._width;
var viewHeight = this._height;
// var invTransform = [];
var scope;
this.eachBuildinLayer(preProcessLayer);
var progressiveLayerIdx = 0;
var currentProgressiveLayer;
// var invTransform = [];
var prevElClipPaths = null;
var width = this._width;
var height = this._height;
var layerProgress;
var frame = this._progress;
function flushProgressiveLayer(layer) {
ctx.save();
ctx.globalAlpha = 1;
ctx.shadowBlur = 0;
// Avoid layer don't clear in next progressive frame
currentLayer.__dirty = true;
ctx.drawImage(layer.dom, 0, 0, width, height);
ctx.restore();
currentLayer.ctx.restore();
}
for (var i = 0, l = list.length; i < l; i++) {
var el = list[i];
var elZLevel = this._singleCanvas ? 0 : el.zlevel;
var elFrame = el.__frame;
// Flush at current context
// PENDING
if (elFrame < 0 && currentProgressiveLayer) {
flushProgressiveLayer(currentProgressiveLayer);
currentProgressiveLayer = null;
}
// Change draw layer
if (currentZLevel !== elZLevel) {
if (ctx) {
ctx.restore();
}
// Reset scope
scope = {};
// Only 0 zlevel if only has one canvas

@@ -288,2 +486,3 @@ currentZLevel = elZLevel;

ctx = currentLayer.ctx;
ctx.save();

@@ -298,33 +497,43 @@ // Reset the count

if (
(currentLayer.__dirty || paintAll)
// Ignore invisible element
&& !el.invisible
// Ignore transparent element
&& el.style.opacity !== 0
// Ignore scale 0 element, in some environment like node-canvas
// Draw a scale 0 element can cause all following draw wrong
&& el.scale[0] && el.scale[1]
// Ignore culled element
&& !(el.culling && isDisplayableCulled(el, viewWidth, viewHeight))
) {
var clipPaths = el.__clipPaths;
if (!(currentLayer.__dirty || paintAll)) {
continue;
}
if (elFrame >= 0) {
// Progressive layer changed
if (!currentProgressiveLayer) {
currentProgressiveLayer = this._progressiveLayers[
Math.min(progressiveLayerIdx++, MAX_PROGRESSIVE_LAYER_NUMBER - 1)
];
// Optimize when clipping on group with several elements
if (isClipPathChanged(clipPaths, prevElClipPaths)) {
// If has previous clipping state, restore from it
if (prevElClipPaths) {
ctx.restore();
currentProgressiveLayer.ctx.save();
currentProgressiveLayer.renderScope = {};
if (currentProgressiveLayer
&& (currentProgressiveLayer.__progress > currentProgressiveLayer.__maxProgress)
) {
// flushProgressiveLayer(currentProgressiveLayer);
// Quick jump all progressive elements
// All progressive element are not dirty, jump over and flush directly
i = currentProgressiveLayer.__nextIdxNotProg - 1;
// currentProgressiveLayer = null;
continue;
}
// New clipping state
if (clipPaths) {
ctx.save();
doClip(clipPaths, ctx);
layerProgress = currentProgressiveLayer.__progress;
if (!currentProgressiveLayer.__dirty) {
// Keep rendering
frame = layerProgress;
}
prevElClipPaths = clipPaths;
currentProgressiveLayer.__progress = frame + 1;
}
el.beforeBrush && el.beforeBrush(ctx);
el.brush(ctx, false);
el.afterBrush && el.afterBrush(ctx);
if (elFrame === frame) {
this._doPaintEl(el, currentProgressiveLayer, true, currentProgressiveLayer.renderScope);
}
}
else {
this._doPaintEl(el, currentLayer, paintAll, scope);
}

@@ -334,10 +543,68 @@ el.__dirty = false;

// If still has clipping state
if (prevElClipPaths) {
ctx.restore();
if (currentProgressiveLayer) {
flushProgressiveLayer(currentProgressiveLayer);
}
this.eachBuildinLayer(postProcessLayer);
// Restore the lastLayer ctx
ctx && ctx.restore();
// If still has clipping state
// if (scope.prevElClipPaths) {
// ctx.restore();
// }
this._furtherProgressive = false;
util.each(this._progressiveLayers, function (layer) {
if (layer.__maxProgress >= layer.__progress) {
this._furtherProgressive = true;
}
}, this);
},
_doPaintEl: function (el, currentLayer, forcePaint, scope) {
var ctx = currentLayer.ctx;
if (
(currentLayer.__dirty || forcePaint)
// Ignore invisible element
&& !el.invisible
// Ignore transparent element
&& el.style.opacity !== 0
// Ignore scale 0 element, in some environment like node-canvas
// Draw a scale 0 element can cause all following draw wrong
&& el.scale[0] && el.scale[1]
// Ignore culled element
&& !(el.culling && isDisplayableCulled(el, this._width, this._height))
) {
var clipPaths = el.__clipPaths;
// Optimize when clipping on group with several elements
if (scope.prevClipLayer !== currentLayer
|| isClipPathChanged(clipPaths, scope.prevElClipPaths)
) {
// If has previous clipping state, restore from it
if (scope.prevElClipPaths) {
scope.prevClipLayer.ctx.restore();
scope.prevClipLayer = scope.prevElClipPaths = null;
// Reset prevEl since context has been restored
scope.prevEl = null;
}
// New clipping state
if (clipPaths) {
ctx.save();
doClip(clipPaths, ctx);
scope.prevClipLayer = currentLayer;
scope.prevElClipPaths = clipPaths;
}
}
el.beforeBrush && el.beforeBrush(ctx);
el.brush(ctx, scope.prevEl || null);
scope.prevEl = el;
el.afterBrush && el.afterBrush(ctx);
}
},
/**

@@ -481,10 +748,23 @@ * 获取 zlevel 所在层,如果不存在则会创建一个新的层

var layers = this._layers;
var progressiveLayers = this._progressiveLayers;
var elCounts = {};
var elCountsLastFrame = {};
var progressiveElCountsLastFrame = {};
this.eachBuildinLayer(function (layer, z) {
elCounts[z] = layer.elCount;
elCountsLastFrame[z] = layer.elCount;
layer.elCount = 0;
layer.__dirty = false;
});
util.each(progressiveLayers, function (layer, idx) {
progressiveElCountsLastFrame[idx] = layer.elCount;
layer.elCount = 0;
layer.__dirty = false;
});
var progressiveLayerCount = 0;
var currentProgressiveLayer;
var lastProgressiveKey;
var frameCount = 0;
for (var i = 0, l = list.length; i < l; i++) {

@@ -494,18 +774,71 @@ var el = list[i];

var layer = layers[zlevel];
var elProgress = el.progressive;
if (layer) {
layer.elCount++;
// 已经被标记为需要刷新
if (layer.__dirty) {
continue;
layer.__dirty = layer.__dirty || el.__dirty;
}
/////// Update progressive
if (elProgress >= 0) {
// Fix wrong progressive sequence problem.
if (lastProgressiveKey !== elProgress) {
lastProgressiveKey = elProgress;
frameCount++;
}
layer.__dirty = el.__dirty;
var elFrame = el.__frame = frameCount - 1;
if (!currentProgressiveLayer) {
var idx = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER - 1);
currentProgressiveLayer = progressiveLayers[idx];
if (!currentProgressiveLayer) {
currentProgressiveLayer = progressiveLayers[idx] = new Layer(
'progressive', this, this.dpr
);
currentProgressiveLayer.initContext();
}
currentProgressiveLayer.__maxProgress = 0;
}
currentProgressiveLayer.__dirty = currentProgressiveLayer.__dirty || el.__dirty;
currentProgressiveLayer.elCount++;
currentProgressiveLayer.__maxProgress = Math.max(
currentProgressiveLayer.__maxProgress, elFrame
);
if (currentProgressiveLayer.__maxProgress >= currentProgressiveLayer.__progress) {
// Should keep rendering this layer because progressive rendering is not finished yet
layer.__dirty = true;
}
}
else {
el.__frame = -1;
if (currentProgressiveLayer) {
currentProgressiveLayer.__nextIdxNotProg = i;
progressiveLayerCount++;
currentProgressiveLayer = null;
}
}
}
if (currentProgressiveLayer) {
progressiveLayerCount++;
currentProgressiveLayer.__nextIdxNotProg = i;
}
// 层中的元素数量有发生变化
this.eachBuildinLayer(function (layer, z) {
if (elCounts[z] !== layer.elCount) {
if (elCountsLastFrame[z] !== layer.elCount) {
layer.__dirty = true;
}
});
progressiveLayers.length = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER);
util.each(progressiveLayers, function (layer, idx) {
if (progressiveElCountsLastFrame[idx] !== layer.elCount) {
el.__dirty = true;
}
if (layer.__dirty) {
layer.__progress = 0;
}
});
},

@@ -639,3 +972,2 @@

var ctx = imageLayer.ctx;
imageLayer.clearColor = opts.backgroundColor;

@@ -646,10 +978,6 @@ imageLayer.clear();

var scope = {};
for (var i = 0; i < displayList.length; i++) {
var el = displayList[i];
if (!el.invisible) {
el.beforeBrush && el.beforeBrush(ctx);
// TODO Check image cross origin
el.brush(ctx, false);
el.afterBrush && el.afterBrush(ctx);
}
this._doPaintEl(el, imageLayer, true, scope);
}

@@ -656,0 +984,0 @@

@@ -13,11 +13,19 @@ /**

var util = require('./core/util');
var env = require('./core/env');
var Group = require('./container/Group');
// Use timsort because in most case elements are partially sorted
// https://jsfiddle.net/pissang/jr4x7mdm/8/
var timsort = require('./core/timsort');
function shapeCompareFunc(a, b) {
if (a.zlevel === b.zlevel) {
if (a.z === b.z) {
if (a.z2 === b.z2) {
return a.__renderidx - b.__renderidx;
}
// if (a.z2 === b.z2) {
// // FIXME Slow has renderidx compare
// // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement
// // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012
// return a.__renderidx - b.__renderidx;
// }
return a.z2 - b.z2;

@@ -50,2 +58,12 @@ }

/**
* @param {Function} cb
*
*/
traverse: function (cb, context) {
for (var i = 0; i < this._roots.length; i++) {
this._roots[i].traverse(cb, context);
}
},
/**
* 返回所有图形的绘制队列

@@ -81,7 +99,8 @@ * @param {boolean} [update=false] 是否在返回前更新该数组

for (var i = 0, len = displayList.length; i < len; i++) {
displayList[i].__renderidx = i;
}
// for (var i = 0, len = displayList.length; i < len; i++) {
// displayList[i].__renderidx = i;
// }
displayList.sort(shapeCompareFunc);
// displayList.sort(shapeCompareFunc);
env.canvasSupported && timsort(displayList, shapeCompareFunc);
},

@@ -97,4 +116,8 @@

el.update();
if (el.__dirty) {
el.update();
}
el.afterUpdate();

@@ -118,3 +141,3 @@

if (el.type == 'group') {
if (el.isGroup) {
var children = el._children;

@@ -127,3 +150,5 @@

// FIXME __dirtyPath ?
child.__dirty = el.__dirty || child.__dirty;
if (el.__dirty) {
child.__dirty = true;
}

@@ -244,3 +269,5 @@ this._updateAndAddDisplayable(child, clipPaths, includeIgnore);

this._roots = null;
}
},
displayableSortFunc: shapeCompareFunc
};

@@ -247,0 +274,0 @@

@@ -459,6 +459,7 @@ /**

function stringify(arrColor, type) {
if (type === 'rgb' || type === 'hsv' || type === 'hsl') {
arrColor = arrColor.slice(0, 3);
var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
colorStr += ',' + arrColor[3];
}
return type + '(' + arrColor.join(',') + ')';
return type + '(' + colorStr + ')';
}

@@ -465,0 +466,0 @@

@@ -381,8 +381,6 @@ define(function (require) {

var len = pathEls.length;
var pathEl;
var i;
for (i = 0; i < len; i++) {
pathEl = pathEls[i];
for (var i = 0; i < len; i++) {
var pathEl = pathEls[i];
if (pathEl.__dirty) {
pathEl.buildPath(pathEl.path, pathEl.shape);
pathEl.buildPath(pathEl.path, pathEl.shape, true);
}

@@ -389,0 +387,0 @@ pathList.push(pathEl.path);

@@ -217,11 +217,11 @@ // http://www.w3.org/TR/NOTE-VML

var updateStrokeNode = function (el, style) {
if (style.lineJoin != null) {
el.joinstyle = style.lineJoin;
}
if (style.miterLimit != null) {
el.miterlimit = style.miterLimit * Z;
}
if (style.lineCap != null) {
el.endcap = style.lineCap;
}
// if (style.lineJoin != null) {
// el.joinstyle = style.lineJoin;
// }
// if (style.miterLimit != null) {
// el.miterlimit = style.miterLimit * Z;
// }
// if (style.lineCap != null) {
// el.endcap = style.lineCap;
// }
if (style.lineDash != null) {

@@ -836,2 +836,3 @@ el.dashstyle = style.lineDash.join(' ');

+ fontStyle.size + 'px "' + fontStyle.family + '"';
var baseline = style.textBaseline;

@@ -838,0 +839,0 @@ var verticalAlign = style.textVerticalAlign;

@@ -151,2 +151,6 @@ /**

clear: function () {
this.root.removeChild(this.vmlViewport);
},
_getWidth: function () {

@@ -153,0 +157,0 @@ var root = this.root;

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

*/
zrender.version = '3.1.0';
zrender.version = '3.1.1';

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

}
if (self._needsRefreshHover) {
self.refreshHoverImmediately();
}
}

@@ -184,3 +187,3 @@ }

* 添加元素
* @param {string|module:zrender/Element} el
* @param {module:zrender/Element} el
*/

@@ -194,3 +197,3 @@ add: function (el) {

* 删除元素
* @param {string|module:zrender/Element} el
* @param {module:zrender/Element} el
*/

@@ -237,2 +240,51 @@ remove: function (el) {

/**
* Add element to hover layer
* @param {module:zrender/Element} el
* @param {Object} style
*/
addHover: function (el, style) {
if (this.painter.addHover) {
this.painter.addHover(el, style);
this.refreshHover();
}
},
/**
* Add element from hover layer
* @param {module:zrender/Element} el
*/
removeHover: function (el) {
if (this.painter.removeHover) {
this.painter.removeHover(el);
this.refreshHover();
}
},
/**
* Clear all hover elements in hover layer
* @param {module:zrender/Element} el
*/
clearHover: function () {
if (this.painter.clearHover) {
this.painter.clearHover();
this.refreshHover();
}
},
/**
* Refresh hover in next frame
*/
refreshHover: function () {
this._needsRefreshHover = true;
},
/**
* Refresh hover immediately
*/
refreshHoverImmediately: function () {
this._needsRefreshHover = false;
this.painter.refreshHover && this.painter.refreshHover();
},
/**
* Resize the canvas.

@@ -293,6 +345,6 @@ * Should be invoked when container size is changed

* Set default cursor
* @param {string} cursorStyle 例如 crosshair
* @param {string} [cursorStyle='default'] 例如 crosshair
*/
setDefaultCursorStyle: function (cursorStyle) {
this.handler.setDefaultCursorStyle(cursorStyle);
setCursorStyle: function (cursorStyle) {
this.handler && this.handler.setCursorStyle(cursorStyle);
},

@@ -299,0 +351,0 @@

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