fabric 按钮

查了半天,没有直接的按钮,得自己画。。。

使用 rect + text ,组成 group 模拟按钮

import { fabric } from 'fabric';

/**
 * 按钮
 */
export class Button {
    isScaling = false;
    constructor(canvas) {
        // 绘制图形
        let rect = new fabric.Rect(Button.defaultButton());
        let text = new fabric.Text('Button', Button.defaultText());
        let group = new fabric.Group([ rect, text ], Button.defaultPosition());
        canvas.add(group);
        group.on('mousedown', (e) => {
            console.log('click');
        })
        group.on('mouseup', (e) => {
            if (this.isScaling) {
                let scaleX = group.scaleX;
                let scaleY = group.scaleY;
                group.set({
                    width: group.width * scaleX,
                    height: group.height * scaleY,
                    scaleX: 1,
                    scaleY: 1,
                });
                group.item(0).set({
                    width: group.width,
                    height: group.height,
                    top: -group.height * 0.5,
                    left: -group.width * 0.5,
                    rx: rect.rx * scaleX,
                    ry: rect.ry * scaleY,
                });
                group.item(1).set({
                   text: 'Button' + parseInt((Math.random() * 10))
                });
                this.setAlign(text, 'center', 'center');
                canvas.renderAll();
                this.isScaling = false;
            }
        });
        // group.item(1).set({ fontSize: 20 }); // 可直接修改字体大小,无问题
        // 重置元素宽度,
        // rect.set({ width: 200 });
        // 删了重新添加组
        // canvas.remove(group);
        // canvas.add(new fabric.Group([ rect, text ], Button.defaultPosition()));
        // 同样需要重新绑定事件
        canvas.on('object:scaling', (e) => {
            this.isScaling = true;
        });
        this.setAlign(text, 'center', 'center');
        canvas.renderAll();
    }

    /**
     * 设置居中位置
     * @param text 文本信息
     * @param ho 水平 left center right
     * @param ve 垂直 top center bottom
     */
    setAlign(text, ho, ve) {
        let left, top;
        switch(ho) {
            case 'left':
                left = -text.group.width * 0.5 + 10;
                break;
            case 'center':
                left = -text.width * 0.5;
                break;
            case 'right':
                left = text.group.width * 0.5 - text.width - 10;
                break;
        }
        switch(ve) {
            case 'top':
                top = -text.group.height * 0.5;
                break;
            case 'center':
                top = -text.height * 0.5;
                break;
            case 'bottom':
                top = text.group.height * 0.5 - text.height;
                break;
        }
        text.set({
            left: left,
            top: top,
        });
    }

    static defaultButton() {
        return {
            width: 160,
            height: 60,
            fill: '#5570C4', // 背景色
            rx: 10,
            ry: 10,
            stroke: '#ddd', // 边框颜色
            strokeWidth: 1, // 边框粗细
        }
    }

    static defaultText() {
        return {
            fill: '#fff',
            fontSize: 30,
            lockScalingX: true, // “true”时,对象水平缩放被锁定
            lockScalingY: true, // “true”时,对象垂直缩放被锁定
        };
    }

    static defaultPosition() {
        return {
            left: 100,
            top: 100,
            // selectable: false, // 是否可交互
            angle: 45,
        }
    }
}

 

posted @ 2022-04-25 17:24  名字不好起啊  阅读(57)  评论(0编辑  收藏  举报