How can i change the rotation icon in fabricjs

2019-02-15 05:43发布

Please guide me to modify Fabricjs to add custom icon for Rotation.

I get some of the answers but it is not working fine.

Please let me know the code to change a particular rotation icon only.

6条回答
姐就是有狂的资本
2楼-- · 2019-02-15 06:25

the problem with image not showing until you move is because image load is asynchronous. Inline it with data url:

image.src = 'data:image/png;base64 .... ';
查看更多
相关推荐>>
3楼-- · 2019-02-15 06:29

I know this is a pretty old question, but for anyone looking for an easier solution:

https://github.com/pixolith/fabricjs-customise-controls-extension

This plugin is up to date and works perfect for me. You won't have to override the internal logic of fabric js and it's therefor safer to use.

查看更多
混吃等死
4楼-- · 2019-02-15 06:38

For fabricjs above 1.6.6 changing function object prototype drawControls, small changes on hasRotation condition, result can be seen this JSFidle

fabric.Object.prototype.drawControls = function (ctx) {

  if (!this.hasControls) {
    return this;
  }

  var wh = this._calculateCurrentDimensions(),
  width = wh.x,
  height = wh.y,
  scaleOffset = this.cornerSize,
  left = -(width + scaleOffset) / 2,
  top = -(height + scaleOffset) / 2,
  methodName = this.transparentCorners ? 'stroke' : 'fill';

  ctx.save();
  ctx.strokeStyle = ctx.fillStyle = this.cornerColor;
  if (!this.transparentCorners) {
    ctx.strokeStyle = this.cornerStrokeColor;
  }
 this._setLineDash(ctx, this.cornerDashArray, null);

  // top-left
 this._drawControl('tl', ctx, methodName,left,top);

 // top-right
this._drawControl('tr', ctx, methodName, left + width,top);

// bottom-left
this._drawControl('bl', ctx, methodName,left, top + height);

// bottom-right
this._drawControl('br', ctx, methodName,left + width,top + height);

if (!this.get('lockUniScaling')) {

// middle-top
this._drawControl('mt', ctx, methodName,
  left + width / 2,
  top);

// middle-bottom
this._drawControl('mb', ctx, methodName,
  left + width / 2,
  top + height);

// middle-right
this._drawControl('mr', ctx, methodName,
  left + width,
  top + height / 2);

// middle-left
this._drawControl('ml', ctx, methodName,
  left,
  top + height / 2);
}

// middle-top-rotate
if (this.hasRotatingPoint) {
  var rotate = new Image(), rotateLeft, rotateTop;
  rotate.src = 'http://localhost:8000/images/toolbar/close.svg';
  rotateLeft = left + width / 2;
  rotateTop = top - this.rotatingPointOffset;
  ctx.drawImage(rotate, rotateLeft, rotateTop, 10, 15);
}

ctx.restore();

return this;

}
查看更多
We Are One
5楼-- · 2019-02-15 06:38

Change fabric object prototype "drawControls" like this.

Here is an example and JSFiddle:

fabric.Object.prototype.drawControls = function (ctx) {
    if (!this.hasControls) return this;


    var size = this.cornerSize,
        size2 = size / 2,
        strokeWidth2 = ~~(this.strokeWidth / 2), // half strokeWidth rounded down
        left = -(this.width / 2),
        top = -(this.height / 2),
        paddingX = this.padding / this.scaleX,
        paddingY = this.padding / this.scaleY,
        scaleOffsetY = size2 / this.scaleY,
        scaleOffsetX = size2 / this.scaleX,
        scaleOffsetSizeX = (size2 - size) / this.scaleX,
        scaleOffsetSizeY = (size2 - size) / this.scaleY,
        height = this.height,
        width = this.width,
        methodName = this.transparentCorners ? 'strokeRect' : 'fillRect';

    ctx.save();

    ctx.lineWidth = 1 / Math.max(this.scaleX, this.scaleY);

    ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
    ctx.strokeStyle = ctx.fillStyle = this.cornerColor;

    // top-left
    this._drawControl('tl', ctx, methodName,
        left - scaleOffsetX - strokeWidth2 - paddingX,
        top - scaleOffsetY - strokeWidth2 - paddingY);

    // top-right
    this._drawControl('tr', ctx, methodName,
        left + width - scaleOffsetX + strokeWidth2 + paddingX,
        top - scaleOffsetY - strokeWidth2 - paddingY);

    // bottom-left
    this._drawControl('bl', ctx, methodName,
        left - scaleOffsetX - strokeWidth2 - paddingX,
        top + height + scaleOffsetSizeY + strokeWidth2 + paddingY);

    // bottom-right
    this._drawControl('br', ctx, methodName,
        left + width + scaleOffsetSizeX + strokeWidth2 + paddingX,
        top + height + scaleOffsetSizeY + strokeWidth2 + paddingY);

    if (!this.get('lockUniScaling')) {

        // middle-top
        this._drawControl('mt', ctx, methodName,
            left + width / 2 - scaleOffsetX,
            top - scaleOffsetY - strokeWidth2 - paddingY);

        // middle-bottom
        this._drawControl('mb', ctx, methodName,
            left + width / 2 - scaleOffsetX,
            top + height + scaleOffsetSizeY + strokeWidth2 + paddingY);

        // middle-right
        this._drawControl('mr', ctx, methodName,
            left + width + scaleOffsetSizeX + strokeWidth2 + paddingX,
            top + height / 2 - scaleOffsetY);

        // middle-left
        this._drawControl('ml', ctx, methodName,
            left - scaleOffsetX - strokeWidth2 - paddingX,
            top + height / 2 - scaleOffsetY);
    }

    // middle-top-rotate
    if (this.hasRotatingPoint) {
        /*
         We dont need old corner for rotate :)

         this._drawControl('mtr', ctx, methodName,
         left + width/2 - scaleOffsetX,
         this.flipY
         ? (top + height + (this.rotatingPointOffset / this.scaleY) - this.cornerSize/this.scaleX/2 + strokeWidth2 + paddingY)
         : (top - (this.rotatingPointOffset / this.scaleY) - this.cornerSize/this.scaleY/2 - strokeWidth2 - paddingY));

         Draw rotate custom icon
         */
        var rotate = new Image(), rotateLeft, rotateTop;
        rotate.src = 'http://www.navifun.net/files/pins/tiny/Arrow-Rotate-Clockwise.png';

        rotateLeft = left + width / 2 - scaleOffsetX;
        rotateTop = this.flipY
            ? (top + height + (this.rotatingPointOffset / this.scaleY) - this.cornerSize / this.scaleX / 2 + strokeWidth2 + paddingY)
            : (top - (this.rotatingPointOffset / this.scaleY) - this.cornerSize / this.scaleY / 2 - strokeWidth2 - paddingY);

        ctx.drawImage(rotate, rotateLeft, rotateTop, size / this.scaleX, size / this.scaleY);


    }

    ctx.restore();

    return this;
};
查看更多
\"骚年 ilove
6楼-- · 2019-02-15 06:38

@hlozancic's answer overrides a big important part of the prototype. Monkey patching libraries maintained by a community doesn't sit well with me, since the code in those methods could change (and, in fact drawControls has changed since July 2nd), without my knowing. Here is an alternative that I prefer:

var _original = fabric.Object.prototype._drawControl;
fabric.Object.prototype._drawControl = function(control, ctx, methodName, left, top) {
  var size = this.cornerSize;

  if (this.canvas.hasControlCallback && this.canvas.hasControlCallback[control]) {
    this.canvas.controlCallback[control](ctx, left, top, size);
  } else {
    _original.call(this, control, ctx, methodName, left, top);
  }
};

/* then, when instantiating your fabric canvas  */

var canvas = new fabric.Canvas();

/* callbacks for drawing the controls */
canvas.hasControlCallback = {
    mtr: true
};

canvas.controlCallback = {
    mtr: function mtrControlCallback (ctx, left, top, size) {
        var image = new Image(), x, y;

        image.src = 'http://www.navifun.net/files/pins/tiny/Arrow-Rotate-Clockwise.png';
        x = left - image.width/2 + size/2;
        y = top - image.height/2 + size/2;

        ctx.drawImage(image, x, y);
    }
};

Apologies for not providing a fiddle, and please be aware of the date of this writing.

查看更多
Evening l夕情丶
7楼-- · 2019-02-15 06:39

This code works in Edge ,Chrome , FireFox, Try this, or You can copy the function from core js library file and then you can replace the ctx.drawImage function

 fabric.Object.prototype.drawControls = function (ctx) {
            if (!this.hasControls) {
                return this;
            }
            var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName = this.transparentCorners ? "stroke" : "fill";
            ctx.save();
            ctx.strokeStyle = ctx.fillStyle = this.cornerColor;
            if (!this.transparentCorners) {
                ctx.strokeStyle = this.cornerStrokeColor;
            }
            this._setLineDash(ctx, this.cornerDashArray, null);
            this._drawControl("tl", ctx, methodName, left, top);
            this._drawControl("tr", ctx, methodName, left + width, top);
            this._drawControl("bl", ctx, methodName, left, top + height);
            this._drawControl("br", ctx, methodName, left + width, top + height);
            if (!this.get("lockUniScaling")) {
                this._drawControl("mt", ctx, methodName, left + width / 2, top);
                this._drawControl("mb", ctx, methodName, left + width / 2, top + height);
                this._drawControl("mr", ctx, methodName, left + width, top + height / 2);
                this._drawControl("ml", ctx, methodName, left, top + height / 2);
            }
            if (this.hasRotatingPoint) {
                this._drawControl("mtr", ctx, methodName, left + width / 2, top - this.rotatingPointOffset);
                var rotate = new Image(), rotateLeft, rotateTop;
                rotate.src = rotate_icon;
                rotateLeft = left + width / 2;
                rotateTop = top - this.rotatingPointOffset;
                ctx.drawImage(rotate, rotateLeft-3, rotateTop-1, 18, 18);

            }
            ctx.restore();
            return this;
        };
查看更多
登录 后发表回答