mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-24 05:03:44 +00:00
parent
03d27681c3
commit
ad7e56422a
5 changed files with 550 additions and 234 deletions
|
|
@ -225,6 +225,13 @@
|
|||
*/
|
||||
isDrawingMode: false,
|
||||
|
||||
/**
|
||||
* Indicates whether objects should remain in current stack position when selected. When false objects are brought to top and rendered as part of the selection group
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
preserveObjectStacking: false,
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
@ -242,6 +249,73 @@
|
|||
this.calcOffset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Divides objects in two groups, one to render immediately
|
||||
* and one to render as activeGroup.
|
||||
* @return {Array} objects to render immediately and pushes the other in the activeGroup.
|
||||
*/
|
||||
_chooseObjectsToRender: function() {
|
||||
var activeGroup = this.getActiveGroup(),
|
||||
activeObject = this.getActiveObject(),
|
||||
object, objsToRender = [ ], activeGroupObjects = [ ];
|
||||
|
||||
if ((activeGroup || activeObject) && !this.preserveObjectStacking) {
|
||||
for (var i = 0, length = this._objects.length; i < length; i++) {
|
||||
object = this._objects[i];
|
||||
if ((!activeGroup || !activeGroup.contains(object)) && object !== activeObject) {
|
||||
objsToRender.push(object);
|
||||
}
|
||||
else {
|
||||
activeGroupObjects.push(object);
|
||||
}
|
||||
}
|
||||
if (activeGroup) {
|
||||
activeGroup._set('_objects', activeGroupObjects);
|
||||
objsToRender.push(activeGroup);
|
||||
}
|
||||
activeObject && objsToRender.push(activeObject);
|
||||
}
|
||||
else {
|
||||
objsToRender = this._objects;
|
||||
}
|
||||
return objsToRender;
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders both the top canvas and the secondary container canvas.
|
||||
* @param {Boolean} [allOnTop] Whether we want to force all images to be rendered on the top canvas
|
||||
* @return {fabric.Canvas} instance
|
||||
* @chainable
|
||||
*/
|
||||
renderAll: function () {
|
||||
if (this.selection && !this._groupSelector && !this.isDrawingMode) {
|
||||
this.clearContext(this.contextTop);
|
||||
}
|
||||
var canvasToDrawOn = this.contextContainer;
|
||||
this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method to render only the top canvas.
|
||||
* Also used to render the group selection box.
|
||||
* @return {fabric.Canvas} thisArg
|
||||
* @chainable
|
||||
*/
|
||||
renderTop: function () {
|
||||
var ctx = this.contextTop;
|
||||
this.clearContext(ctx);
|
||||
|
||||
// we render the top context - last object
|
||||
if (this.selection && this._groupSelector) {
|
||||
this._drawSelection(ctx);
|
||||
}
|
||||
|
||||
this.fire('after:render');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the current transform to its original values and chooses the type of resizing based on the event
|
||||
* @private
|
||||
|
|
@ -299,8 +373,9 @@
|
|||
* @return {Boolean} true if point is contained within an area of given object
|
||||
*/
|
||||
containsPoint: function (e, target, point) {
|
||||
var pointer = point || this.getPointer(e, true),
|
||||
xy = this._normalizePointer(target, pointer);
|
||||
var ignoreZoom = true,
|
||||
pointer = point || this.getPointer(e, ignoreZoom),
|
||||
xy;
|
||||
|
||||
if (target.group && target.group === this.getActiveGroup()) {
|
||||
xy = this._normalizePointer(target.group, pointer);
|
||||
|
|
@ -317,18 +392,13 @@
|
|||
* @private
|
||||
*/
|
||||
_normalizePointer: function (object, pointer) {
|
||||
var lt, m;
|
||||
|
||||
m = fabric.util.multiplyTransformMatrices(
|
||||
this.viewportTransform,
|
||||
object.calcTransformMatrix());
|
||||
|
||||
m = fabric.util.invertTransform(m);
|
||||
pointer = fabric.util.transformPoint(pointer, m , false);
|
||||
lt = fabric.util.transformPoint(object.getCenterPoint(), m , false);
|
||||
pointer.x -= lt.x;
|
||||
pointer.y -= lt.y;
|
||||
return { x: pointer.x, y: pointer.y };
|
||||
var m = object.calcTransformMatrix(),
|
||||
invertedM = fabric.util.invertTransform(m),
|
||||
vpt = this.viewportTransform,
|
||||
vptPointer = this.restorePointerVpt(pointer),
|
||||
p = fabric.util.transformPoint(vptPointer, invertedM);
|
||||
return fabric.util.transformPoint(p, vpt);
|
||||
//return { x: p.x * vpt[0], y: p.y * vpt[3] };
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -864,6 +934,7 @@
|
|||
},
|
||||
|
||||
/**
|
||||
* @param {fabric.Object} target to reset transform
|
||||
* @private
|
||||
*/
|
||||
_resetObjectTransform: function (target) {
|
||||
|
|
@ -876,10 +947,10 @@
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx to draw the selection on
|
||||
*/
|
||||
_drawSelection: function () {
|
||||
var ctx = this.contextTop,
|
||||
groupSelector = this._groupSelector,
|
||||
_drawSelection: function (ctx) {
|
||||
var groupSelector = this._groupSelector,
|
||||
left = groupSelector.left,
|
||||
top = groupSelector.top,
|
||||
aleft = abs(left),
|
||||
|
|
@ -933,9 +1004,10 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var pointer = this.getPointer(e, true),
|
||||
activeGroup = this.getActiveGroup(),
|
||||
activeObject = this.getActiveObject();
|
||||
var ignoreZoom = true,
|
||||
pointer = this.getPointer(e, ignoreZoom),
|
||||
activeGroup = this.getActiveGroup(),
|
||||
activeObject = this.getActiveObject();
|
||||
|
||||
// first check current group (if one exists)
|
||||
// active group does not check sub targets like normal groups.
|
||||
|
|
@ -1020,6 +1092,18 @@
|
|||
return target;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns pointer coordinates without the effect of the viewport
|
||||
* @param {Object} pointer with "x" and "y" number values
|
||||
* @return {Object} object with "x" and "y" number values
|
||||
*/
|
||||
restorePointerVpt: function(pointer) {
|
||||
return fabric.util.transformPoint(
|
||||
pointer,
|
||||
fabric.util.invertTransform(this.viewportTransform)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns pointer coordinates relative to canvas.
|
||||
* @param {Event} e
|
||||
|
|
@ -1049,10 +1133,7 @@
|
|||
pointer.x = pointer.x - this._offset.left;
|
||||
pointer.y = pointer.y - this._offset.top;
|
||||
if (!ignoreZoom) {
|
||||
pointer = fabric.util.transformPoint(
|
||||
pointer,
|
||||
fabric.util.invertTransform(this.viewportTransform)
|
||||
);
|
||||
pointer = this.restorePointerVpt(pointer);
|
||||
}
|
||||
|
||||
if (boundsWidth === 0 || boundsHeight === 0) {
|
||||
|
|
@ -1195,6 +1276,20 @@
|
|||
return this._activeObject;
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {fabric.Object} obj Object that was removed
|
||||
*/
|
||||
_onObjectRemoved: function(obj) {
|
||||
// removing active object should fire "selection:cleared" events
|
||||
if (this.getActiveObject() === obj) {
|
||||
this.fire('before:selection:cleared', { target: obj });
|
||||
this._discardActiveObject();
|
||||
this.fire('selection:cleared');
|
||||
}
|
||||
this.callSuper('_onObjectRemoved', obj);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
@ -1323,6 +1418,18 @@
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears all contexts (background, main, top) of an instance
|
||||
* @return {fabric.Canvas} thisArg
|
||||
* @chainable
|
||||
*/
|
||||
clear: function () {
|
||||
this.discardActiveGroup();
|
||||
this.discardActiveObject();
|
||||
this.clearContext(this.contextTop);
|
||||
return this.callSuper('clear');
|
||||
},
|
||||
|
||||
/**
|
||||
* Draws objects' controls (borders/controls)
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render controls on
|
||||
|
|
@ -1350,22 +1457,6 @@
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {fabric.Object} obj Object that was removed
|
||||
*/
|
||||
_onObjectRemoved: function(obj) {
|
||||
this.callSuper('_onObjectRemoved', obj);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears all contexts (background, main, top) of an instance
|
||||
* @return {fabric.Canvas} thisArg
|
||||
* @chainable
|
||||
*/
|
||||
clear: function () {
|
||||
return this.callSuper('clear');
|
||||
}
|
||||
});
|
||||
|
||||
// copying static properties manually to work around Opera's bug,
|
||||
|
|
|
|||
|
|
@ -383,8 +383,7 @@
|
|||
if (this.clipTo) {
|
||||
fabric.util.clipContext(this, this.contextTop);
|
||||
}
|
||||
var ivt = fabric.util.invertTransform(this.viewportTransform),
|
||||
pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt);
|
||||
var pointer = this.getPointer(e);
|
||||
this.freeDrawingBrush.onMouseDown(pointer);
|
||||
this._handleEvent(e, 'down');
|
||||
},
|
||||
|
|
@ -395,8 +394,7 @@
|
|||
*/
|
||||
_onMouseMoveInDrawingMode: function(e) {
|
||||
if (this._isCurrentlyDrawing) {
|
||||
var ivt = fabric.util.invertTransform(this.viewportTransform),
|
||||
pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt);
|
||||
var pointer = this.getPointer(e);
|
||||
this.freeDrawingBrush.onMouseMove(pointer);
|
||||
}
|
||||
this.setCursor(this.freeDrawingCursor);
|
||||
|
|
@ -672,11 +670,13 @@
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} e Event object
|
||||
* @param {Object} transform current tranform
|
||||
* @param {Number} x mouse position x from origin
|
||||
* @param {Number} y mouse poistion y from origin
|
||||
* @return {Boolean} true if the scaling occurred
|
||||
*/
|
||||
_onScale: function(e, transform, x, y) {
|
||||
// rotate object only if shift key is not pressed
|
||||
// and if it is not a group we are transforming
|
||||
if ((e[this.uniScaleKey] || this.uniScaleTransform) && !transform.target.get('lockUniScaling')) {
|
||||
transform.currentAction = 'scale';
|
||||
return this._scaleObject(x, y);
|
||||
|
|
|
|||
|
|
@ -133,13 +133,6 @@
|
|||
*/
|
||||
imageSmoothingEnabled: true,
|
||||
|
||||
/**
|
||||
* Indicates whether objects should remain in current stack position when selected. When false objects are brought to top and rendered as part of the selection group
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
preserveObjectStacking: false,
|
||||
|
||||
/**
|
||||
* The transformation (in the format of Canvas transform) which focuses the viewport
|
||||
* @type Array
|
||||
|
|
@ -181,6 +174,7 @@
|
|||
* @param {Object} [options] Options object
|
||||
*/
|
||||
_initStatic: function(el, options) {
|
||||
var cb = fabric.StaticCanvas.prototype.renderAll.bind(this);
|
||||
this._objects = [];
|
||||
|
||||
this._createLowerCanvas(el);
|
||||
|
|
@ -193,16 +187,16 @@
|
|||
}
|
||||
|
||||
if (options.overlayImage) {
|
||||
this.setOverlayImage(options.overlayImage, this.renderAll.bind(this));
|
||||
this.setOverlayImage(options.overlayImage, cb);
|
||||
}
|
||||
if (options.backgroundImage) {
|
||||
this.setBackgroundImage(options.backgroundImage, this.renderAll.bind(this));
|
||||
this.setBackgroundImage(options.backgroundImage, cb);
|
||||
}
|
||||
if (options.backgroundColor) {
|
||||
this.setBackgroundColor(options.backgroundColor, this.renderAll.bind(this));
|
||||
this.setBackgroundColor(options.backgroundColor, cb);
|
||||
}
|
||||
if (options.overlayColor) {
|
||||
this.setOverlayColor(options.overlayColor, this.renderAll.bind(this));
|
||||
this.setOverlayColor(options.overlayColor, cb);
|
||||
}
|
||||
this.calcOffset();
|
||||
},
|
||||
|
|
@ -669,13 +663,13 @@
|
|||
setViewportTransform: function (vpt) {
|
||||
var activeGroup = this.getActiveGroup();
|
||||
this.viewportTransform = vpt;
|
||||
this.renderAll();
|
||||
for (var i = 0, len = this._objects.length; i < len; i++) {
|
||||
this._objects[i].setCoords();
|
||||
}
|
||||
if (activeGroup) {
|
||||
activeGroup.setCoords();
|
||||
}
|
||||
this.renderAll();
|
||||
return this;
|
||||
},
|
||||
|
||||
|
|
@ -688,18 +682,14 @@
|
|||
*/
|
||||
zoomToPoint: function (point, value) {
|
||||
// TODO: just change the scale, preserve other transformations
|
||||
var before = point;
|
||||
var before = point, vpt = this.viewportTransform.slice(0);
|
||||
point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform));
|
||||
this.viewportTransform[0] = value;
|
||||
this.viewportTransform[3] = value;
|
||||
var after = fabric.util.transformPoint(point, this.viewportTransform);
|
||||
this.viewportTransform[4] += before.x - after.x;
|
||||
this.viewportTransform[5] += before.y - after.y;
|
||||
this.renderAll();
|
||||
for (var i = 0, len = this._objects.length; i < len; i++) {
|
||||
this._objects[i].setCoords();
|
||||
}
|
||||
return this;
|
||||
vpt[0] = value;
|
||||
vpt[3] = value;
|
||||
var after = fabric.util.transformPoint(point, vpt);
|
||||
vpt[4] += before.x - after.x;
|
||||
vpt[5] += before.y - after.y;
|
||||
return this.setViewportTransform(vpt);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -720,13 +710,10 @@
|
|||
* @chainable true
|
||||
*/
|
||||
absolutePan: function (point) {
|
||||
this.viewportTransform[4] = -point.x;
|
||||
this.viewportTransform[5] = -point.y;
|
||||
this.renderAll();
|
||||
for (var i = 0, len = this._objects.length; i < len; i++) {
|
||||
this._objects[i].setCoords();
|
||||
}
|
||||
return this;
|
||||
var vpt = this.viewportTransform.slice(0);
|
||||
vpt[4] = -point.x;
|
||||
vpt[5] = -point.y;
|
||||
return this.setViewportTransform(vpt);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -783,13 +770,6 @@
|
|||
* @param {fabric.Object} obj Object that was removed
|
||||
*/
|
||||
_onObjectRemoved: function(obj) {
|
||||
// removing active object should fire "selection:cleared" events
|
||||
if (this.getActiveObject() === obj) {
|
||||
this.fire('before:selection:cleared', { target: obj });
|
||||
this._discardActiveObject();
|
||||
this.fire('selection:cleared');
|
||||
}
|
||||
|
||||
this.fire('object:removed', { target: obj });
|
||||
obj.fire('removed');
|
||||
},
|
||||
|
|
@ -820,97 +800,64 @@
|
|||
*/
|
||||
clear: function () {
|
||||
this._objects.length = 0;
|
||||
if (this.discardActiveGroup) {
|
||||
this.discardActiveGroup();
|
||||
}
|
||||
if (this.discardActiveObject) {
|
||||
this.discardActiveObject();
|
||||
}
|
||||
this.clearContext(this.contextContainer);
|
||||
if (this.contextTop) {
|
||||
this.clearContext(this.contextTop);
|
||||
}
|
||||
this.fire('canvas:cleared');
|
||||
this.renderAll();
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Divides objects in two groups, one to render immediately
|
||||
* and one to render as activeGroup.
|
||||
* return objects to render immediately and pushes the other in the activeGroup.
|
||||
*/
|
||||
_chooseObjectsToRender: function() {
|
||||
var activeGroup = this.getActiveGroup(),
|
||||
activeObject = this.getActiveObject(),
|
||||
object, objsToRender = [ ], activeGroupObjects = [ ];
|
||||
|
||||
if ((activeGroup || activeObject) && !this.preserveObjectStacking) {
|
||||
for (var i = 0, length = this._objects.length; i < length; i++) {
|
||||
object = this._objects[i];
|
||||
if ((!activeGroup || !activeGroup.contains(object)) && object !== activeObject) {
|
||||
objsToRender.push(object);
|
||||
}
|
||||
else {
|
||||
activeGroupObjects.push(object);
|
||||
}
|
||||
}
|
||||
activeGroup && activeGroup._set('_objects', activeGroupObjects);
|
||||
}
|
||||
else {
|
||||
objsToRender = this._objects;
|
||||
}
|
||||
return objsToRender;
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders both the top canvas and the secondary container canvas.
|
||||
* @param {Boolean} [allOnTop] Whether we want to force all images to be rendered on the top canvas
|
||||
* Renders both the canvas.
|
||||
* @return {fabric.Canvas} instance
|
||||
* @chainable
|
||||
*/
|
||||
renderAll: function () {
|
||||
var canvasToDrawOn = this.contextContainer, objsToRender;
|
||||
|
||||
if (this.contextTop && this.selection && !this._groupSelector && !this.isDrawingMode) {
|
||||
this.clearContext(this.contextTop);
|
||||
}
|
||||
|
||||
this.clearContext(canvasToDrawOn);
|
||||
|
||||
this.fire('before:render');
|
||||
|
||||
if (this.clipTo) {
|
||||
fabric.util.clipContext(this, canvasToDrawOn);
|
||||
}
|
||||
this._renderBackground(canvasToDrawOn);
|
||||
|
||||
canvasToDrawOn.save();
|
||||
objsToRender = this._chooseObjectsToRender();
|
||||
//apply viewport transform once for all rendering process
|
||||
canvasToDrawOn.transform.apply(canvasToDrawOn, this.viewportTransform);
|
||||
this._renderObjects(canvasToDrawOn, objsToRender);
|
||||
if (!this.preserveObjectStacking) {
|
||||
objsToRender = [this.getActiveGroup(), this.getActiveObject()];
|
||||
this._renderObjects(canvasToDrawOn, objsToRender);
|
||||
}
|
||||
canvasToDrawOn.restore();
|
||||
|
||||
if (!this.controlsAboveOverlay && this.interactive) {
|
||||
this.drawControls(canvasToDrawOn);
|
||||
}
|
||||
if (this.clipTo) {
|
||||
canvasToDrawOn.restore();
|
||||
}
|
||||
this._renderOverlay(canvasToDrawOn);
|
||||
if (this.controlsAboveOverlay && this.interactive) {
|
||||
this.drawControls(canvasToDrawOn);
|
||||
}
|
||||
|
||||
this.fire('after:render');
|
||||
var canvasToDrawOn = this.contextContainer;
|
||||
this.renderCanvas(canvasToDrawOn, this._objects);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders background, objects, overlay and controls.
|
||||
* @param {CanvasRenderingContext2D} ctx
|
||||
* @param {Array} objects to render
|
||||
* @return {fabric.Canvas} instance
|
||||
* @chainable
|
||||
*/
|
||||
renderCanvas: function(ctx, objects) {
|
||||
this.clearContext(ctx);
|
||||
this.fire('before:render');
|
||||
if (this.clipTo) {
|
||||
fabric.util.clipContext(this, ctx);
|
||||
}
|
||||
this._renderBackground(ctx);
|
||||
|
||||
ctx.save();
|
||||
//apply viewport transform once for all rendering process
|
||||
ctx.transform.apply(ctx, this.viewportTransform);
|
||||
this._renderObjects(ctx, objects);
|
||||
ctx.restore();
|
||||
if (!this.controlsAboveOverlay && this.interactive) {
|
||||
this.drawControls(ctx);
|
||||
}
|
||||
if (this.clipTo) {
|
||||
ctx.restore();
|
||||
}
|
||||
this._renderOverlay(ctx);
|
||||
if (this.controlsAboveOverlay && this.interactive) {
|
||||
this.drawControls(ctx);
|
||||
}
|
||||
this.fire('after:render');
|
||||
},
|
||||
|
||||
/**
|
||||
* dummy function for organization purpouse.
|
||||
* @private
|
||||
*/
|
||||
drawControls: function() {
|
||||
// NOOP
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
|
|
@ -967,26 +914,6 @@
|
|||
this._renderBackgroundOrOverlay(ctx, 'overlay');
|
||||
},
|
||||
|
||||
/**
|
||||
* Method to render only the top canvas.
|
||||
* Also used to render the group selection box.
|
||||
* @return {fabric.Canvas} thisArg
|
||||
* @chainable
|
||||
*/
|
||||
renderTop: function () {
|
||||
var ctx = this.contextTop || this.contextContainer;
|
||||
this.clearContext(ctx);
|
||||
|
||||
// we render the top context - last object
|
||||
if (this.selection && this._groupSelector) {
|
||||
this._drawSelection();
|
||||
}
|
||||
|
||||
this.fire('after:render');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns coordinates of a center of canvas.
|
||||
* Returned value is an object with top and left properties
|
||||
|
|
|
|||
|
|
@ -48,6 +48,22 @@
|
|||
'"shadow":null,'+
|
||||
'"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0}],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}';
|
||||
|
||||
function _createImageElement() {
|
||||
return fabric.isLikelyNode ? new (require('canvas').Image)() : fabric.document.createElement('img');
|
||||
}
|
||||
|
||||
function getAbsolutePath(path) {
|
||||
var isAbsolute = /^https?:/.test(path);
|
||||
if (isAbsolute) return path;
|
||||
var imgEl = _createImageElement();
|
||||
imgEl.src = path;
|
||||
var src = imgEl.src;
|
||||
imgEl = null;
|
||||
return src;
|
||||
}
|
||||
|
||||
var IMG_SRC = fabric.isLikelyNode ? (__dirname + '/../fixtures/test_image.gif') : getAbsolutePath('../fixtures/test_image.gif');
|
||||
|
||||
var el = fabric.document.createElement('canvas');
|
||||
el.width = 600; el.height = 600;
|
||||
|
||||
|
|
@ -68,6 +84,8 @@
|
|||
QUnit.module('fabric.Canvas', {
|
||||
setup: function() {
|
||||
upperCanvasEl.style.display = '';
|
||||
canvas.controlsAboveOverlay = fabric.Canvas.prototype.controlsAboveOverlay;
|
||||
canvas.preserveObjectStacking = fabric.Canvas.prototype.preserveObjectStacking;
|
||||
},
|
||||
teardown: function() {
|
||||
canvas.clear();
|
||||
|
|
@ -103,6 +121,83 @@
|
|||
equal(canvas.item(0), rect, 'should return proper item');
|
||||
});
|
||||
|
||||
test('preserveObjectStacking', function() {
|
||||
ok(typeof canvas.preserveObjectStacking == 'boolean');
|
||||
ok(!canvas.preserveObjectStacking, 'default is false');
|
||||
});
|
||||
|
||||
test('uniScaleTransform', function() {
|
||||
ok(typeof canvas.uniScaleTransform == 'boolean');
|
||||
ok(!canvas.uniScaleTransform, 'default is false');
|
||||
});
|
||||
|
||||
test('uniScaleKey', function() {
|
||||
ok(typeof canvas.uniScaleKey == 'string');
|
||||
equal(canvas.uniScaleKey, 'shiftKey', 'default is shift');
|
||||
});
|
||||
|
||||
test('centeredScaling', function() {
|
||||
ok(typeof canvas.centeredScaling == 'boolean');
|
||||
ok(!canvas.centeredScaling, 'default is false');
|
||||
});
|
||||
|
||||
test('centeredRotation', function() {
|
||||
ok(typeof canvas.centeredRotation == 'boolean');
|
||||
ok(!canvas.centeredRotation, 'default is false');
|
||||
});
|
||||
|
||||
test('centeredKey', function() {
|
||||
ok(typeof canvas.centeredKey == 'string');
|
||||
equal(canvas.centeredKey, 'altKey', 'default is alt');
|
||||
});
|
||||
|
||||
test('altActionKey', function() {
|
||||
ok(typeof canvas.altActionKey == 'string');
|
||||
equal(canvas.altActionKey, 'shiftKey', 'default is shift');
|
||||
});
|
||||
|
||||
test('interactive', function() {
|
||||
ok(typeof canvas.interactive == 'boolean');
|
||||
ok(canvas.interactive, 'default is true');
|
||||
});
|
||||
|
||||
test('selection', function() {
|
||||
ok(typeof canvas.selection == 'boolean');
|
||||
ok(canvas.selection, 'default is true');
|
||||
});
|
||||
|
||||
test('_initInteractive', function() {
|
||||
ok(typeof canvas._initInteractive == 'function');
|
||||
});
|
||||
|
||||
test('renderTop', function() {
|
||||
ok(typeof canvas.renderTop == 'function');
|
||||
equal(canvas, canvas.renderTop());
|
||||
});
|
||||
|
||||
test('_chooseObjectsToRender', function() {
|
||||
ok(typeof canvas._chooseObjectsToRender == 'function');
|
||||
var rect = makeRect(), rect2 = makeRect(), rect3 = makeRect();
|
||||
canvas.add(rect);
|
||||
canvas.add(rect2);
|
||||
canvas.add(rect3);
|
||||
var objs = canvas._chooseObjectsToRender();
|
||||
equal(objs[0], rect);
|
||||
equal(objs[1], rect2);
|
||||
equal(objs[2], rect3);
|
||||
canvas.setActiveObject(rect);
|
||||
objs = canvas._chooseObjectsToRender();
|
||||
equal(objs[0], rect2);
|
||||
equal(objs[1], rect3);
|
||||
equal(objs[2], rect);
|
||||
canvas.setActiveObject(rect2);
|
||||
canvas.preserveObjectStacking = true;
|
||||
objs = canvas._chooseObjectsToRender();
|
||||
equal(objs[0], rect);
|
||||
equal(objs[1], rect2);
|
||||
equal(objs[2], rect3);
|
||||
});
|
||||
|
||||
test('calcOffset', function() {
|
||||
ok(typeof canvas.calcOffset == 'function', 'should respond to `calcOffset`');
|
||||
equal(canvas.calcOffset(), canvas, 'should be chainable');
|
||||
|
|
@ -214,9 +309,8 @@
|
|||
equal(canvas, canvas.renderAll());
|
||||
});
|
||||
|
||||
test('renderTop', function() {
|
||||
ok(typeof canvas.renderTop == 'function');
|
||||
equal(canvas, canvas.renderTop());
|
||||
test('_drawSelection', function() {
|
||||
ok(typeof canvas._drawSelection == 'function');
|
||||
});
|
||||
|
||||
test('findTarget', function() {
|
||||
|
|
@ -793,6 +887,78 @@
|
|||
});
|
||||
});
|
||||
|
||||
test('loadFromJSON with custom properties on Canvas with no async object', function() {
|
||||
var serialized = JSON.parse(PATH_JSON);
|
||||
serialized.controlsAboveOverlay = true;
|
||||
serialized.preserveObjectStacking = true;
|
||||
equal(canvas.controlsAboveOverlay, fabric.Canvas.prototype.controlsAboveOverlay);
|
||||
equal(canvas.preserveObjectStacking, fabric.Canvas.prototype.preserveObjectStacking);
|
||||
canvas.loadFromJSON(serialized, function() {
|
||||
ok(!canvas.isEmpty(), 'canvas is not empty');
|
||||
equal(canvas.controlsAboveOverlay, true);
|
||||
equal(canvas.preserveObjectStacking, true);
|
||||
});
|
||||
// if no async object the callback is called syncronously
|
||||
equal(canvas.controlsAboveOverlay, true);
|
||||
equal(canvas.preserveObjectStacking, true);
|
||||
});
|
||||
|
||||
asyncTest('loadFromJSON with custom properties on Canvas with image', function() {
|
||||
var JSON_STRING = '{"objects":[{"type":"image","originX":"left","originY":"top","left":13.6,"top":-1.4,"width":3000,"height":3351,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":0.05,"scaleY":0.05,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"src":"' + IMG_SRC + '","filters":[],"crossOrigin":"","alignX":"none","alignY":"none","meetOrSlice":"meet"}],'
|
||||
+ '"background":"green"}';
|
||||
var serialized = JSON.parse(JSON_STRING);
|
||||
serialized.controlsAboveOverlay = true;
|
||||
serialized.preserveObjectStacking = true;
|
||||
equal(canvas.controlsAboveOverlay, fabric.Canvas.prototype.controlsAboveOverlay);
|
||||
equal(canvas.preserveObjectStacking, fabric.Canvas.prototype.preserveObjectStacking);
|
||||
canvas.loadFromJSON(serialized, function() {
|
||||
ok(!canvas.isEmpty(), 'canvas is not empty');
|
||||
equal(canvas.controlsAboveOverlay, true);
|
||||
equal(canvas.preserveObjectStacking, true);
|
||||
start();
|
||||
});
|
||||
// before callback the properties are still false.
|
||||
equal(canvas.controlsAboveOverlay, false);
|
||||
equal(canvas.preserveObjectStacking, false);
|
||||
});
|
||||
|
||||
|
||||
test('normalize pointer', function(){
|
||||
ok(typeof canvas._normalizePointer == 'function');
|
||||
var pointer = { x: 10, y: 20 },
|
||||
object = makeRect({ top: 10, left: 10, width: 50, height: 50, strokeWidth: 0}),
|
||||
normalizedPointer = canvas._normalizePointer(object, pointer);
|
||||
equal(normalizedPointer.x, -25, 'should be in top left corner of rect');
|
||||
equal(normalizedPointer.y, -15, 'should be in top left corner of rect');
|
||||
object.angle = 90;
|
||||
normalizedPointer = canvas._normalizePointer(object, pointer);
|
||||
equal(normalizedPointer.x, -15, 'should consider angle');
|
||||
equal(normalizedPointer.y, -25, 'should consider angle');
|
||||
object.angle = 0;
|
||||
object.scaleX = 2;
|
||||
object.scaleY = 2;
|
||||
normalizedPointer = canvas._normalizePointer(object, pointer);
|
||||
equal(normalizedPointer.x, -25, 'should consider scale');
|
||||
equal(normalizedPointer.y, -20, 'should consider scale');
|
||||
object.skewX = 60;
|
||||
normalizedPointer = canvas._normalizePointer(object, pointer);
|
||||
equal(normalizedPointer.x.toFixed(2), -33.66, 'should consider skewX');
|
||||
equal(normalizedPointer.y, -20, 'should not change');
|
||||
});
|
||||
|
||||
test('restorePointerVpt', function(){
|
||||
ok(typeof canvas.restorePointerVpt == 'function');
|
||||
var pointer = { x: 10, y: 20 },
|
||||
restoredPointer = canvas.restorePointerVpt(pointer);
|
||||
equal(restoredPointer.x, pointer.x, 'no changes if not vpt is set');
|
||||
equal(restoredPointer.y, pointer.y, 'no changes if not vpt is set');
|
||||
canvas.viewportTransform = [2, 0, 0, 2, 50, -60];
|
||||
restoredPointer = canvas.restorePointerVpt(pointer);
|
||||
equal(restoredPointer.x, -20, 'vpt changes restored');
|
||||
equal(restoredPointer.y, 40, 'vpt changes restored');
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
|
||||
});
|
||||
|
||||
// asyncTest('loadFromJSON with backgroundImage', function() {
|
||||
// canvas.setBackgroundImage('../../assets/pug.jpg');
|
||||
// var anotherCanvas = new fabric.Canvas();
|
||||
|
|
@ -1315,6 +1481,104 @@
|
|||
ok(canvas.containsPoint(eventStub, rect), 'on rect at (200, 200) should be within area (175, 175, 225, 225)');
|
||||
});
|
||||
|
||||
test('setupCurrentTransform', function() {
|
||||
ok(typeof canvas._setupCurrentTransform == 'function');
|
||||
|
||||
var rect = new fabric.Rect({ left: 75, top: 75, width: 50, height: 50 });
|
||||
canvas.add(rect);
|
||||
var canvasEl = canvas.getElement(),
|
||||
canvasOffset = fabric.util.getElementOffset(canvasEl);
|
||||
var eventStub = {
|
||||
clientX: canvasOffset.left + 100,
|
||||
clientY: canvasOffset.top + 100,
|
||||
target: rect
|
||||
};
|
||||
rect.active = true;
|
||||
canvas._setupCurrentTransform(eventStub, rect);
|
||||
var t = canvas._currentTransform;
|
||||
equal(t.target, rect, 'should have rect as a target');
|
||||
equal(t.action, 'drag', 'should target inside rect and setup drag');
|
||||
equal(t.corner, 0, 'no corner selected');
|
||||
equal(t.originX, rect.originX, 'no origin change for drag');
|
||||
equal(t.originY, rect.originY, 'no origin change for drag');
|
||||
|
||||
eventStub = {
|
||||
clientX: canvasOffset.left + rect.oCoords.tl.corner.tl.x + 1,
|
||||
clientY: canvasOffset.top + rect.oCoords.tl.corner.tl.y + 1,
|
||||
target: rect
|
||||
};
|
||||
canvas._setupCurrentTransform(eventStub, rect);
|
||||
t = canvas._currentTransform;
|
||||
equal(t.target, rect, 'should have rect as a target');
|
||||
equal(t.action, 'scale', 'should target a corner and setup scale');
|
||||
equal(t.corner, 'tl', 'tl selected');
|
||||
equal(t.originX, 'right', 'origin in opposite direction');
|
||||
equal(t.originY, 'bottom', 'origin in opposite direction');
|
||||
equal(t.shiftKey, undefined, 'shift was not pressed');
|
||||
|
||||
eventStub = {
|
||||
clientX: canvasOffset.left + rect.left - 2,
|
||||
clientY: canvasOffset.top + rect.top + rect.height/2,
|
||||
target: rect,
|
||||
shiftKey: true
|
||||
};
|
||||
canvas._setupCurrentTransform(eventStub, rect);
|
||||
t = canvas._currentTransform;
|
||||
equal(t.target, rect, 'should have rect as a target');
|
||||
equal(t.action, 'skewY', 'should target a corner and setup skew');
|
||||
equal(t.shiftKey, true, 'shift was pressed');
|
||||
equal(t.corner, 'ml', 'ml selected');
|
||||
equal(t.originX, 'right', 'origin in opposite direction');
|
||||
|
||||
eventStub = {
|
||||
clientX: canvasOffset.left + rect.oCoords.mtr.x,
|
||||
clientY: canvasOffset.top + rect.oCoords.mtr.y,
|
||||
target: rect,
|
||||
};
|
||||
canvas._setupCurrentTransform(eventStub, rect);
|
||||
t = canvas._currentTransform;
|
||||
equal(t.target, rect, 'should have rect as a target');
|
||||
equal(t.action, 'rotate', 'should target a corner and setup rotate');
|
||||
equal(t.corner, 'mtr', 'mtr selected');
|
||||
canvas._currentTransform = false;
|
||||
});
|
||||
|
||||
test('_scaleObject', function() {
|
||||
ok(typeof canvas._scaleObject == 'function');
|
||||
var rect = new fabric.Rect({ left: 75, top: 75, width: 50, height: 50 });
|
||||
canvas.add(rect);
|
||||
var canvasEl = canvas.getElement(),
|
||||
canvasOffset = fabric.util.getElementOffset(canvasEl);
|
||||
var eventStub = {
|
||||
clientX: canvasOffset.left + rect.oCoords.tl.corner.tl.x + 1,
|
||||
clientY: canvasOffset.top + rect.oCoords.tl.corner.tl.y + 1,
|
||||
target: rect
|
||||
};
|
||||
canvas._setupCurrentTransform(eventStub, rect);
|
||||
var scaled = canvas._scaleObject(30, 30, 'equally');
|
||||
equal(scaled, true, 'return true if scaling happened');
|
||||
scaled = canvas._scaleObject(30, 30, 'equally');
|
||||
equal(scaled, false, 'return false if no movement happen');
|
||||
});
|
||||
|
||||
test('containsPoint in viewport transform', function() {
|
||||
canvas.viewportTransform = [2, 0, 0, 2, 50, 50];
|
||||
var rect = new fabric.Rect({ left: 75, top: 75, width: 50, height: 50 });
|
||||
canvas.add(rect);
|
||||
|
||||
var canvasEl = canvas.getElement(),
|
||||
canvasOffset = fabric.util.getElementOffset(canvasEl);
|
||||
|
||||
var eventStub = {
|
||||
clientX: canvasOffset.left + 250,
|
||||
clientY: canvasOffset.top + 250,
|
||||
target: rect
|
||||
};
|
||||
|
||||
ok(canvas.containsPoint(eventStub, rect), 'point at (250, 250) should be within area (75, 75, 125, 125)');
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
|
||||
});
|
||||
|
||||
asyncTest('fxRemove', function() {
|
||||
ok(typeof canvas.fxRemove == 'function');
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
'backgroundColor': '',
|
||||
'clipTo': null,
|
||||
'filters': [],
|
||||
'resizeFilters': [],
|
||||
'resizeFilters': [],
|
||||
'fillRule': 'nonzero',
|
||||
'globalCompositeOperation': 'source-over',
|
||||
'transformMatrix': null,
|
||||
|
|
@ -158,9 +158,7 @@
|
|||
canvas.backgroundColor = fabric.StaticCanvas.prototype.backgroundColor;
|
||||
canvas.backgroundImage = fabric.StaticCanvas.prototype.backgroundImage;
|
||||
canvas.overlayColor = fabric.StaticCanvas.prototype.overlayColor;
|
||||
canvas.controlsAboveOverlay = fabric.StaticCanvas.prototype.controlsAboveOverlay;
|
||||
canvas.preserveObjectStacking = fabric.StaticCanvas.prototype.preserveObjectStacking;
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
|
||||
canvas.calcOffset();
|
||||
}
|
||||
});
|
||||
|
|
@ -434,16 +432,6 @@
|
|||
equal(canvas, canvas.renderAll());
|
||||
});
|
||||
|
||||
test('preserveObjectStacking', function() {
|
||||
ok(typeof canvas.preserveObjectStacking == 'boolean');
|
||||
ok(!canvas.preserveObjectStacking);
|
||||
});
|
||||
|
||||
test('renderTop', function() {
|
||||
ok(typeof canvas.renderTop == 'function');
|
||||
equal(canvas, canvas.renderTop());
|
||||
});
|
||||
|
||||
test('toDataURL', function() {
|
||||
ok(typeof canvas.toDataURL == 'function');
|
||||
if (!fabric.Canvas.supports('toDataURL')) {
|
||||
|
|
@ -486,7 +474,7 @@
|
|||
equal(rect.getCenterPoint().x, canvas.width / 2, 'object\'s "center.y" property should correspond to canvas element\'s center');
|
||||
canvas.setZoom(4);
|
||||
equal(rect.getCenterPoint().x, canvas.height / 2, 'object\'s "center.x" property should correspond to canvas element\'s center when canvas is transformed');
|
||||
|
||||
canvas.setZoom(1);
|
||||
});
|
||||
|
||||
test('centerObjectV', function() {
|
||||
|
|
@ -511,6 +499,7 @@
|
|||
canvas.setZoom(4);
|
||||
equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center when canvas is transformed');
|
||||
equal(rect.getCenterPoint().x, canvas.height / 2, 'object\'s "center.x" property should correspond to canvas element\'s center when canvas is transformed');
|
||||
canvas.setZoom(1);
|
||||
});
|
||||
|
||||
test('viewportCenterObjectH', function() {
|
||||
|
|
@ -924,42 +913,6 @@
|
|||
});
|
||||
});
|
||||
|
||||
test('loadFromJSON with custom properties on Canvas with no async object', function() {
|
||||
var serialized = JSON.parse(PATH_JSON);
|
||||
serialized.controlsAboveOverlay = true;
|
||||
serialized.preserveObjectStacking = true;
|
||||
equal(canvas.controlsAboveOverlay, fabric.Canvas.prototype.controlsAboveOverlay);
|
||||
equal(canvas.preserveObjectStacking, fabric.Canvas.prototype.preserveObjectStacking);
|
||||
canvas.loadFromJSON(serialized, function() {
|
||||
ok(!canvas.isEmpty(), 'canvas is not empty');
|
||||
equal(canvas.controlsAboveOverlay, true);
|
||||
equal(canvas.preserveObjectStacking, true);
|
||||
});
|
||||
// if no async object the callback is called syncronously
|
||||
equal(canvas.controlsAboveOverlay, true);
|
||||
equal(canvas.preserveObjectStacking, true);
|
||||
});
|
||||
|
||||
asyncTest('loadFromJSON with custom properties on Canvas with image', function() {
|
||||
var JSON_STRING = '{"objects":[{"type":"image","originX":"left","originY":"top","left":13.6,"top":-1.4,"width":3000,"height":3351,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":0.05,"scaleY":0.05,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"src":"' + IMG_SRC + '","filters":[],"crossOrigin":"","alignX":"none","alignY":"none","meetOrSlice":"meet"}],'
|
||||
+ '"background":"green"}';
|
||||
var serialized = JSON.parse(JSON_STRING);
|
||||
serialized.controlsAboveOverlay = true;
|
||||
serialized.preserveObjectStacking = true;
|
||||
equal(canvas.controlsAboveOverlay, fabric.Canvas.prototype.controlsAboveOverlay);
|
||||
equal(canvas.preserveObjectStacking, fabric.Canvas.prototype.preserveObjectStacking);
|
||||
canvas.loadFromJSON(serialized, function() {
|
||||
ok(!canvas.isEmpty(), 'canvas is not empty');
|
||||
equal(canvas.controlsAboveOverlay, true);
|
||||
equal(canvas.preserveObjectStacking, true);
|
||||
start();
|
||||
});
|
||||
// before callback the properties are still false.
|
||||
equal(canvas.controlsAboveOverlay, false);
|
||||
equal(canvas.preserveObjectStacking, false);
|
||||
});
|
||||
|
||||
|
||||
asyncTest('loadFromJSON with image background and color', function() {
|
||||
var serialized = JSON.parse(PATH_JSON);
|
||||
serialized.background = 'green';
|
||||
|
|
@ -1324,6 +1277,87 @@
|
|||
});
|
||||
});
|
||||
|
||||
test('setViewportTransform', function() {
|
||||
ok(typeof canvas.setViewportTransform == 'function');
|
||||
var vpt = [2, 0, 0, 2, 50, 50];
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
|
||||
canvas.setViewportTransform(vpt);
|
||||
deepEqual(canvas.viewportTransform, vpt, 'viewport now is the set one');
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
});
|
||||
|
||||
test('getZoom', function() {
|
||||
ok(typeof canvas.getZoom == 'function');
|
||||
var vpt = [2, 0, 0, 2, 50, 50];
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
deepEqual(canvas.getZoom(), 1, 'initial zoom is 1');
|
||||
canvas.setViewportTransform(vpt);
|
||||
deepEqual(canvas.getZoom(), 2, 'zoom is set to 2');
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
});
|
||||
|
||||
test('setZoom', function() {
|
||||
ok(typeof canvas.setZoom == 'function');
|
||||
deepEqual(canvas.getZoom(), 1, 'initial zoom is 1');
|
||||
canvas.setZoom(2);
|
||||
deepEqual(canvas.getZoom(), 2, 'zoom is set to 2');
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
});
|
||||
|
||||
test('zoomToPoint', function() {
|
||||
ok(typeof canvas.zoomToPoint == 'function');
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
|
||||
var point = new fabric.Point(50, 50);
|
||||
canvas.zoomToPoint(point, 1);
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'viewport has no changes if not moving with zoom level');
|
||||
canvas.zoomToPoint(point, 2);
|
||||
deepEqual(canvas.viewportTransform, [2, 0, 0, 2, -50, -50], 'viewport has a translation effect and zoom');
|
||||
canvas.zoomToPoint(point, 3);
|
||||
deepEqual(canvas.viewportTransform, [3, 0, 0, 3, -100, -100], 'viewport has a translation effect and zoom');
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
});
|
||||
|
||||
test('absolutePan', function() {
|
||||
ok(typeof canvas.absolutePan == 'function');
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
|
||||
var point = new fabric.Point(50, 50);
|
||||
canvas.absolutePan(point);
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -point.x, -point.y], 'viewport has translation effect applied');
|
||||
canvas.absolutePan(point);
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -point.x, -point.y], 'viewport has same translation effect applied');
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
});
|
||||
|
||||
test('relativePan', function() {
|
||||
ok(typeof canvas.relativePan == 'function');
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
|
||||
var point = new fabric.Point(-50, -50);
|
||||
canvas.relativePan(point);
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -50, -50], 'viewport has translation effect applied');
|
||||
canvas.relativePan(point);
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -100, -100], 'viewport has translation effect applied on top of old one');
|
||||
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
|
||||
});
|
||||
|
||||
test('getActiveObject', function() {
|
||||
ok(typeof canvas.getActiveObject == 'function');
|
||||
var activeObject = canvas.getActiveObject();
|
||||
equal(activeObject, null, 'should return null');
|
||||
});
|
||||
|
||||
test('getActiveGroup', function() {
|
||||
ok(typeof canvas.getActiveGroup == 'function');
|
||||
var activeGroup = canvas.getActiveGroup();
|
||||
equal(activeGroup, null, 'should return null');
|
||||
});
|
||||
|
||||
test('getContext', function() {
|
||||
ok(typeof canvas.getContext == 'function');
|
||||
var context = canvas.getContext();
|
||||
equal(context, canvas.contextContainer, 'should return the context container');
|
||||
});
|
||||
|
||||
//how to test with an exception?
|
||||
/*asyncTest('options in setBackgroundImage from invalid URL', function() {
|
||||
canvas.backgroundImage = null;
|
||||
|
|
|
|||
Loading…
Reference in a new issue