We need to take pixel ratio into account when directly blitting blend-modes onto canvas.

This commit is contained in:
Jürg Lehni 2013-11-06 13:11:54 +01:00
parent 4dcb0d66a9
commit 5439f6ba45
4 changed files with 30 additions and 18 deletions

View file

@ -15,34 +15,45 @@
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
getCanvas: function(width, height) { getCanvas: function(width, height, ratio) {
var size = height === undefined ? width : new Size(width, height), var canvas,
canvas,
init = true; init = true;
if (typeof width === 'object') {
ratio = height;
height = width.height;
width = width.width;
}
if (!ratio) {
ratio = 1;
} else if (ratio !== 1) {
width *= ratio;
height *= ratio;
}
if (this.canvases.length) { if (this.canvases.length) {
canvas = this.canvases.pop(); canvas = this.canvases.pop();
} else { } else {
/*#*/ if (options.environment == 'browser') { /*#*/ if (options.environment == 'browser') {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
/*#*/ } else { // !options.environment == 'browser' /*#*/ } else { // options.environment != 'browser'
canvas = new Canvas(size.width, size.height); canvas = new Canvas(width, height);
init = false; // It's already initialized through constructor. init = false; // It's already initialized through constructor.
/*#*/ } // !options.environment == 'browser' /*#*/ } // options.environment != 'browser'
} }
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
// We save on retrieval and restore on release.
ctx.save();
// If they are not the same size, we don't need to clear them // If they are not the same size, we don't need to clear them
// using clearRect and visa versa. // using clearRect and visa versa.
if (canvas.width === size.width && canvas.height === size.height) { if (canvas.width === width && canvas.height === height) {
// +1 is needed on some browsers to really clear the borders // +1 is needed on some browsers to really clear the borders
if (init) if (init)
ctx.clearRect(0, 0, size.width + 1, size.height + 1); ctx.clearRect(0, 0, width + 1, height + 1);
} else { } else {
canvas.width = size.width; canvas.width = width;
canvas.height = size.height; canvas.height = height;
} }
// We save on retrieval and restore on release.
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
return canvas; return canvas;
}, },

View file

@ -3242,7 +3242,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
// it, instead of the mainCtx. // it, instead of the mainCtx.
mainCtx = ctx; mainCtx = ctx;
ctx = CanvasProvider.getContext( ctx = CanvasProvider.getContext(
bounds.getSize().ceil().add(new Size(1, 1))); bounds.getSize().ceil().add(new Size(1, 1)), param.ratio);
} }
ctx.save(); ctx.save();
// If drawing directly, handle opacity and native blending now, // If drawing directly, handle opacity and native blending now,
@ -3274,8 +3274,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
// opacity. // opacity.
BlendMode.process(blendMode, ctx, mainCtx, opacity, BlendMode.process(blendMode, ctx, mainCtx, opacity,
// Calculate the pixel offset of the temporary canvas to the // Calculate the pixel offset of the temporary canvas to the
// main canvas. // main canvas. We also need to factor in the pixel ratio.
itemOffset.subtract(prevOffset)); itemOffset.subtract(prevOffset).multiply(param.ratio));
// Return the temporary context, so it can be reused // Return the temporary context, so it can be reused
CanvasProvider.release(ctx); CanvasProvider.release(ctx);
// Restore previous offset. // Restore previous offset.

View file

@ -380,7 +380,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
* @type Symbol[] * @type Symbol[]
*/ */
draw: function(ctx, matrix) { draw: function(ctx, matrix, ratio) {
// Increase the drawCount before the draw-loop. After that, items that // Increase the drawCount before the draw-loop. After that, items that
// are visible will have their drawCount set to the new value. // are visible will have their drawCount set to the new value.
this._drawCount++; this._drawCount++;
@ -390,6 +390,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
// values // values
var param = Base.merge({ var param = Base.merge({
offset: new Point(0, 0), offset: new Point(0, 0),
ratio: ratio,
// A stack of concatenated matrices, to keep track of the current // A stack of concatenated matrices, to keep track of the current
// global matrix, since Canvas is not able tell us (yet). // global matrix, since Canvas is not able tell us (yet).
transforms: [matrix], transforms: [matrix],

View file

@ -90,7 +90,7 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
var ctx = this._context, var ctx = this._context,
size = this._viewSize; size = this._viewSize;
ctx.clearRect(0, 0, size.width + 1, size.height + 1); ctx.clearRect(0, 0, size.width + 1, size.height + 1);
this._project.draw(ctx, this._matrix); this._project.draw(ctx, this._matrix, this._ratio);
this._project._needsRedraw = false; this._project._needsRedraw = false;
return true; return true;
} }