Better offscreen detetion, added parameter to skip offscreen rendering. (#3758)

* added check for offscren

* changes

* better onscreen detection

* fix lint
This commit is contained in:
Andrea Bogazzi 2017-03-03 16:42:14 +01:00 committed by GitHub
parent 7733dea5c1
commit 0d0f5c5e63
5 changed files with 50 additions and 0 deletions

View file

@ -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;
},

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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');