Skip to content

Commit

Permalink
Better offscreen detetion, added parameter to skip offscreen renderin…
Browse files Browse the repository at this point in the history
…g. (#3758)

* added check for offscren

* changes

* better onscreen detection

* fix lint
  • Loading branch information
asturur committed Mar 14, 2017
1 parent 05f959a commit a816742
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/mixins/object_geometry.mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@
return true;
}
}
// no points on screen, check intersection with absolute coordinates
if (this.intersectsWithRect(pointTL, pointBR, true)) {
return true;
}
// worst case scenario the object is so big that contanins the screen
var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };
if (this.containsPoint(centerPoint, null, true)) {
return true;
}
return false;
},

Expand Down
3 changes: 3 additions & 0 deletions src/shapes/object.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,9 @@
if ((this.width === 0 && this.height === 0) || !this.visible) {
return;
}
if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {
return;
}
ctx.save();
//setup fill rule for current object
this._setupCompositeOperation(ctx);
Expand Down
3 changes: 3 additions & 0 deletions src/shapes/text.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,9 @@
if (!this.visible) {
return;
}
if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {
return;
}
if (this._shouldClearDimensionCache()) {
this._setTextStyles(ctx);
this._initDimensions(ctx);
Expand Down
10 changes: 10 additions & 0 deletions src/static_canvas.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,16 @@
*/
vptCoords: { },

/**
* Based on vptCoords and object.aCoords, skip rendering of objects that
* are not included in current viewport.
* May greatly help in applications with crowded canvas and use of zoom/pan
* If One of the corner of the bounding box of the object is on the canvas
* the objects get rendered.
* @memberOf fabric.StaticCanvas.prototype
*/
skipOffscreen: true,

/**
* @private
* @param {HTMLElement | String} el <canvas> element to initialize instance on
Expand Down
25 changes: 25 additions & 0 deletions test/unit/object_geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,31 @@
ok(cObj.isOnScreen(), 'zooming out the object is again on screen');
});

test('isOnScreen with object that include canvas', function(){
var cObj = new fabric.Object(
{ left: -10, top: -10, width: canvas.getWidth() + 100, height: canvas.getHeight(), strokeWidth: 0});
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
cObj.canvas = canvas;
cObj.setCoords();
equal(cObj.isOnScreen(), true, 'object is onScreen because it include the canvas');
cObj.top = -1000;
cObj.left = -1000;
cObj.setCoords();
equal(cObj.isOnScreen(), false, 'object is completely out of viewport');
});

test('isOnScreen with object that is in top left corner of canvas', function(){
var cObj = new fabric.Rect({left: -46.56, top: -9.23, width: 50,height: 50, angle: 314.57});
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
cObj.canvas = canvas;
cObj.setCoords();
ok(cObj.isOnScreen(), 'object is onScreen because it intersect a canvas line');
cObj.top -= 20;
cObj.left -= 20;
cObj.setCoords();
ok(!cObj.isOnScreen(), 'object is completely out of viewport');
});

test('calcTransformMatrix', function(){
var cObj = new fabric.Object({ width: 10, height: 15, strokeWidth: 0 });
ok(typeof cObj.calcTransformMatrix == 'function', 'calcTransformMatrix should exist');
Expand Down

0 comments on commit a816742

Please sign in to comment.