mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 10:45:21 +08:00
cache patterns and gradients
This commit is contained in:
parent
1b6238cbb2
commit
99e66c380f
@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
* A bit changed behavior of `removeId` (private method), now it doesn't clear node ref, if object is changed.
|
||||
* simplified `batchDraw` method (it doesn't use `Konva.Animation`) now.
|
||||
* `id` and `name` properties defaults are empty strings, not `undefined`
|
||||
* Performance improvements for shapes will image patterns, linear and radial fills
|
||||
|
||||
### Removed
|
||||
* `Konva.Util.addMethods`
|
||||
|
108
konva.js
108
konva.js
@ -8,7 +8,7 @@
|
||||
* Konva JavaScript Framework v3.0.0-0
|
||||
* http://konvajs.github.io/
|
||||
* Licensed under the MIT
|
||||
* Date: Mon Feb 11 2019
|
||||
* Date: Wed Feb 13 2019
|
||||
*
|
||||
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
||||
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
|
||||
@ -1769,29 +1769,22 @@
|
||||
if (fillPatternOffsetX || fillPatternOffsetY) {
|
||||
this.translate(-1 * fillPatternOffsetX, -1 * fillPatternOffsetY);
|
||||
}
|
||||
// TODO: cache pattern
|
||||
this.setAttr('fillStyle', this.createPattern(shape.getFillPatternImage(), shape.getFillPatternRepeat() || 'repeat'));
|
||||
this.setAttr('fillStyle', shape._getFillPattern());
|
||||
shape._fillFunc(this);
|
||||
};
|
||||
SceneContext.prototype._fillLinearGradient = function (shape) {
|
||||
var start = shape.getFillLinearGradientStartPoint(), end = shape.getFillLinearGradientEndPoint(), colorStops = shape.getFillLinearGradientColorStops(), grd = this.createLinearGradient(start.x, start.y, end.x, end.y);
|
||||
if (colorStops) {
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
}
|
||||
var grd = shape._getLinearGradient();
|
||||
if (grd) {
|
||||
this.setAttr('fillStyle', grd);
|
||||
shape._fillFunc(this);
|
||||
}
|
||||
};
|
||||
SceneContext.prototype._fillRadialGradient = function (shape) {
|
||||
var start = shape.getFillRadialGradientStartPoint(), end = shape.getFillRadialGradientEndPoint(), startRadius = shape.getFillRadialGradientStartRadius(), endRadius = shape.getFillRadialGradientEndRadius(), colorStops = shape.getFillRadialGradientColorStops(), grd = this.createRadialGradient(start.x, start.y, startRadius, end.x, end.y, endRadius);
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
var grd = shape._getRadialGradient();
|
||||
if (grd) {
|
||||
this.setAttr('fillStyle', grd);
|
||||
shape._fillFunc(this);
|
||||
}
|
||||
this.setAttr('fillStyle', grd);
|
||||
shape._fillFunc(this);
|
||||
};
|
||||
SceneContext.prototype._fill = function (shape) {
|
||||
var hasColor = shape.fill(), fillPriority = shape.getFillPriority();
|
||||
@ -6808,7 +6801,17 @@
|
||||
|
||||
var HAS_SHADOW = 'hasShadow';
|
||||
var SHADOW_RGBA = 'shadowRGBA';
|
||||
// TODO: cache gradient from context
|
||||
var patternImage = 'patternImage';
|
||||
var linearGradient = 'linearGradient';
|
||||
var radialGradient = 'radialGradient';
|
||||
var dummyContext;
|
||||
function getDummyContext() {
|
||||
if (dummyContext) {
|
||||
return dummyContext;
|
||||
}
|
||||
dummyContext = Util.createCanvasElement().getContext('2d');
|
||||
return dummyContext;
|
||||
}
|
||||
// TODO: write a test for adding destroyed shape into the layer
|
||||
// will it draw?
|
||||
// will it pass hit test?
|
||||
@ -6836,6 +6839,15 @@
|
||||
function _clearGetShadowRGBACache() {
|
||||
this._clearCache(SHADOW_RGBA);
|
||||
}
|
||||
function _clearFillPatternCache() {
|
||||
this._clearCache(patternImage);
|
||||
}
|
||||
function _clearLinearGradientCache() {
|
||||
this._clearCache(linearGradient);
|
||||
}
|
||||
function _clearRadialGradientCache() {
|
||||
this._clearCache(radialGradient);
|
||||
}
|
||||
/**
|
||||
* Shape constructor. Shapes are primitive objects such as rectangles,
|
||||
* circles, text, lines, etc.
|
||||
@ -6947,6 +6959,9 @@
|
||||
shapes[key] = _this;
|
||||
_this.on('shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearHasShadowCache);
|
||||
_this.on('shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearGetShadowRGBACache);
|
||||
_this.on('fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva', _clearFillPatternCache);
|
||||
_this.on('fillPriorityChange.konva fillLinearGradientColorStopsChange.konva fillLinearGradientStartPointXChange.konva fillLinearGradientStartPointYChange.konva fillLinearGradientEndPointXChange.konva fillLinearGradientEndPointYChange.konva', _clearLinearGradientCache);
|
||||
_this.on('fillPriorityChange.konva fillRadialGradientColorStopsChange.konva fillRadialGradientStartPointXChange.konva fillRadialGradientStartPointYChange.konva fillRadialGradientEndPointXChange.konva fillRadialGradientEndPointYChange.konva fillRadialGradientStartRadiusChange.konva fillRadialGradientEndRadiusChange.konva', _clearRadialGradientCache);
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
@ -6987,6 +7002,49 @@
|
||||
this.shadowOffsetX() ||
|
||||
this.shadowOffsetY())));
|
||||
};
|
||||
Shape.prototype._getFillPattern = function () {
|
||||
return this._getCache(patternImage, this.__getFillPattern);
|
||||
};
|
||||
Shape.prototype.__getFillPattern = function () {
|
||||
if (this.fillPatternImage()) {
|
||||
var ctx = getDummyContext();
|
||||
return ctx.createPattern(this.fillPatternImage(), this.fillPatternRepeat() || 'repeat');
|
||||
}
|
||||
};
|
||||
Shape.prototype._getLinearGradient = function () {
|
||||
return this._getCache(linearGradient, this.__getLinearGradient);
|
||||
};
|
||||
Shape.prototype.__getLinearGradient = function () {
|
||||
var colorStops = this.fillLinearGradientColorStops();
|
||||
if (colorStops) {
|
||||
var ctx = getDummyContext();
|
||||
var start = this.fillLinearGradientStartPoint();
|
||||
var end = this.fillLinearGradientEndPoint();
|
||||
var grd = ctx.createLinearGradient(start.x, start.y, end.x, end.y);
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
}
|
||||
return grd;
|
||||
}
|
||||
};
|
||||
Shape.prototype._getRadialGradient = function () {
|
||||
return this._getCache(radialGradient, this.__getRadialGradient);
|
||||
};
|
||||
Shape.prototype.__getRadialGradient = function () {
|
||||
var colorStops = this.fillRadialGradientColorStops();
|
||||
if (colorStops) {
|
||||
var ctx = getDummyContext();
|
||||
var start = this.fillRadialGradientStartPoint();
|
||||
var end = this.fillRadialGradientEndPoint();
|
||||
var grd = ctx.createRadialGradient(start.x, start.y, this.fillRadialGradientStartRadius(), end.x, end.y, this.fillRadialGradientEndRadius());
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
}
|
||||
return grd;
|
||||
}
|
||||
};
|
||||
Shape.prototype.getShadowRGBA = function () {
|
||||
return this._getCache(SHADOW_RGBA, this._getShadowRGBA);
|
||||
};
|
||||
@ -12300,13 +12358,13 @@
|
||||
],
|
||||
// cached variables
|
||||
attrChangeListLen$1 = ATTR_CHANGE_LIST$1.length;
|
||||
var dummyContext;
|
||||
function getDummyContext() {
|
||||
if (dummyContext) {
|
||||
return dummyContext;
|
||||
var dummyContext$1;
|
||||
function getDummyContext$1() {
|
||||
if (dummyContext$1) {
|
||||
return dummyContext$1;
|
||||
}
|
||||
dummyContext = Util.createCanvasElement().getContext(CONTEXT_2D);
|
||||
return dummyContext;
|
||||
dummyContext$1 = Util.createCanvasElement().getContext(CONTEXT_2D);
|
||||
return dummyContext$1;
|
||||
}
|
||||
function _fillFunc$1(context) {
|
||||
context.fillText(this.partialText, 0, 0);
|
||||
@ -12565,7 +12623,7 @@
|
||||
};
|
||||
// TODO: make it public, rename to "measure text"?
|
||||
Text.prototype._getTextSize = function (text) {
|
||||
var _context = getDummyContext(), fontSize = this.fontSize(), metrics;
|
||||
var _context = getDummyContext$1(), fontSize = this.fontSize(), metrics;
|
||||
_context.save();
|
||||
_context.font = this._getContextFont();
|
||||
metrics = _context.measureText(text);
|
||||
@ -12605,7 +12663,7 @@
|
||||
Text.prototype._getTextWidth = function (text) {
|
||||
var letterSpacing = this.letterSpacing();
|
||||
var length = text.length;
|
||||
return (getDummyContext().measureText(text).width +
|
||||
return (getDummyContext$1().measureText(text).width +
|
||||
(length ? letterSpacing * (length - 1) : 0));
|
||||
};
|
||||
Text.prototype._setTextData = function () {
|
||||
@ -12613,7 +12671,7 @@
|
||||
// align = this.align(),
|
||||
shouldWrap = wrap !== NONE$1, wrapAtWord = wrap !== CHAR && shouldWrap, shouldAddEllipsis = this.ellipsis() && !shouldWrap;
|
||||
this.textArr = [];
|
||||
getDummyContext().font = this._getContextFont();
|
||||
getDummyContext$1().font = this._getContextFont();
|
||||
var additionalWidth = shouldAddEllipsis ? this._getTextWidth(ELLIPSIS) : 0;
|
||||
for (var i = 0, max = lines.length; i < max; ++i) {
|
||||
var line = lines[i];
|
||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@ -496,52 +496,23 @@ export class SceneContext extends Context {
|
||||
this.translate(-1 * fillPatternOffsetX, -1 * fillPatternOffsetY);
|
||||
}
|
||||
|
||||
// TODO: cache pattern
|
||||
this.setAttr(
|
||||
'fillStyle',
|
||||
this.createPattern(
|
||||
shape.getFillPatternImage(),
|
||||
shape.getFillPatternRepeat() || 'repeat'
|
||||
)
|
||||
);
|
||||
this.setAttr('fillStyle', shape._getFillPattern());
|
||||
shape._fillFunc(this);
|
||||
}
|
||||
_fillLinearGradient(shape) {
|
||||
var start = shape.getFillLinearGradientStartPoint(),
|
||||
end = shape.getFillLinearGradientEndPoint(),
|
||||
colorStops = shape.getFillLinearGradientColorStops(),
|
||||
grd = this.createLinearGradient(start.x, start.y, end.x, end.y);
|
||||
var grd = shape._getLinearGradient();
|
||||
|
||||
if (colorStops) {
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
}
|
||||
if (grd) {
|
||||
this.setAttr('fillStyle', grd);
|
||||
shape._fillFunc(this);
|
||||
}
|
||||
}
|
||||
_fillRadialGradient(shape) {
|
||||
var start = shape.getFillRadialGradientStartPoint(),
|
||||
end = shape.getFillRadialGradientEndPoint(),
|
||||
startRadius = shape.getFillRadialGradientStartRadius(),
|
||||
endRadius = shape.getFillRadialGradientEndRadius(),
|
||||
colorStops = shape.getFillRadialGradientColorStops(),
|
||||
grd = this.createRadialGradient(
|
||||
start.x,
|
||||
start.y,
|
||||
startRadius,
|
||||
end.x,
|
||||
end.y,
|
||||
endRadius
|
||||
);
|
||||
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
var grd = shape._getRadialGradient();
|
||||
if (grd) {
|
||||
this.setAttr('fillStyle', grd);
|
||||
shape._fillFunc(this);
|
||||
}
|
||||
this.setAttr('fillStyle', grd);
|
||||
shape._fillFunc(this);
|
||||
}
|
||||
_fill(shape) {
|
||||
var hasColor = shape.fill(),
|
||||
|
104
src/Shape.ts
104
src/Shape.ts
@ -8,8 +8,19 @@ import { Context } from './Context';
|
||||
|
||||
var HAS_SHADOW = 'hasShadow';
|
||||
var SHADOW_RGBA = 'shadowRGBA';
|
||||
var patternImage = 'patternImage';
|
||||
var linearGradient = 'linearGradient';
|
||||
var radialGradient = 'radialGradient';
|
||||
|
||||
var dummyContext;
|
||||
function getDummyContext() {
|
||||
if (dummyContext) {
|
||||
return dummyContext;
|
||||
}
|
||||
dummyContext = Util.createCanvasElement().getContext('2d');
|
||||
return dummyContext;
|
||||
}
|
||||
|
||||
// TODO: cache gradient from context
|
||||
// TODO: write a test for adding destroyed shape into the layer
|
||||
// will it draw?
|
||||
// will it pass hit test?
|
||||
@ -42,6 +53,18 @@ function _clearGetShadowRGBACache() {
|
||||
this._clearCache(SHADOW_RGBA);
|
||||
}
|
||||
|
||||
function _clearFillPatternCache() {
|
||||
this._clearCache(patternImage);
|
||||
}
|
||||
|
||||
function _clearLinearGradientCache() {
|
||||
this._clearCache(linearGradient);
|
||||
}
|
||||
|
||||
function _clearRadialGradientCache() {
|
||||
this._clearCache(radialGradient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shape constructor. Shapes are primitive objects such as rectangles,
|
||||
* circles, text, lines, etc.
|
||||
@ -101,6 +124,21 @@ export class Shape extends Node {
|
||||
'shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva',
|
||||
_clearGetShadowRGBACache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva',
|
||||
_clearFillPatternCache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'fillPriorityChange.konva fillLinearGradientColorStopsChange.konva fillLinearGradientStartPointXChange.konva fillLinearGradientStartPointYChange.konva fillLinearGradientEndPointXChange.konva fillLinearGradientEndPointYChange.konva',
|
||||
_clearLinearGradientCache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'fillPriorityChange.konva fillRadialGradientColorStopsChange.konva fillRadialGradientStartPointXChange.konva fillRadialGradientStartPointYChange.konva fillRadialGradientEndPointXChange.konva fillRadialGradientEndPointYChange.konva fillRadialGradientStartRadiusChange.konva fillRadialGradientEndRadiusChange.konva',
|
||||
_clearRadialGradientCache
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,6 +184,64 @@ export class Shape extends Node {
|
||||
))
|
||||
);
|
||||
}
|
||||
_getFillPattern() {
|
||||
return this._getCache(patternImage, this.__getFillPattern);
|
||||
}
|
||||
__getFillPattern() {
|
||||
if (this.fillPatternImage()) {
|
||||
var ctx = getDummyContext();
|
||||
return ctx.createPattern(
|
||||
this.fillPatternImage(),
|
||||
this.fillPatternRepeat() || 'repeat'
|
||||
);
|
||||
}
|
||||
}
|
||||
_getLinearGradient() {
|
||||
return this._getCache(linearGradient, this.__getLinearGradient);
|
||||
}
|
||||
__getLinearGradient() {
|
||||
var colorStops = this.fillLinearGradientColorStops();
|
||||
if (colorStops) {
|
||||
var ctx = getDummyContext();
|
||||
|
||||
var start = this.fillLinearGradientStartPoint();
|
||||
var end = this.fillLinearGradientEndPoint();
|
||||
var grd = ctx.createLinearGradient(start.x, start.y, end.x, end.y);
|
||||
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
}
|
||||
return grd;
|
||||
}
|
||||
}
|
||||
|
||||
_getRadialGradient() {
|
||||
return this._getCache(radialGradient, this.__getRadialGradient);
|
||||
}
|
||||
__getRadialGradient() {
|
||||
var colorStops = this.fillRadialGradientColorStops();
|
||||
if (colorStops) {
|
||||
var ctx = getDummyContext();
|
||||
|
||||
var start = this.fillRadialGradientStartPoint();
|
||||
var end = this.fillRadialGradientEndPoint();
|
||||
var grd = ctx.createRadialGradient(
|
||||
start.x,
|
||||
start.y,
|
||||
this.fillRadialGradientStartRadius(),
|
||||
end.x,
|
||||
end.y,
|
||||
this.fillRadialGradientEndRadius()
|
||||
);
|
||||
|
||||
// build color stops
|
||||
for (var n = 0; n < colorStops.length; n += 2) {
|
||||
grd.addColorStop(colorStops[n], colorStops[n + 1]);
|
||||
}
|
||||
return grd;
|
||||
}
|
||||
}
|
||||
getShadowRGBA() {
|
||||
return this._getCache(SHADOW_RGBA, this._getShadowRGBA);
|
||||
}
|
||||
@ -550,6 +646,12 @@ export class Shape extends Node {
|
||||
fillRadialGradientStartRadius: GetSet<number, this>;
|
||||
fillRadialGradientEndRadius: GetSet<number, this>;
|
||||
fillRadialGradientColorStops: GetSet<Array<number | string>, this>;
|
||||
fillRadialGradientStartPoint: GetSet<Vector2d, this>;
|
||||
fillRadialGradientStartPointX: GetSet<number, this>;
|
||||
fillRadialGradientStartPointY: GetSet<number, this>;
|
||||
fillRadialGradientEndPoint: GetSet<Vector2d, this>;
|
||||
fillRadialGradientEndPointX: GetSet<number, this>;
|
||||
fillRadialGradientEndPointY: GetSet<number, this>;
|
||||
fillPatternOffset: GetSet<Vector2d, this>;
|
||||
fillPatternOffsetX: GetSet<number, this>;
|
||||
fillPatternOffsetY: GetSet<number, this>;
|
||||
|
@ -377,7 +377,7 @@ suite('Shape', function() {
|
||||
|
||||
assert.equal(
|
||||
trace,
|
||||
'clearRect(0,0,578,200);save();transform(3,0,0,1.5,10,15);beginPath();rect(0,0,100,100);closePath();createLinearGradient(0,0,100,100);fillStyle=[object CanvasGradient];fill();lineWidth=2;createLinearGradient(0,0,100,100);strokeStyle=[object CanvasGradient];stroke();restore();'
|
||||
'clearRect(0,0,578,200);save();transform(3,0,0,1.5,10,15);beginPath();rect(0,0,100,100);closePath();fillStyle=[object CanvasGradient];fill();lineWidth=2;createLinearGradient(0,0,100,100);strokeStyle=[object CanvasGradient];stroke();restore();'
|
||||
);
|
||||
});
|
||||
|
||||
@ -1471,4 +1471,307 @@ suite('Shape', function() {
|
||||
layer.add(rect);
|
||||
stage.add(layer);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('cache fill pattern', function(done) {
|
||||
var imageObj = new Image();
|
||||
imageObj.onload = function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var star = new Konva.Star({
|
||||
x: 200,
|
||||
y: 100,
|
||||
numPoints: 5,
|
||||
innerRadius: 40,
|
||||
outerRadius: 70,
|
||||
|
||||
fillPatternImage: imageObj,
|
||||
fillPatternX: -20,
|
||||
fillPatternY: -30,
|
||||
fillPatternScale: { x: 0.5, y: 0.5 },
|
||||
fillPatternOffset: { x: 219, y: 150 },
|
||||
fillPatternRotation: 90,
|
||||
fillPatternRepeat: 'no-repeat',
|
||||
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
layer.add(star);
|
||||
stage.add(layer);
|
||||
|
||||
var ctx = layer.getContext();
|
||||
var oldCreate = ctx.createPattern;
|
||||
|
||||
var callCount = 0;
|
||||
ctx.createPattern = function() {
|
||||
callCount += 1;
|
||||
return oldCreate.apply(this, arguments);
|
||||
};
|
||||
|
||||
layer.draw();
|
||||
layer.draw();
|
||||
assert.equal(callCount, 0);
|
||||
done();
|
||||
};
|
||||
imageObj.src = 'assets/darth-vader.jpg';
|
||||
});
|
||||
|
||||
test('recache fill pattern on changes', function(done) {
|
||||
var imageObj = new Image();
|
||||
imageObj.onload = function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var star = new Konva.Star({
|
||||
x: 200,
|
||||
y: 100,
|
||||
numPoints: 5,
|
||||
innerRadius: 40,
|
||||
outerRadius: 70,
|
||||
|
||||
fillPatternImage: imageObj,
|
||||
fillPatternX: -20,
|
||||
fillPatternY: -30,
|
||||
fillPatternScale: { x: 0.5, y: 0.5 },
|
||||
fillPatternOffset: { x: 219, y: 150 },
|
||||
fillPatternRotation: 90,
|
||||
fillPatternRepeat: 'no-repeat',
|
||||
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
layer.add(star);
|
||||
stage.add(layer);
|
||||
|
||||
var pattern1 = star._getFillPattern();
|
||||
|
||||
star.fillPatternImage(document.createElement('canvas'));
|
||||
|
||||
var pattern2 = star._getFillPattern();
|
||||
|
||||
assert.notEqual(pattern1, pattern2);
|
||||
|
||||
star.fillPatternRepeat('repeat');
|
||||
|
||||
var pattern3 = star._getFillPattern();
|
||||
|
||||
assert.notEqual(pattern2, pattern3);
|
||||
|
||||
done();
|
||||
};
|
||||
imageObj.src = 'assets/darth-vader.jpg';
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('cache linear gradient', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var star = new Konva.Star({
|
||||
x: 200,
|
||||
y: 100,
|
||||
numPoints: 5,
|
||||
innerRadius: 40,
|
||||
outerRadius: 70,
|
||||
|
||||
fillLinearGradientStartPoint: { x: -50, y: -50 },
|
||||
fillLinearGradientEndPoint: { x: 50, y: 50 },
|
||||
fillLinearGradientColorStops: [0, 'red', 1, 'yellow'],
|
||||
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
layer.add(star);
|
||||
stage.add(layer);
|
||||
|
||||
var ctx = layer.getContext();
|
||||
var oldCreate = ctx.createLinearGradient;
|
||||
|
||||
var callCount = 0;
|
||||
ctx.createLinearGradient = function() {
|
||||
callCount += 1;
|
||||
return oldCreate.apply(this, arguments);
|
||||
};
|
||||
|
||||
layer.draw();
|
||||
layer.draw();
|
||||
assert.equal(callCount, 0);
|
||||
});
|
||||
|
||||
test('recache linear gradient on changes', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var star = new Konva.Star({
|
||||
x: 200,
|
||||
y: 100,
|
||||
numPoints: 5,
|
||||
innerRadius: 40,
|
||||
outerRadius: 70,
|
||||
|
||||
fillLinearGradientStartPoint: { x: -50, y: -50 },
|
||||
fillLinearGradientEndPoint: { x: 50, y: 50 },
|
||||
fillLinearGradientColorStops: [0, 'red', 1, 'yellow'],
|
||||
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
layer.add(star);
|
||||
stage.add(layer);
|
||||
|
||||
var gradient1 = star._getLinearGradient();
|
||||
|
||||
star.fillLinearGradientStartPointX(-10);
|
||||
|
||||
var gradient2 = star._getLinearGradient();
|
||||
|
||||
assert.notEqual(gradient1, gradient2);
|
||||
|
||||
star.fillLinearGradientStartPointY(-10);
|
||||
|
||||
var gradient3 = star._getLinearGradient();
|
||||
|
||||
assert.notEqual(gradient2, gradient3);
|
||||
|
||||
star.fillLinearGradientEndPointX(100);
|
||||
|
||||
var gradient4 = star._getLinearGradient();
|
||||
|
||||
assert.notEqual(gradient3, gradient4);
|
||||
|
||||
star.fillLinearGradientEndPointY(100);
|
||||
|
||||
var gradient5 = star._getLinearGradient();
|
||||
|
||||
assert.notEqual(gradient4, gradient5);
|
||||
|
||||
star.fillLinearGradientColorStops([0, 'red', 1, 'green']);
|
||||
|
||||
var gradient6 = star._getLinearGradient();
|
||||
|
||||
assert.notEqual(gradient5, gradient6);
|
||||
|
||||
layer.draw();
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('cache radial gradient', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var star = new Konva.Star({
|
||||
x: 200,
|
||||
y: 100,
|
||||
numPoints: 5,
|
||||
innerRadius: 40,
|
||||
outerRadius: 70,
|
||||
|
||||
fillRadialGradientStartPoint: { x: 0, y: 0 },
|
||||
fillRadialGradientStartRadius: 0,
|
||||
fillRadialGradientEndPoint: { x: 0, y: 0 },
|
||||
fillRadialGradientEndRadius: 70,
|
||||
fillRadialGradientColorStops: [0, 'red', 0.5, 'yellow', 1, 'blue'],
|
||||
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
layer.add(star);
|
||||
stage.add(layer);
|
||||
|
||||
var ctx = layer.getContext();
|
||||
var oldCreate = ctx.createRadialGradient;
|
||||
|
||||
var callCount = 0;
|
||||
ctx.createRadialGradient = function() {
|
||||
callCount += 1;
|
||||
return oldCreate.apply(this, arguments);
|
||||
};
|
||||
|
||||
layer.draw();
|
||||
layer.draw();
|
||||
assert.equal(callCount, 0);
|
||||
});
|
||||
|
||||
test('recache linear gradient on changes', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var star = new Konva.Star({
|
||||
x: 200,
|
||||
y: 100,
|
||||
numPoints: 5,
|
||||
innerRadius: 40,
|
||||
outerRadius: 70,
|
||||
|
||||
fillRadialGradientStartPoint: { x: 0, y: 0 },
|
||||
fillRadialGradientStartRadius: 0,
|
||||
fillRadialGradientEndPoint: { x: 0, y: 0 },
|
||||
fillRadialGradientEndRadius: 70,
|
||||
fillRadialGradientColorStops: [0, 'red', 0.5, 'yellow', 1, 'blue'],
|
||||
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
layer.add(star);
|
||||
stage.add(layer);
|
||||
|
||||
var gradient1 = star._getRadialGradient();
|
||||
|
||||
star.fillRadialGradientStartPointX(-10);
|
||||
|
||||
var gradient2 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient1, gradient2);
|
||||
|
||||
star.fillRadialGradientStartPointY(-10);
|
||||
|
||||
var gradient3 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient2, gradient3);
|
||||
|
||||
star.fillRadialGradientEndPointX(100);
|
||||
|
||||
var gradient4 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient3, gradient4);
|
||||
|
||||
star.fillRadialGradientEndPointY(100);
|
||||
|
||||
var gradient5 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient4, gradient5);
|
||||
|
||||
star.fillRadialGradientColorStops([0, 'red', 1, 'green']);
|
||||
|
||||
var gradient6 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient5, gradient6);
|
||||
|
||||
star.fillRadialGradientStartRadius(10);
|
||||
|
||||
var gradient7 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient6, gradient7);
|
||||
|
||||
star.fillRadialGradientEndRadius(200);
|
||||
|
||||
var gradient8 = star._getRadialGradient();
|
||||
|
||||
assert.notEqual(gradient7, gradient8);
|
||||
|
||||
layer.draw();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user