cache patterns and gradients

This commit is contained in:
Anton Lavrenov
2019-02-13 22:04:54 -05:00
parent 1b6238cbb2
commit 99e66c380f
6 changed files with 500 additions and 65 deletions

View File

@@ -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(),

View File

@@ -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>;