【问题标题】:FabricJS - change the anchor side of the rotating pointFabricJS - 改变旋转点的锚边
【发布时间】:2019-10-21 05:48:02
【问题描述】:

我正在尝试渲染一个底部带有旋转点的框。通常,我们可以渲染一个带有hasRotatingPoint: true 属性的盒子,并且盒子的顶部会出现一个手柄,以便用户旋转它。

我想要的是把它画在盒子的底部。

这可以通过 set angle: 180 来实现,旋转点将出现在底部(当我们将盒子旋转 180° 时)但我遇到了这种方法的绘制问题:绘制过程也旋转了 180°,现在当我画画时,我的盒子朝相反的方向移动。

提前感谢您的帮助!

编辑 1

How to change Rotating point position to bottom in FabricJS? 这里有一个关于这个问题的非常相似的问题,但接受的解决方案在我的上下文中创建了另一个错误,如第三段所述。

【问题讨论】:

    标签: rotation fabricjs fabricjs2


    【解决方案1】:

    你需要重写 3 个函数。 fabric.Object.prototype.calcCoords, fabric.Object.prototype.drawControls, fabric.Object.prototype.drawBorders 这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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多