如何使用fabric.Textbox类重写在Fabric js中创建自定义类? [英] how to make custom class in fabric js using fabric.Textbox Class override?

查看:333
本文介绍了如何使用fabric.Textbox类重写在Fabric js中创建自定义类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 我正在使用FabricJS版本:3.6.3
  2. 我想创建一个名为:Button的新FabricJS类
  3. 因此我从fabric js扩展了一个名为 Textbox 的类,该类将在 Text 绘制一个 Rectangle >,它看起来像一个按钮.
  4. 但是问题在于,我不能将 height 设置为该 Button ,因为 Texbox中不允许使用 height code>对象.
  5. 我想将 Height Width 设置为 Button 对象.由于 Textbox Width 正常工作.如果宽度保持小于文本宽度,它也会扭曲文本,并且可以通过双击对其进行编辑.但是唯一的问题是不能将 Height 设置为 object
  6. Height 增加时,它应该是文本垂直居中.
  1. I am using FabricJS version : 3.6.3
  2. I want to make new FabricJS class called : Button
  3. So that I have extend one class called Textbox from fabric js, which will Draw a Rectangle behind Text and it looking like a button.
  4. But Problem is that, I can't set height to that Button because height is not allow in Texbox object.
  5. I want to set Height and Width to Button object. Width is working Properly due to Textbox. it will also warp Text if width keep smaller then text width, and can be editable by double clicking on it. But only problem is that can't set Height to an object
  6. it should be Text vertically center when Height is increase.

简而言之,我想使用对象自定义在Fabric js中实现这种功能.

In short I want to make this kind of functionality in fabric js using object customization.

预期输出:

实际输出:

这是我创建代码的代码:

Here Is my Code That Create button :

// fabric js custom button class
(function (fabric) {
  "use strict";

  // var fabric = global.fabric || (global.fabric = {});

  fabric.Button = fabric.util.createClass(fabric.Textbox, {
    type: "button",
    stateProperties: fabric.Object.prototype.stateProperties.concat(
      "buttonRx",
      "buttonRy",
      "buttonFill",
      "buttonPadding",
      "buttonStrokeColor",
      "buttonStrokeWidth"
    ),
    buttonRx: 0,
    buttonRy: 0,
    buttonFill: "#ffffff00",
    buttonPadding: 0,
    buttonHeight: 0,
    buttonWidth: 0,
    textAlign: "center",
    buttonStrokeColor: "#000000",
    buttonStrokeWidth: 0,
    _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat(
      "width",
      "fontSize"
    ),
    cacheProperties: fabric.Object.prototype.cacheProperties.concat(
      "buttonRx",
      "buttonRy",
      "buttonFill",
      "buttonPadding",
      "buttonStrokeColor",
      "buttonStrokeWidth"
    ),
    initialize: function (text, options) {
      this.text = text;
      this.callSuper("initialize", text, options);
      /* this.on("scaling", function () {
        console.log('scaling', this.getScaledHeight());
        
        this.set({
          height: this.getScaledHeight(),
          scaleY: 1,
        });
      }); */

      this._initRxRy();
    },

    _initRxRy: function () {
      if (this.buttonRx && !this.buttonRy) {
        this.buttonRy = this.buttonRx;
      } else if (this.buttonRy && !this.buttonRx) {
        this.buttonRx = this.buttonRy;
      }
    },
    /* _setCenter(){

    }, */
    _render: function (ctx) {
      // 1x1 case (used in spray brush) optimization was removed because
      // with caching and higher zoom level this makes more damage than help
      // this.width = this.width * this.scaleX;
      // this.height = this.height * this.scaleY;
      // (this.scaleX = 1), (this.scaleY = 1);
      var rx = this.buttonRx ? Math.min(this.buttonRx, this.width / 2) : 0,
        ry = this.buttonRy ? Math.min(this.buttonRy, this.height / 2) : 0,
        w = this.width + this.buttonPadding,
        h = this.height + this.buttonPadding,
        x = -this.width / 2 - this.buttonPadding / 2,
        y = -this.height / 2 - this.buttonPadding / 2,
        isRounded = rx !== 0 || ry !== 0,
        /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */
        k = 1 - 0.5522847498;
      ctx.beginPath();

      ctx.moveTo(x + rx, y);

      ctx.lineTo(x + w - rx, y);
      isRounded &&
        ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);

      ctx.lineTo(x + w, y + h - ry);
      isRounded &&
        ctx.bezierCurveTo(
          x + w,
          y + h - k * ry,
          x + w - k * rx,
          y + h,
          x + w - rx,
          y + h
        );

      ctx.lineTo(x + rx, y + h);
      isRounded &&
        ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);

      ctx.lineTo(x, y + ry);
      isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);

      ctx.closePath();
      ctx.save();
      if (this.buttonFill) {
        ctx.fillStyle = this.buttonFill;
        if (this.fillRule === "evenodd") {
          ctx.fill("evenodd");
        } else {
          ctx.fill();
        }
      }
      if (this.buttonStrokeWidth > 0) {
        if (this.strokeUniform) {
          ctx.scale(1 / this.scaleX, 1 / this.scaleY);
        }
        if (this.shadow && !this.shadow.affectStroke) {
          this._removeShadow(ctx);
        }
        if (this.buttonStrokeColor) {
          ctx.lineWidth = this.buttonStrokeWidth;
          ctx.strokeStyle = this.buttonStrokeColor;
          ctx.stroke();
        } else {
          ctx.lineWidth = this.buttonStrokeWidth;
          ctx.stroke();
        }
      }
      ctx.restore();

      this.clearContextTop();
      this._clearCache();
      this.height = this.calcTextHeight();
      this.saveState({ propertySet: "_dimensionAffectingProps" });
      //   this._renderPaintInOrder(ctx);

      this._setTextStyles(ctx);
      this._renderTextLinesBackground(ctx);
      this._renderTextDecoration(ctx, "underline");
      this._renderText(ctx);
      this._renderTextDecoration(ctx, "overline");
      this._renderTextDecoration(ctx, "linethrough");
      this.initDimensions();
      // this.callSuper('render', ctx);
    },
    toObject: function (propertiesToInclude) {
      return this.callSuper(
        "toObject",
        [
          "buttonRx",
          "buttonRy",
          "buttonFill",
          "buttonPadding",
          "buttonStrokeColor",
          "buttonStrokeWidth",
          "objectCaching",
        ].concat(propertiesToInclude)
      );
    },
  });

  fabric.Button.fromObject = function (object, callback) {
    return fabric.Object._fromObject("Button", object, callback, "text");
  };
})(fabric);

// fabric js class finish here


var canvas = [];
var cotainer = document.getElementById("canvas-container");
for (let i = 0; i < 1; i++) {
  var width = 500,
    height = 500;
  var canvasEl = document.createElement("canvas");
  canvasEl.id = "canvas-" + i;
  cotainer.append(canvasEl);
  var fabCanvas = new fabric.Canvas(canvasEl, {});
  fabCanvas.setHeight(height);
  fabCanvas.setWidth(width);
  canvas.push(fabCanvas);
}

canvas.forEach((c) => {
  var button = new fabric.Button("Click Me", {
    text: "Click Me",
    buttonStrokeColor: "#f00",
    buttonStrokeWidth: 2,
    width: 110,
    fill: "#f00",
    fontSize: 50,
    width: 400,
    buttonFill: "#42A5F5",
    buttonRx: 15,
    buttonRy: 15,
    objectCaching: false,
    fontFamily: "verdana",
  });
  c.add(button);
  c.renderAll();
});

canvas{
border: 1px solid black
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.2/fabric.js"></script>
<div id="canvas-container">
</div>

推荐答案

解决方案是在缩放按钮对象时将按钮文本的scaleX和scaleY设置为1,并且将文本的字体大小设置为.它的规模.

The solution will be to set the scaleX and scaleY of the button text to 1 when you scale the Button Object and also set the font size of the text equal to its scale.

这篇关于如何使用fabric.Textbox类重写在Fabric js中创建自定义类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆