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 = {
canvases: [],
getCanvas: function(width, height) {
var size = height === undefined ? width : new Size(width, height),
canvas,
getCanvas: function(width, height, ratio) {
var canvas,
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) {
canvas = this.canvases.pop();
} else {
/*#*/ if (options.environment == 'browser') {
canvas = document.createElement('canvas');
/*#*/ } else { // !options.environment == 'browser'
canvas = new Canvas(size.width, size.height);
/*#*/ } else { // options.environment != 'browser'
canvas = new Canvas(width, height);
init = false; // It's already initialized through constructor.
/*#*/ } // !options.environment == 'browser'
/*#*/ } // options.environment != 'browser'
}
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
// 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
if (init)
ctx.clearRect(0, 0, size.width + 1, size.height + 1);
ctx.clearRect(0, 0, width + 1, height + 1);
} else {
canvas.width = size.width;
canvas.height = size.height;
canvas.width = width;
canvas.height = height;
}
// We save on retrieval and restore on release.
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
return canvas;
},

View file

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

View file

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

View file

@ -90,7 +90,7 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
var ctx = this._context,
size = this._viewSize;
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;
return true;
}