mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-08-13 14:38:49 -04:00
Add support for canvas compositing modes to Item#blendMode.
Closes #159.
This commit is contained in:
parent
175091a69f
commit
94c192495a
2 changed files with 27 additions and 15 deletions
src
|
@ -215,13 +215,23 @@ var BlendMode = new function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build a lookup table for natively supported CSS blend-modes. Just seeing
|
// Build a lookup table for natively supported CSS composite- & blend-modes.
|
||||||
// if globalCompositeOperation is actually sticky is not enough, as Chome 27
|
// The canvas composite modes are always natively supported:
|
||||||
// pretends for blend-modes to work, but does not actually apply them.
|
var nativeModes = this.nativeModes = Base.each([
|
||||||
|
'source-over', 'source-in', 'source-out', 'source-atop',
|
||||||
|
'destination-over', 'destination-in', 'destination-out',
|
||||||
|
'destination-atop', 'lighter', 'darker', 'copy', 'xor'
|
||||||
|
], function(mode) {
|
||||||
|
this[mode] = true;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// Now test for the new blend modes. Just seeing if globalCompositeOperation
|
||||||
|
// is sticky is not enough, as Chome 27 pretends for blend-modes to work,
|
||||||
|
// but does not actually apply them.
|
||||||
var ctx = CanvasProvider.getContext(1, 1);
|
var ctx = CanvasProvider.getContext(1, 1);
|
||||||
// Blend #330000 (51) and #aa0000 (170). Multiplying should lead to
|
Base.each(modes, function(func, mode) {
|
||||||
// #220000 (34)
|
// Blend #330000 (51) and #aa0000 (170):
|
||||||
function testMode(mode) {
|
// Multiplying should lead to #220000 (34)
|
||||||
ctx.save();
|
ctx.save();
|
||||||
// For darken we need to reverse color parameters in order to test mode.
|
// For darken we need to reverse color parameters in order to test mode.
|
||||||
var darken = mode === 'darken',
|
var darken = mode === 'darken',
|
||||||
|
@ -234,20 +244,16 @@ var BlendMode = new function() {
|
||||||
ctx.fillRect(0, 0, 1, 1);
|
ctx.fillRect(0, 0, 1, 1);
|
||||||
ok = ctx.getImageData(0, 0, 1, 1).data[0] !== (darken ? 170 : 51);
|
ok = ctx.getImageData(0, 0, 1, 1).data[0] !== (darken ? 170 : 51);
|
||||||
}
|
}
|
||||||
|
nativeModes[mode] = ok;
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
return ok;
|
});
|
||||||
}
|
|
||||||
this.nativeModes = testMode('multiply') && Base.each(modes,
|
|
||||||
function(func, mode) {
|
|
||||||
this[mode] = testMode(mode);
|
|
||||||
}, {});
|
|
||||||
CanvasProvider.release(ctx);
|
CanvasProvider.release(ctx);
|
||||||
|
|
||||||
this.process = function(mode, srcContext, dstContext, alpha, offset) {
|
this.process = function(mode, srcContext, dstContext, alpha, offset) {
|
||||||
var srcCanvas = srcContext.canvas,
|
var srcCanvas = srcContext.canvas,
|
||||||
normal = mode === 'normal';
|
normal = mode === 'normal';
|
||||||
// Use native blend-modes if supported, and fall back to emulation.
|
// Use native blend-modes if supported, and fall back to emulation.
|
||||||
if (normal || this.nativeModes[mode]) {
|
if (normal || nativeModes[mode]) {
|
||||||
dstContext.save();
|
dstContext.save();
|
||||||
// Reset transformations, since we're blitting and pixel scale and
|
// Reset transformations, since we're blitting and pixel scale and
|
||||||
// with a given offset.
|
// with a given offset.
|
||||||
|
|
|
@ -449,13 +449,19 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
||||||
_visible: true,
|
_visible: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The blend mode of the item.
|
* The blend mode with which the item is composited onto the canvas. Both
|
||||||
|
* the standard canvas compositing modes, as well as the new CSS blend modes
|
||||||
|
* are supported. If blend-modes cannot be rendered natively, they are
|
||||||
|
* emulated. Be aware that emulation can have an impact on performance.
|
||||||
*
|
*
|
||||||
* @name Item#blendMode
|
* @name Item#blendMode
|
||||||
* @type String('normal', 'multiply', 'screen', 'overlay', 'soft-light',
|
* @type String('normal', 'multiply', 'screen', 'overlay', 'soft-light',
|
||||||
* 'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten',
|
* 'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten',
|
||||||
* 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color',
|
* 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color',
|
||||||
* 'add', 'subtract', 'average', 'pin-light', 'negation')
|
* 'add', 'subtract', 'average', 'pin-light', 'negation', 'source-over',
|
||||||
|
* 'source-in', 'source-out', 'source-atop', 'destination-over',
|
||||||
|
* 'destination-in', 'destination-out', 'destination-atop', 'lighter',
|
||||||
|
* 'darker', 'copy', 'xor')
|
||||||
* @default 'normal'
|
* @default 'normal'
|
||||||
*
|
*
|
||||||
* @example {@paperscript}
|
* @example {@paperscript}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue