mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-18 18:41:08 +00:00
Added object controls visibility (github issue #552).
This commit is contained in:
parent
c50275a524
commit
d1642c0729
3 changed files with 235 additions and 55 deletions
|
|
@ -6,7 +6,13 @@
|
|||
fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
|
||||
|
||||
/**
|
||||
* Determines which one of the four corners has been clicked
|
||||
* The object interactivity controls.
|
||||
* @private
|
||||
*/
|
||||
_controlsVisibility: null,
|
||||
|
||||
/**
|
||||
* Determines which corner has been clicked
|
||||
* @private
|
||||
* @param {Event} e Event object
|
||||
* @param {Object} offset Canvas offset
|
||||
|
|
@ -23,6 +29,10 @@
|
|||
|
||||
for (var i in this.oCoords) {
|
||||
|
||||
if (!this.isControlVisible(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i === 'mtr' && !this.hasRotatingPoint) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -279,7 +289,7 @@
|
|||
~~(h + padding2 + strokeWidth * this.scaleY) + 1
|
||||
);
|
||||
|
||||
if (this.hasRotatingPoint && !this.get('lockRotation') && this.hasControls) {
|
||||
if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) {
|
||||
|
||||
var rotateHeight = (
|
||||
this.flipY
|
||||
|
|
@ -338,65 +348,80 @@
|
|||
ctx.strokeStyle = ctx.fillStyle = this.cornerColor;
|
||||
|
||||
// top-left
|
||||
_left = left - scaleOffsetX - strokeWidth2 - paddingX;
|
||||
_top = top - scaleOffsetY - strokeWidth2 - paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
// top-right
|
||||
_left = left + width - scaleOffsetX + strokeWidth2 + paddingX;
|
||||
_top = top - scaleOffsetY - strokeWidth2 - paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
// bottom-left
|
||||
_left = left - scaleOffsetX - strokeWidth2 - paddingX;
|
||||
_top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
// bottom-right
|
||||
_left = left + width + scaleOffsetSizeX + strokeWidth2 + paddingX;
|
||||
_top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
if (!this.get('lockUniScaling')) {
|
||||
// middle-top
|
||||
_left = left + width/2 - scaleOffsetX;
|
||||
_top = top - scaleOffsetY - strokeWidth2 - paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
// middle-bottom
|
||||
_left = left + width/2 - scaleOffsetX;
|
||||
_top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
// middle-right
|
||||
_left = left + width + scaleOffsetSizeX + strokeWidth2 + paddingX;
|
||||
_top = top + height/2 - scaleOffsetY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
|
||||
// middle-left
|
||||
if (this.isControlVisible('tl')) {
|
||||
_left = left - scaleOffsetX - strokeWidth2 - paddingX;
|
||||
_top = top + height/2 - scaleOffsetY;
|
||||
_top = top - scaleOffsetY - strokeWidth2 - paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
|
||||
// top-right
|
||||
if (this.isControlVisible('tr')) {
|
||||
_left = left + width - scaleOffsetX + strokeWidth2 + paddingX;
|
||||
_top = top - scaleOffsetY - strokeWidth2 - paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
|
||||
// bottom-left
|
||||
if (this.isControlVisible('bl')) {
|
||||
_left = left - scaleOffsetX - strokeWidth2 - paddingX;
|
||||
_top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
|
||||
// bottom-right
|
||||
if (this.isControlVisible('br')) {
|
||||
_left = left + width + scaleOffsetSizeX + strokeWidth2 + paddingX;
|
||||
_top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
|
||||
if (!this.get('lockUniScaling')) {
|
||||
// middle-top
|
||||
if (this.isControlVisible('mt')) {
|
||||
_left = left + width/2 - scaleOffsetX;
|
||||
_top = top - scaleOffsetY - strokeWidth2 - paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
|
||||
// middle-bottom
|
||||
if (this.isControlVisible('mb')) {
|
||||
_left = left + width/2 - scaleOffsetX;
|
||||
_top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
|
||||
// middle-right
|
||||
if (this.isControlVisible('mr')) {
|
||||
_left = left + width + scaleOffsetSizeX + strokeWidth2 + paddingX;
|
||||
_top = top + height/2 - scaleOffsetY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
// middle-left
|
||||
if (this.isControlVisible('ml')) {
|
||||
_left = left - scaleOffsetX - strokeWidth2 - paddingX;
|
||||
_top = top + height/2 - scaleOffsetY;
|
||||
|
||||
isVML || transparent || ctx.clearRect(_left, _top, sizeX, sizeY);
|
||||
ctx[methodName](_left, _top, sizeX, sizeY);
|
||||
}
|
||||
}
|
||||
|
||||
// middle-top-rotate
|
||||
if (this.hasRotatingPoint) {
|
||||
if (this.hasRotatingPoint && this.isControlVisible('mtr')) {
|
||||
|
||||
_left = left + width/2 - scaleOffsetX;
|
||||
_top = this.flipY ?
|
||||
|
|
@ -410,6 +435,73 @@
|
|||
ctx.restore();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the specified control is visible, false otherwise.
|
||||
* @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
|
||||
* @returns {Boolean} true if the specified control is visible, false otherwise
|
||||
*/
|
||||
isControlVisible: function(controlName) {
|
||||
return this._getControlsVisibility()[controlName];
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the visibility of the specified control.
|
||||
* @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
|
||||
* @param {Boolean} visible true to set the specified control visible, false otherwise
|
||||
* @return {fabric.Object} thisArg
|
||||
* @chainable
|
||||
*/
|
||||
setControlVisible: function(controlName, visible) {
|
||||
this._getControlsVisibility()[controlName] = visible;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the visibility state of object controls.
|
||||
* @param {Object} [options] Options object
|
||||
* @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it
|
||||
* @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it
|
||||
* @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it
|
||||
* @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it
|
||||
* @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it
|
||||
* @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it
|
||||
* @param {Boolean} [options.tl] true to enable the top-left control, false to disable it
|
||||
* @param {Boolean} [options.tr] true to enable the top-right control, false to disable it
|
||||
* @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it
|
||||
* @return {fabric.Object} thisArg
|
||||
* @chainable
|
||||
*/
|
||||
setControlsVisibility: function(options) {
|
||||
options || (options = { });
|
||||
|
||||
for (var p in options) {
|
||||
this.setControlVisible(p, options[p]);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the instance of the control visibility set for this object.
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getControlsVisibility: function() {
|
||||
if (!this._controlsVisibility) {
|
||||
this._controlsVisibility = {
|
||||
tl: true,
|
||||
tr: true,
|
||||
br: true,
|
||||
bl: true,
|
||||
ml: true,
|
||||
mt: true,
|
||||
mr: true,
|
||||
mb: true,
|
||||
mtr: true
|
||||
};
|
||||
}
|
||||
return this._controlsVisibility;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
3
test.js
3
test.js
|
|
@ -29,7 +29,8 @@ testrunner.run({
|
|||
'./test/unit/canvas_static.js',
|
||||
'./test/unit/gradient.js',
|
||||
'./test/unit/pattern.js',
|
||||
'./test/unit/shadow.js'
|
||||
'./test/unit/shadow.js',
|
||||
'./test/unit/object_interactivity.js'
|
||||
]
|
||||
}, function(err, report) {
|
||||
if (err) {
|
||||
|
|
|
|||
87
test/unit/object_interactivity.js
Normal file
87
test/unit/object_interactivity.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
(function() {
|
||||
|
||||
QUnit.module('fabric.ObjectInteractivity');
|
||||
|
||||
test('isControlVisible', function(){
|
||||
ok(fabric.Object);
|
||||
|
||||
var cObj = new fabric.Object({ });
|
||||
ok(typeof cObj.isControlVisible == 'function', 'isControlVisible should exist');
|
||||
|
||||
equal(cObj.isControlVisible('tl'), true);
|
||||
equal(cObj.isControlVisible('tr'), true);
|
||||
equal(cObj.isControlVisible('br'), true);
|
||||
equal(cObj.isControlVisible('bl'), true);
|
||||
equal(cObj.isControlVisible('ml'), true);
|
||||
equal(cObj.isControlVisible('mt'), true);
|
||||
equal(cObj.isControlVisible('mr'), true);
|
||||
equal(cObj.isControlVisible('mb'), true);
|
||||
equal(cObj.isControlVisible('mtr'), true);
|
||||
});
|
||||
|
||||
test('setControlVisible', function(){
|
||||
ok(fabric.Object);
|
||||
|
||||
var cObj = new fabric.Object({ });
|
||||
ok(typeof cObj.setControlVisible == 'function', 'setControlVisible should exist');
|
||||
equal(cObj.setControlVisible('tl'), cObj, 'chainable');
|
||||
|
||||
cObj.setControlVisible('tl', false);
|
||||
equal(cObj.isControlVisible('tl'), false);
|
||||
cObj.setControlVisible('tl', true);
|
||||
equal(cObj.isControlVisible('tl'), true);
|
||||
});
|
||||
|
||||
test('setControlsVisibility', function(){
|
||||
ok(fabric.Object);
|
||||
|
||||
var cObj = new fabric.Object({ });
|
||||
ok(typeof cObj.setControlsVisibility == 'function', 'setControlsVisibility should exist');
|
||||
equal(cObj.setControlsVisibility(), cObj, 'chainable');
|
||||
|
||||
cObj.setControlsVisibility({
|
||||
bl: false,
|
||||
br: false,
|
||||
mb: false,
|
||||
ml: false,
|
||||
mr: false,
|
||||
mt: false,
|
||||
tl: false,
|
||||
tr: false,
|
||||
mtr: false
|
||||
});
|
||||
|
||||
equal(cObj.isControlVisible('tl'), false);
|
||||
equal(cObj.isControlVisible('tr'), false);
|
||||
equal(cObj.isControlVisible('br'), false);
|
||||
equal(cObj.isControlVisible('bl'), false);
|
||||
equal(cObj.isControlVisible('ml'), false);
|
||||
equal(cObj.isControlVisible('mt'), false);
|
||||
equal(cObj.isControlVisible('mr'), false);
|
||||
equal(cObj.isControlVisible('mb'), false);
|
||||
equal(cObj.isControlVisible('mtr'), false);
|
||||
|
||||
cObj.setControlsVisibility({
|
||||
bl: true,
|
||||
br: true,
|
||||
mb: true,
|
||||
ml: true,
|
||||
mr: true,
|
||||
mt: true,
|
||||
tl: true,
|
||||
tr: true,
|
||||
mtr: true
|
||||
});
|
||||
|
||||
equal(cObj.isControlVisible('tl'), true);
|
||||
equal(cObj.isControlVisible('tr'), true);
|
||||
equal(cObj.isControlVisible('br'), true);
|
||||
equal(cObj.isControlVisible('bl'), true);
|
||||
equal(cObj.isControlVisible('ml'), true);
|
||||
equal(cObj.isControlVisible('mt'), true);
|
||||
equal(cObj.isControlVisible('mr'), true);
|
||||
equal(cObj.isControlVisible('mb'), true);
|
||||
equal(cObj.isControlVisible('mtr'), true);
|
||||
});
|
||||
|
||||
})();
|
||||
Loading…
Reference in a new issue