mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Implement Item#blendMode.
This commit is contained in:
parent
d9b75a7232
commit
eddbc25171
7 changed files with 131 additions and 91 deletions
|
@ -33,7 +33,7 @@ Doc = Base.extend({
|
||||||
// this.canvas.width = this.canvas.width might be faster..
|
// this.canvas.width = this.canvas.width might be faster..
|
||||||
this.ctx.clearRect(0, 0, this.size.width + 1, this.size.height);
|
this.ctx.clearRect(0, 0, this.size.width + 1, this.size.height);
|
||||||
for (var i = 0, l = this.layers.length; i < l; i++) {
|
for (var i = 0, l = this.layers.length; i < l; i++) {
|
||||||
this.layers[i].draw(this.ctx);
|
this.layers[i].draw(this.ctx, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,30 +11,35 @@ Group = Item.extend({
|
||||||
this.clipped = false;
|
this.clipped = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
draw: function(ctx) {
|
draw: function(ctx, param) {
|
||||||
if (!this.visible)
|
if (!this.visible)
|
||||||
return;
|
return;
|
||||||
// If the group has an opacity of less then 1, draw its children on a
|
// If the group has an opacity of less then 1, draw its children on a
|
||||||
// temporary canvas, and then draw that canvas onto ctx afterwards
|
// temporary canvas, and then draw that canvas onto ctx afterwards
|
||||||
// with globalAlpha set.
|
// with globalAlpha set.
|
||||||
var tempCanvas, originalCtx;
|
var tempCanvas, originalCtx;
|
||||||
if (this.opacity < 1) {
|
if(this.blendMode != 'normal' && !param.ignoreBlendMode) {
|
||||||
var originalCtx = ctx;
|
BlendMode.process(ctx, this, param);
|
||||||
tempCanvas = CanvasProvider.getCanvas(this.document.size);
|
} else {
|
||||||
ctx = tempCanvas.getContext('2d');
|
param.ignoreBlendMode = false;
|
||||||
}
|
if (this.opacity < 1) {
|
||||||
for (var i = 0, l = this.children.length; i < l; i++) {
|
var originalCtx = ctx;
|
||||||
this.children[i].draw(ctx);
|
tempCanvas = CanvasProvider.getCanvas(this.document.size);
|
||||||
if (this.clipped & i == 0)
|
ctx = tempCanvas.getContext('2d');
|
||||||
ctx.clip();
|
}
|
||||||
}
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
||||||
if (tempCanvas) {
|
this.children[i].draw(ctx, param);
|
||||||
originalCtx.save();
|
if (this.clipped & i == 0)
|
||||||
originalCtx.globalAlpha = this.opacity;
|
ctx.clip();
|
||||||
originalCtx.drawImage(tempCanvas, 0, 0);
|
}
|
||||||
originalCtx.restore();
|
if (tempCanvas) {
|
||||||
// Return the canvas, so it can be reused
|
originalCtx.save();
|
||||||
CanvasProvider.returnCanvas(tempCanvas);
|
originalCtx.globalAlpha = this.opacity;
|
||||||
|
originalCtx.drawImage(tempCanvas, 0, 0);
|
||||||
|
originalCtx.restore();
|
||||||
|
// Return the canvas, so it can be reused
|
||||||
|
CanvasProvider.returnCanvas(tempCanvas);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,20 @@ Item = Base.extend({
|
||||||
|
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blend mode of the item.
|
||||||
|
*
|
||||||
|
* Sample code:
|
||||||
|
* <code>
|
||||||
|
* var circle = new Path.Circle(new Point(50, 50), 10);
|
||||||
|
* print(circle.blendMode); // normal
|
||||||
|
*
|
||||||
|
* // Change the blend mode of the path item:
|
||||||
|
* circle.blendMode = 'multiply';
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
blendMode: 'normal',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether the item is hidden.
|
* Specifies whether the item is hidden.
|
||||||
*
|
*
|
||||||
|
@ -137,7 +151,6 @@ Item = Base.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: getBlendMode / setBlendMode
|
|
||||||
// TODO: getIsolated / setIsolated (print specific feature)
|
// TODO: getIsolated / setIsolated (print specific feature)
|
||||||
// TODO: get/setKnockout (print specific feature)
|
// TODO: get/setKnockout (print specific feature)
|
||||||
// TODO get/setAlphaIsShape
|
// TODO get/setAlphaIsShape
|
||||||
|
|
|
@ -38,12 +38,17 @@ PlacedSymbol = Item.extend({
|
||||||
return this._bounds;
|
return this._bounds;
|
||||||
},
|
},
|
||||||
|
|
||||||
draw: function(ctx) {
|
draw: function(ctx, param) {
|
||||||
// TODO: we need to preserve strokewidth, but still transform the fill
|
if(this.blendMode != 'normal' && !param.ignoreBlendMode) {
|
||||||
ctx.save();
|
BlendMode.process(ctx, this, param);
|
||||||
this.matrix.applyToContext(ctx);
|
} else {
|
||||||
this.symbol.definition.draw(ctx);
|
param.ignoreBlendMode = false;
|
||||||
ctx.restore();
|
// TODO: we need to preserve strokewidth, but still transform the fill
|
||||||
|
ctx.save();
|
||||||
|
this.matrix.applyToContext(ctx);
|
||||||
|
this.symbol.definition.draw(ctx);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO:
|
// TODO:
|
||||||
// embed()
|
// embed()
|
||||||
|
|
|
@ -165,12 +165,17 @@ Raster = Item.extend({
|
||||||
return this._bounds;
|
return this._bounds;
|
||||||
},
|
},
|
||||||
|
|
||||||
draw: function(ctx) {
|
draw: function(ctx, param) {
|
||||||
ctx.save();
|
if(this.blendMode != 'normal' && !param.ignoreBlendMode) {
|
||||||
this.matrix.applyToContext(ctx);
|
BlendMode.process(ctx, this, param);
|
||||||
ctx.drawImage(this._canvas || this._image,
|
} else {
|
||||||
-this.size.width / 2, -this.size.height / 2);
|
param.ignoreBlendMode = false;
|
||||||
ctx.restore();
|
ctx.save();
|
||||||
|
this.matrix.applyToContext(ctx);
|
||||||
|
ctx.drawImage(this._canvas || this._image,
|
||||||
|
-this.size.width / 2, -this.size.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, new function() {
|
}, new function() {
|
||||||
function getAverageColor(pixels) {
|
function getAverageColor(pixels) {
|
||||||
|
|
|
@ -19,24 +19,30 @@ CompoundPath = PathItem.extend(new function() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
draw: function(ctx) {
|
draw: function(ctx, param) {
|
||||||
if(!this.visible)
|
if(!this.visible)
|
||||||
return;
|
return;
|
||||||
if (this.children.length) {
|
if (this.children.length) {
|
||||||
var firstChild = this.children[0];
|
if(this.blendMode && !param.ignoreBlendMode) {
|
||||||
ctx.beginPath();
|
BlendMode.process(ctx, this, param);
|
||||||
for (var i = 0, l = this.children.length; i < l; i++) {
|
} else {
|
||||||
var child = this.children[i];
|
var firstChild = this.children[0];
|
||||||
child.draw(ctx, true);
|
ctx.beginPath();
|
||||||
}
|
param.compound = true;
|
||||||
firstChild.setCtxStyles(ctx);
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
||||||
if (firstChild.fillColor) {
|
var child = this.children[i];
|
||||||
ctx.fillStyle = firstChild.fillColor.getCssString();
|
child.draw(ctx, param);
|
||||||
ctx.fill();
|
}
|
||||||
}
|
param.compound = false;
|
||||||
if (firstChild.strokeColor) {
|
firstChild.setCtxStyles(ctx);
|
||||||
ctx.strokeStyle = firstChild.strokeColor.getCssString();
|
if (firstChild.fillColor) {
|
||||||
ctx.stroke();
|
ctx.fillStyle = firstChild.fillColor.getCssString();
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
if (firstChild.strokeColor) {
|
||||||
|
ctx.strokeStyle = firstChild.strokeColor.getCssString();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -352,57 +352,63 @@ Path = PathItem.extend({
|
||||||
this.closed = ture;
|
this.closed = ture;
|
||||||
},
|
},
|
||||||
|
|
||||||
draw: function(ctx, compound) {
|
draw: function(ctx, param) {
|
||||||
if (!this.visible) return;
|
if (!this.visible) return;
|
||||||
if (!compound)
|
if(this.blendMode != 'normal' && !param.ignoreBlendMode) {
|
||||||
ctx.beginPath();
|
BlendMode.process(ctx, this, param);
|
||||||
|
} else {
|
||||||
var segments = this._segments;
|
param.ignoreBlendMode = false;
|
||||||
var length = segments.length;
|
if (!param.compound)
|
||||||
for (var i = 0; i < length; i++) {
|
ctx.beginPath();
|
||||||
var segment = segments[i];
|
|
||||||
var x = segment.point.x;
|
var segments = this._segments;
|
||||||
var y = segment.point.y;
|
var length = segments.length;
|
||||||
var handleIn = segment.handleIn;
|
for (var i = 0; i < length; i++) {
|
||||||
if (i == 0) {
|
var segment = segments[i];
|
||||||
ctx.moveTo(x, y);
|
var x = segment.point.x;
|
||||||
} else {
|
var y = segment.point.y;
|
||||||
if (handleOut.isZero() && handleIn.isZero()) {
|
var handleIn = segment.handleIn;
|
||||||
ctx.lineTo(x, y);
|
if (i == 0) {
|
||||||
|
ctx.moveTo(x, y);
|
||||||
} else {
|
} else {
|
||||||
ctx.bezierCurveTo(
|
if (handleOut.isZero() && handleIn.isZero()) {
|
||||||
outX, outY,
|
ctx.lineTo(x, y);
|
||||||
handleIn.x + x, handleIn.y + y,
|
} else {
|
||||||
x, y
|
ctx.bezierCurveTo(
|
||||||
);
|
outX, outY,
|
||||||
|
handleIn.x + x, handleIn.y + y,
|
||||||
|
x, y
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
var handleOut = segment.handleOut;
|
||||||
|
var outX = handleOut.x + x;
|
||||||
|
var outY = handleOut.y + y;
|
||||||
}
|
}
|
||||||
var handleOut = segment.handleOut;
|
if (this.closed && length > 1) {
|
||||||
var outX = handleOut.x + x;
|
var segment = segments[0];
|
||||||
var outY = handleOut.y + y;
|
var x = segment.point.x;
|
||||||
}
|
var y = segment.point.y;
|
||||||
if (this.closed && length > 1) {
|
var handleIn = segment.handleIn;
|
||||||
var segment = segments[0];
|
ctx.bezierCurveTo(outX, outY, handleIn.x + x, handleIn.y + y, x, y);
|
||||||
var x = segment.point.x;
|
ctx.closePath();
|
||||||
var y = segment.point.y;
|
|
||||||
var handleIn = segment.handleIn;
|
|
||||||
ctx.bezierCurveTo(outX, outY, handleIn.x + x, handleIn.y + y, x, y);
|
|
||||||
ctx.closePath();
|
|
||||||
}
|
|
||||||
if (!compound) {
|
|
||||||
this.setCtxStyles(ctx);
|
|
||||||
ctx.save();
|
|
||||||
ctx.globalAlpha = this.opacity;
|
|
||||||
if (this.fillColor) {
|
|
||||||
ctx.fillStyle = this.fillColor.getCanvasStyle(ctx);
|
|
||||||
ctx.fill();
|
|
||||||
}
|
}
|
||||||
if (this.strokeColor) {
|
if (!param.compound) {
|
||||||
ctx.strokeStyle = this.strokeColor.getCanvasStyle(ctx);
|
this.setCtxStyles(ctx);
|
||||||
ctx.stroke();
|
ctx.save();
|
||||||
|
ctx.globalAlpha = this.opacity;
|
||||||
|
if (this.fillColor) {
|
||||||
|
ctx.fillStyle = this.fillColor.getCanvasStyle(ctx);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
if (this.strokeColor) {
|
||||||
|
ctx.strokeStyle = this.strokeColor.getCanvasStyle(ctx);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
}
|
}
|
||||||
ctx.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}, new function() { // inject methods that require scoped privates
|
}, new function() { // inject methods that require scoped privates
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue