我正在尝试渲染一个在底部具有旋转点的框。通常,我们可以渲染具有属性hasRotatingPoint: true
的框,并且在框的顶部会出现一个手柄,以供用户旋转。
我想要在框的底部绘制它。
这可以通过设置angle: 180
来实现,并且旋转点将出现在底部(当我们将盒子旋转180°时),但是我遇到了这种方法的绘制问题:绘制过程也旋转了180°现在我在绘画时,盒子的方向相反。
在此先感谢您的帮助!
编辑1
How to change Rotating point position to bottom in FabricJS?对此问题有一个非常相似的问题,但是接受的解决方案在我的上下文中会造成另一个错误,如第三段所述。
答案 0 :(得分:1)
您需要重写3个功能。 fabric.Object.prototype.calcCoords
,fabric.Object.prototype.drawControls
,fabric.Object.prototype.drawControls
这3个几乎相同,唯一的不同是mtr点的计算方式不同。
fabric.Object.prototype.calcCoords= function(absolute) {
var rotateMatrix = this._calcRotateMatrix(),
translateMatrix = this._calcTranslateMatrix(),
startMatrix = fabric.util.multiplyTransformMatrices(translateMatrix, rotateMatrix),
vpt = this.getViewportTransform(),
finalMatrix = absolute ? startMatrix : fabric.util.multiplyTransformMatrices(vpt, startMatrix),
dim = this._getTransformedDimensions(),
w = dim.x / 2, h = dim.y / 2,
tl = fabric.util.transformPoint({ x: -w, y: -h }, finalMatrix),
tr = fabric.util.transformPoint({ x: w, y: -h }, finalMatrix),
bl = fabric.util.transformPoint({ x: -w, y: h }, finalMatrix),
br = fabric.util.transformPoint({ x: w, y: h }, finalMatrix);
if (!absolute) {
var padding = this.padding, angle = fabric.util.degreesToRadians(this.angle),
cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),
cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,
cosPMinusSinP = cosP - sinP;
if (padding) {
tl.x -= cosPMinusSinP;
tl.y -= cosPSinP;
tr.x += cosPSinP;
tr.y -= cosPMinusSinP;
bl.x -= cosPSinP;
bl.y += cosPMinusSinP;
br.x += cosPMinusSinP;
br.y += cosPSinP;
}
var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),
mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),
mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),
mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),
mtr = new fabric.Point(mb.x - sin * this.rotatingPointOffset, mb.y + cos * this.rotatingPointOffset);
}
// if (!absolute) {
// var canvas = this.canvas;
// setTimeout(function() {
// canvas.contextTop.clearRect(0, 0, 700, 700);
// canvas.contextTop.fillStyle = 'green';
// canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);
// canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);
// canvas.contextTop.fillRect(br.x, br.y, 3, 3);
// canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);
// canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);
// canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);
// canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);
// canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);
// canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);
// }, 50);
// }
var coords = {
// corners
tl: tl, tr: tr, br: br, bl: bl,
};
if (!absolute) {
// middle
coords.ml = ml;
coords.mt = mt;
coords.mr = mr;
coords.mb = mb;
// rotating point
coords.mtr = mtr;
}
return coords;
}
fabric.Object.prototype.drawControls=function(ctx, styleOverride) {
styleOverride = styleOverride || {};
var wh = this._calculateCurrentDimensions(),
width = wh.x,
height = wh.y,
scaleOffset = styleOverride.cornerSize || this.cornerSize,
left = -(width + scaleOffset) / 2,
top = -(height + scaleOffset) / 2,
transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?
styleOverride.transparentCorners : this.transparentCorners,
hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?
styleOverride.hasRotatingPoint : this.hasRotatingPoint,
methodName = transparentCorners ? 'stroke' : 'fill';
ctx.save();
ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;
if (!this.transparentCorners) {
ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;
}
this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);
// top-left
this._drawControl('tl', ctx, methodName,
left,
top, styleOverride);
// top-right
this._drawControl('tr', ctx, methodName,
left + width,
top, styleOverride);
// bottom-left
this._drawControl('bl', ctx, methodName,
left,
top + height, styleOverride);
// bottom-right
this._drawControl('br', ctx, methodName,
left + width,
top + height, styleOverride);
if (!this.get('lockUniScaling')) {
// middle-top
this._drawControl('mt', ctx, methodName,
left + width / 2,
top, styleOverride);
// middle-bottom
this._drawControl('mb', ctx, methodName,
left + width / 2,
top + height, styleOverride);
// middle-right
this._drawControl('mr', ctx, methodName,
left + width,
top + height / 2, styleOverride);
// middle-left
this._drawControl('ml', ctx, methodName,
left,
top + height / 2, styleOverride);
}
// middle-top-rotate
if (hasRotatingPoint) {
this._drawControl('mtr', ctx, methodName,
left + width / 2,
top + height + this.rotatingPointOffset, styleOverride);
}
ctx.restore();
return this;
}
fabric.Object.prototype.drawBorders=function(ctx, styleOverride) {
styleOverride = styleOverride || {};
var wh = this._calculateCurrentDimensions(),
strokeWidth = 1 / this.borderScaleFactor,
width = wh.x + strokeWidth,
height = wh.y + strokeWidth,
drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?
styleOverride.hasRotatingPoint : this.hasRotatingPoint,
hasControls = typeof styleOverride.hasControls !== 'undefined' ?
styleOverride.hasControls : this.hasControls,
rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== 'undefined' ?
styleOverride.rotatingPointOffset : this.rotatingPointOffset;
ctx.save();
ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);
ctx.strokeRect(
-width / 2,
-height / 2,
width,
height
);
if (drawRotatingPoint && this.isControlVisible('mtr') && hasControls) {
var rotateHeight = height / 2;
ctx.beginPath();
ctx.moveTo(0, rotateHeight);
ctx.lineTo(0, rotateHeight + rotatingPointOffset);
ctx.stroke();
}
ctx.restore();
return this;
}
body {
background-color: ivory;
padding:20px;
}
#canvas {
border:1px solid red;
}
<canvas id="canvas" width="666" height="444"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.0.0/fabric.js"></script>
<script>
var obj = new fabric.Triangle({
fill: 'lime',
top: 110,
left: 110,
borderColor: 'red',
cornerColor: 'cyan',
cornerSize: 9,
transparentCorners: false
});
var canvas = new fabric.Canvas('canvas');
canvas.add(obj);
</script>