如何使用fabric.Textbox类覆盖在fabric js中制作自定义类? [英] how to make custom class in fabric js using fabric.Textbox Class override?

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

问题描述

  1. 我使用的是 FabricJS 版本:3.6.3
  2. 我想创建一个名为 Button 的新 FabricJS 类
  3. 所以我从 fabric js 扩展了一个名为 Textbox 的类,它将在 Text绘制一个 Rectangle> 它看起来像一个按钮.
  4. 但问题是,我不能将 height 设置为那个 Button 因为 heightTexbox对象.
  5. 我想将 HeightWidth 设置为 Button 对象.由于 TextboxWidth 工作正常.如果宽度保持小于文本宽度,它也会扭曲文本,并且可以通过双击它进行编辑.但唯一的问题是不能将 Height 设置为 object
  6. Height增加时应该是Text垂直居中.
  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天全站免登陆