fabric button 通过子类实现

创建 button 类:

import { fabric } from 'fabric';

/**
 * 继承并扩展 rect ,实现:text + rect 的类 button 组
 */
export class Button {
    button;

    constructor(config) {
        fabric.Button = fabric.util.createClass(fabric.Rect, {
            type: 'LabelRect',
            initialize: function (options) {
                options || (options = {});
                this.callSuper('initialize', options);
                this.set('id', options.id || '');
                this.set('label', options.label || '');
                this.set('fontColor', options.fontColor || '');
                this.set('fontSize', options.fontSize || '');
                this.set('fontFamily', options.fontFamily || '');
                this.set('fontWeight', options.fontWeight || '');
                this.set('fontStyle', options.fontStyle || '');
                this.set('fontVertical', options.fontVertical || '');
                this.set('fontHorizontal', options.fontHorizontal || '');
            },
            toObject: function () {
                return fabric.util.object.extend(this.callSuper('toObject'), {
                    id: this.get('id'),
                    label: this.get('label'),
                    fontColor: this.get('fontColor'),
                    fontSize: this.get('fontSize'),
                    fontFamily: this.get('fontFamily'),
                    fontWeight: this.get('fontWeight'),
                    fontStyle: this.get('fontStyle'),
                    fontVertical: this.get('fontVertical'),
                    fontHorizontal: this.get('fontHorizontal'),
                });
            },
            _render: function (ctx) {
                this.callSuper('_render', ctx);
                ctx.font = `${ this.fontStyle } ${ this.fontWeight } ${ this.fontSize }px ${ this.fontFamily }`;
                ctx.fillStyle = this.fontColor;
                let x, y;
                // 计算水平
                switch (this.fontHorizontal) {
                    case 'left':
                        ctx.textAlign = 'left';
                        x = -(this.width - this.rx) / 2;
                        break;
                    case 'center':
                        ctx.textAlign = 'center';
                        x = 0;
                        break;
                    case 'right':
                        ctx.textAlign = 'right';
                        x = (this.width - this.rx) / 2;
                        break;
                }
                // 计算垂直
                switch (this.fontVertical) {
                    case 'top':
                        y = -(this.height - this.ry) / 2;
                        ctx.textBaseline = 'top';
                        break;
                    case 'center':
                        y = 1;
                        ctx.textBaseline = 'middle';
                        break;
                    case 'bottom':
                        y = (this.height) / 2;
                        ctx.textBaseline = 'bottom';
                        break;
                }
                ctx.fillText(this.label, x, y);
            }
        });return new fabric.Button(config);
    }

    static defaultButton() {
        return {
            width: 160,
            height: 60,
            fill: '#5570C4', // 背景色
            rx: 10, // 圆角
            ry: 10, // 圆角
            left: 100,
            top: 100,
            label: 'Button',
            fontVertical: 'center', // 垂直 top center bottom
            fontHorizontal: 'center', // 水平 left center right
            fontSize: 20,
            fontWeight: 'normal', // 文字粗细 normal bold 或者数字(100,200,400,600,800)
            fontStyle: 'normal', // 字体风格 normal  italic
            fontFamily: 'Helvetica',
            fontColor: '#fff',
            stroke: '#ddd', // 边框颜色
            strokeWidth: 1, // 边框粗细
            angle: 0,
            id: Math.random(),
        }
    }
}

 

调用:

import { Button } from "./class/button";

/**
 * 测试 Button 类
 */
export class LabelRect {
    isScaling = false;
    constructor(canvas) {
        // 创建 button 对象
        let button = new Button(Button.defaultButton());
        canvas.add(button);
        button.set('label', 'Button' + Math.random());
        // 绑定事件
        this.bindEvents(canvas, button);
    }

    /**
     * 绑定事件
     * @param canvas
     * @param button
     */
    bindEvents(canvas, button) {
        canvas.on('mouse:dblclick', (e) => {
            if (e.target && e.target.id === button.id) {
                console.log('dblclick');
            }
        });
        button.on('mousedown', (e) => {
            console.log('mousedown');
        });
        button.on('mouseover', (e) => {
            console.log('mouseover');
        });
        button.on('mouseout', (e) => {
            console.log('mouseout');
        });
        button.on('mouseup', (e) => {
            console.log('mouseup');
            if (this.isScaling) {
                let scaleX = button.scaleX;
                let scaleY = button.scaleY;
                button.set({
                    width: button.width * scaleX,
                    height: button.height * scaleY,
                    rx: button.rx * scaleX,
                    ry: button.ry * scaleY,
                    scaleX: 1,
                    scaleY: 1,
                });
                canvas.renderAll();
                this.isScaling = false;
            }
        });
        canvas.on('object:scaling', (e) => {
            this.isScaling = true;
        });
    }
}

 

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