Javascript 如何更改fabricjs中的旋转图标

Javascript 如何更改fabricjs中的旋转图标,javascript,html,fabricjs,Javascript,Html,Fabricjs,请指导我修改Fabricjs以添加用于旋转的自定义图标 我得到了一些答案,但效果不好 请告诉我仅更改特定旋转图标的代码。像这样更改织物对象原型“drawControls” 以下是一个示例和示例: @hlozancic的回答覆盖了原型的一个重要部分。社区维护的猴子补丁库对我来说并不合适,因为这些方法中的代码可能会在我不知道的情况下发生变化(事实上,drawControls自7月2日以来已经发生了变化)。以下是我更喜欢的一种选择: var _original = fabric.Object.prot

请指导我修改Fabricjs以添加用于旋转的自定义图标

我得到了一些答案,但效果不好


请告诉我仅更改特定旋转图标的代码。

像这样更改织物对象原型“drawControls”

以下是一个示例和示例:


@hlozancic的回答覆盖了原型的一个重要部分。社区维护的猴子补丁库对我来说并不合适,因为这些方法中的代码可能会在我不知道的情况下发生变化(事实上,
drawControls
自7月2日以来已经发生了变化)。以下是我更喜欢的一种选择:

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);
    }
};

很抱歉没有提供小提琴,请注意本文的写作日期。

移动前图像不显示的问题是因为图像加载是异步的。将其与数据url内联:

image.src = 'data:image/png;base64 .... ';

对于1.6.6以上的fabricjs,改变函数对象原型drawControls,hasRotation条件的微小变化,结果如下所示


我知道这是一个很老的问题,但对于任何想寻求更简单解决方案的人来说:


这个插件是最新的,非常适合我。您不必重写fabric js的内部逻辑,因此使用起来更安全。

此代码适用于Edge、Chrome、FireFox,试试这个,或者 您可以从core js库文件复制该函数,然后替换ctx.drawImage函数

 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;
        };

随着2020年8月v4.0的发布,Fabric.js现在包含了一个完整的控件自定义系统,这使得旋转控件的样式设置非常简单

var canvas=newfabric.canvas('c');
//在此将图标设置为base64字符串
变量旋转=数据:image/svg+xml;base64,PHN2ZYB4BWXUCZ0IJ48CGF0ACBKPSJNMCAWADI0DJI0SDB6IIBMAWXSPSJub25Li8+PHBHDGGZD0ITTEYDZ2M2W0LTQTNC00DJLTJ0D9IJ0D9IJ0IJ48CGF0ACBKPSJNMCAWADI0DJI0I0L2L2L8L6L6LZDZD2W0LZDZD2LZD2W0LZD9IJ0D9IJ0D9IJJ0IJJJ0I48CGF0ACB4B9J0D9IJ0D9I0D9IJ0D9IJ0D9I0D4C0D4C0D4C0D4C0D4C0D4C0D4C0D4C0D4C0D4C0D4C0D4C0D4CY40NC44NC43IdeunzkunyaylJGmcazljmxltiunjgnni02Idz2LtnsTqgnca0Id2LtnJnc40 miawidgtmy41oca4ltggmc0xlju3Ls40ni0zljazlteumjTqtnc4ynnoilz48l3n2zz4=“;
var img=document.createElement('img');
img.src=旋转;
//这里是自定义旋转控件的定义位置
//通过更改值,可以自定义控件的位置、大小、外观和行为
fabric.Object.prototype.controls.mtr=新fabric.Control({
x:0,,
y:-0.5,
副职:-40,
光标样式:“十字线”,
actionHandler:fabric.controlsUtils.RotationWithNapping,
actionName:'旋转',
渲染:renderIcon,
尺寸:28,
withConnection:正确
});
//这里定义了控件的渲染操作
函数renderIcon(ctx、左、上、样式覆盖、FabriObject){
var size=此.cornerSize;
ctx.save();
ctx.translate(左,上);
ctx.旋转(织物使用度弧度(织物对象角度));
ctx.drawImage(img,-size/2,-size/2,size,size);
ctx.restore();
}
var rect=new fabric.rect({
左:50,,
前70名,
填充:“红色”,
宽度:200,
身高:100,
objectCaching:false,
笔划:“蓝色”,
冲程宽度:4,
});
canvas.add(rect);
canvas.setActiveObject(rect);


请有人为我提供相同的指导。相关控制包括:tl、tr、br、bl、ml、mt、mr、mb、mtr,用于“左上”、“右上”、“中上旋转”“。还要注意,这不会改变控件本身的大小:每个控件的可单击区域仍然是一个矩形。加载旋转图标工作正常,但仅在移动对象时显示,一旦我们添加了对象,就可以显示问题了吗?通过第一次加载就可以看到,只有rest很好。我想你链接到implements@hlozancic答案的小提琴,不是我的。也许他能更好地回答有关这方面的问题。2019年,这个答案是否仍然成立?
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;

}
 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;
        };