Give a way to draw controls programmatically (#3887)

* changes to control rendering

* changes

* moved render all after the events

* more changes

* removed console.log
This commit is contained in:
Andrea Bogazzi 2017-04-29 20:08:23 +02:00 committed by GitHub
parent 977d71de6e
commit ee323e126f
4 changed files with 48 additions and 50 deletions

View file

@ -1608,11 +1608,13 @@
* @private
*/
_drawObjectsControls: function(ctx) {
var object;
for (var i = 0, len = this._objects.length; i < len; ++i) {
if (!this._objects[i] || !this._objects[i].active) {
object = this._objects[i];
if (!object || !object.active) {
continue;
}
this._objects[i]._renderControls(ctx);
object._renderControls(ctx);
}
},

View file

@ -136,22 +136,20 @@
* Requires public properties: width, height
* Requires public options: padding, borderColor
* @param {CanvasRenderingContext2D} ctx Context to draw on
* @param {Object} bordersStyle object to override the object style
* @return {fabric.Object} thisArg
* @chainable
*/
drawBorders: function(ctx) {
if (!this.hasBorders) {
return this;
}
drawBorders: function(ctx, bordersStyle) {
bordersStyle = bordersStyle || {};
var wh = this._calculateCurrentDimensions(),
strokeWidth = 1 / this.borderScaleFactor,
width = wh.x + strokeWidth,
height = wh.y + strokeWidth;
ctx.save();
ctx.strokeStyle = this.borderColor;
this._setLineDash(ctx, this.borderDashArray, null);
ctx.strokeStyle = bordersStyle.borderColor || this.borderColor;
this._setLineDash(ctx, bordersStyle.borderDashArray || this.borderDashArray, null);
ctx.strokeRect(
-width / 2,
@ -160,7 +158,8 @@
height
);
if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) {
if (bordersStyle.hasRotatingPoint ||
this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) {
var rotateHeight = -height / 2;
@ -181,14 +180,12 @@
* Requires public options: padding, borderColor
* @param {CanvasRenderingContext2D} ctx Context to draw on
* @param {object} options object representing current object parameters
* @param {Object} bordersStyle object to override the object style
* @return {fabric.Object} thisArg
* @chainable
*/
drawBordersInGroup: function(ctx, options) {
if (!this.hasBorders) {
return this;
}
drawBordersInGroup: function(ctx, options, bordersStyle) {
bordersStyle = bordersStyle || {};
var p = this._getNonTransformedDimensions(),
matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX),
wh = fabric.util.transformPoint(p, matrix),
@ -197,8 +194,8 @@
height = wh.y + strokeWidth;
ctx.save();
this._setLineDash(ctx, this.borderDashArray, null);
ctx.strokeStyle = this.borderColor;
this._setLineDash(ctx, bordersStyle.borderDashArray || this.borderDashArray, null);
ctx.strokeStyle = bordersStyle.borderColor || this.borderColor;
ctx.strokeRect(
-width / 2,
@ -216,77 +213,75 @@
* Requires public properties: width, height
* Requires public options: cornerSize, padding
* @param {CanvasRenderingContext2D} ctx Context to draw on
* @param {Object} controlsStyle object to override the object style
* @return {fabric.Object} thisArg
* @chainable
*/
drawControls: function(ctx) {
if (!this.hasControls) {
return this;
}
drawControls: function(ctx, controlsStyle) {
controlsStyle = controlsStyle || {};
var wh = this._calculateCurrentDimensions(),
width = wh.x,
height = wh.y,
scaleOffset = this.cornerSize,
scaleOffset = controlsStyle.cornerSize || this.cornerSize,
left = -(width + scaleOffset) / 2,
top = -(height + scaleOffset) / 2,
methodName = this.transparentCorners ? 'stroke' : 'fill';
methodName = controlsStyle.transparentCorners || this.transparentCorners ? 'stroke' : 'fill';
ctx.save();
ctx.strokeStyle = ctx.fillStyle = this.cornerColor;
ctx.strokeStyle = ctx.fillStyle = controlsStyle.cornerColor || this.cornerColor;
if (!this.transparentCorners) {
ctx.strokeStyle = this.cornerStrokeColor;
ctx.strokeStyle = controlsStyle.cornerStrokeColor || this.cornerStrokeColor;
}
this._setLineDash(ctx, this.cornerDashArray, null);
this._setLineDash(ctx, controlsStyle.cornerDashArray || this.cornerDashArray, null);
// top-left
this._drawControl('tl', ctx, methodName,
left,
top);
top, controlsStyle);
// top-right
this._drawControl('tr', ctx, methodName,
left + width,
top);
top, controlsStyle);
// bottom-left
this._drawControl('bl', ctx, methodName,
left,
top + height);
top + height, controlsStyle);
// bottom-right
this._drawControl('br', ctx, methodName,
left + width,
top + height);
top + height, controlsStyle);
if (!this.get('lockUniScaling')) {
// middle-top
this._drawControl('mt', ctx, methodName,
left + width / 2,
top);
top, controlsStyle);
// middle-bottom
this._drawControl('mb', ctx, methodName,
left + width / 2,
top + height);
top + height, controlsStyle);
// middle-right
this._drawControl('mr', ctx, methodName,
left + width,
top + height / 2);
top + height / 2, controlsStyle);
// middle-left
this._drawControl('ml', ctx, methodName,
left,
top + height / 2);
top + height / 2, controlsStyle);
}
// middle-top-rotate
if (this.hasRotatingPoint) {
if (controlsStyle.hasRotatingPoint || this.hasRotatingPoint) {
this._drawControl('mtr', ctx, methodName,
left + width / 2,
top - this.rotatingPointOffset);
top - this.rotatingPointOffset, controlsStyle);
}
ctx.restore();
@ -297,12 +292,13 @@
/**
* @private
*/
_drawControl: function(control, ctx, methodName, left, top) {
_drawControl: function(control, ctx, methodName, left, top, controlStyle) {
controlStyle = controlStyle || {};
if (!this.isControlVisible(control)) {
return;
}
var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;
switch (this.cornerStyle) {
switch (controlStyle.cornerStyle || this.cornerStyle) {
case 'circle':
ctx.beginPath();
ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);

View file

@ -380,8 +380,10 @@
ctx.save();
ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
this.callSuper('_renderControls', ctx, noTransform);
for (var i = 0, len = this._objects.length; i < len; i++) {
this._objects[i]._renderControls(ctx);
if (this.canvas && this === this.canvas.getActiveGroup()) {
for (var i = 0, len = this._objects.length; i < len; i++) {
this._objects[i]._renderControls(ctx);
}
}
ctx.restore();
},

View file

@ -1308,17 +1308,15 @@
* Renders controls and borders for the object
* @param {CanvasRenderingContext2D} ctx Context to render on
*/
_renderControls: function(ctx) {
if (!this.active || (this.group && this.group !== this.canvas.getActiveGroup())) {
return;
}
_renderControls: function(ctx, bordersStyle, controlsStyle) {
var vpt = this.getViewportTransform(),
matrix = this.calcTransformMatrix(),
options;
matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);
options = fabric.util.qrDecompose(matrix);
if (controlsStyle && bordersStyle) {
bordersStyle.hasRotatingPoint = controlsStyle.hasRotatingPoint;
}
ctx.save();
ctx.translate(options.translateX, options.translateY);
ctx.lineWidth = 1 * this.borderScaleFactor;
@ -1327,13 +1325,13 @@
}
if (this.group && this.group === this.canvas.getActiveGroup()) {
ctx.rotate(degreesToRadians(options.angle));
this.drawBordersInGroup(ctx, options);
(this.hasBorders || bordersStyle) && this.drawBordersInGroup(ctx, options, bordersStyle);
}
else {
ctx.rotate(degreesToRadians(this.angle));
this.drawBorders(ctx);
(this.hasBorders || bordersStyle) && this.drawBorders(ctx, bordersStyle);
}
this.drawControls(ctx);
(this.hasControls || controlsStyle) && this.drawControls(ctx, controlsStyle);
ctx.restore();
},