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