Handle nested matrices correctly when drawing blend modes or transparency.

Closes #194.
This commit is contained in:
Jürg Lehni 2013-04-09 20:01:10 -07:00
parent f79e561512
commit 2c3e8a32ab

View file

@ -2796,7 +2796,12 @@ var Item = this.Item = Base.extend(Callback, {
// way to filter out selected items that are not being drawn, e.g. // way to filter out selected items that are not being drawn, e.g.
// because they are currently not part of the DOM. // because they are currently not part of the DOM.
item._drawCount = item._project._drawCount; item._drawCount = item._project._drawCount;
var parentCtx, itemOffset, prevOffset; // Keep calculating the current global matrix, by keeping a history
// and pushing / popping as we go along.
var transforms = param.transforms,
parentMatrix = transforms[transforms.length - 1],
globalMatrix = parentMatrix.clone().concatenate(item._matrix);
transforms.push(item._globalMatrix = globalMatrix);
// If the item has a blendMode or is defining an opacity, draw it on // If the item has a blendMode or is defining an opacity, draw it on
// a temporary canvas first and composite the canvas afterwards. // a temporary canvas first and composite the canvas afterwards.
// Paths with an opacity < 1 that both define a fillColor // Paths with an opacity < 1 that both define a fillColor
@ -2805,10 +2810,13 @@ var Item = this.Item = Base.extend(Callback, {
// over their fill. // over their fill.
// Exclude Raster items since they never draw a stroke and handle // Exclude Raster items since they never draw a stroke and handle
// opacity by themselves (they also don't call _setStyles) // opacity by themselves (they also don't call _setStyles)
var parentCtx, itemOffset, prevOffset;
if (item._blendMode !== 'normal' || item._opacity < 1 if (item._blendMode !== 'normal' || item._opacity < 1
&& item._type !== 'raster' && (item._type !== 'path' && item._type !== 'raster' && (item._type !== 'path'
|| item.getFillColor() && item.getStrokeColor())) { || item.getFillColor() && item.getStrokeColor())) {
var bounds = item.getStrokeBounds(); // Apply the paren't global matrix to the calculation of correct
// bounds.
var bounds = item.getStrokeBounds(parentMatrix);
if (!bounds.width || !bounds.height) if (!bounds.width || !bounds.height)
return; return;
// Store previous offset and save the parent context, so we can // Store previous offset and save the parent context, so we can
@ -2828,15 +2836,11 @@ var Item = this.Item = Base.extend(Callback, {
// on the temporary canvas. // on the temporary canvas.
if (parentCtx) if (parentCtx)
ctx.translate(-itemOffset.x, -itemOffset.y); ctx.translate(-itemOffset.x, -itemOffset.y);
// Keep calculating the current global matrix, by keeping a history // Apply globalMatrix when blitting into temporary canvas.
// and pushing / popping as we go along. (parentCtx ? globalMatrix : item._matrix).applyToContext(ctx);
var transforms = param.transforms;
transforms.push(item._globalMatrix = transforms[transforms.length-1]
.clone().concatenate(item._matrix));
item._matrix.applyToContext(ctx);
item.draw(ctx, param); item.draw(ctx, param);
transforms.pop();
ctx.restore(); ctx.restore();
transforms.pop();
if (param.clip) if (param.clip)
ctx.clip(); ctx.clip();
// If a temporary canvas was created before, composite it onto the // If a temporary canvas was created before, composite it onto the