mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-22 07:19:57 -05:00
We need to take pixel ratio into account when directly blitting blend-modes onto canvas.
This commit is contained in:
parent
4dcb0d66a9
commit
5439f6ba45
4 changed files with 30 additions and 18 deletions
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue