UNPKG

@cataract6545/tmui

Version:

tm-vuetify是一个新势力由主题驱动的UI组件库,相比其它优势大,组件全,设计趋势紧跟未来。具有主题生成,主题实时切换,暗黑实时切换,lottie动画,图表等新颖功能,tmui TMUI

140 lines (132 loc) 5.63 kB
import { tmCv } from "."; import { color } from "./color"; import { shapeStyle } from "./interface"; import { division, addition, multiply, subtract, uuid } from "./util"; export class Shape { id: string = uuid(16) x: number = 0; y: number = 0; width: number = 0; height: number = 0; fillStyle: string = 'rgba(0,0,0,0)'; strokeStyle: string = 'rgba(0,0,0,0)'; lineWidth: number = 0; lineDashOffset: number = 0 lineDash: number[] = [0] sAngle: number = 0 eAngle: number = 0 radius: [number, number, number, number] = [0, 0, 0, 0] /**一些圆弧等用到的内半径 */ r: number = 0 /**圆环时可能用到的内半径 */ innerRadius: number = 0 lineCap: any = 'round' lineJoin: any = 'round' textMaxWidth: number = 0 /** 字符间距不支持断行 */ letterSpace: number = 0 text: string = '' playing: boolean = false; fontSize: number = 14 textAlign: 'left' | 'right' | 'center' = 'left' canvas: tmCv constructor(tmcv: tmCv, arg: Partial<shapeStyle>) { for (const item in arg) { // @ts-expect-error this[item] = arg[item] // @ts-expect-error this['back_' + item] = arg[item] } this.canvas = tmcv; this.draw() } /**绘制 */ draw<T>(arg?: shapeStyle) { return this } /**动画 */ public animate(arg: Partial<shapeStyle>, animateConfig?: { /**动画时长 */ duration?: number, /**重复次数 */ repeat?: number, /**是否来回动画0-1,1-0这样的过渡效果 */ yoyo?: boolean }) { const config = { duration: 500, repeat: 0, yoyo: false, onStart: () => { }, ...(animateConfig || {}) } this.playing = true; return this.canvas.animation(config, (progress: number) => { // 计算动画过程中矩形的位置和颜色 let { x, y, width, height, radius, eAngle, sAngle, textMaxWidth, letterSpace, fontSize } = this; if (typeof arg.x !== 'undefined') { const baseX = this['back_x'] ?? 0; x = baseX + Number(arg.x - baseX) * progress } if (typeof arg.y !== 'undefined') { const baseY = this['back_y'] ?? 0; y = baseY + Number(arg.y - baseY) * progress } if (typeof arg.width !== 'undefined') { const baseWidth = this['back_width'] ?? 0; width = baseWidth + Math.abs((arg.width - baseWidth) * (progress)) } if (typeof arg.width !== 'undefined') { const baseHeight = this['back_height'] ?? 0; height = baseHeight + Math.abs((arg.height - baseHeight) * (progress)) } if (typeof arg.radius !== 'undefined' && radius) { this.radius = multiply(arg.radius, progress) } if (typeof arg.eAngle !== 'undefined' && eAngle) { this.eAngle = Number(arg.eAngle) * progress } if (typeof arg.sAngle !== 'undefined' && sAngle) { this.sAngle = Number(arg.sAngle) * progress } if (typeof arg?.textMaxWidth !== 'undefined') { this.textMaxWidth = Number(arg.textMaxWidth) * progress } if (typeof arg?.letterSpace !== 'undefined' && letterSpace) { this.letterSpace = Number(arg.letterSpace) * progress } if (typeof arg?.fontSize !== 'undefined') { const baseFontSize = this['back_fontSize'] ?? 14; this.fontSize = baseFontSize + (Number(arg.fontSize) - baseFontSize) * progress } if (typeof arg.fillStyle !== 'undefined') { const [rgbastr, rgba] = color.convertColorToRGBA(arg.fillStyle); const [s_rgbas, s_rgba] = color.convertColorToRGBA(this['back_fillStyle']); const rgbaResult = subtract(s_rgba, rgba, true) rgbaResult[0] = s_rgba[0] + progress * rgbaResult[0] rgbaResult[1] = s_rgba[1] + progress * rgbaResult[1] rgbaResult[2] = s_rgba[2] + progress * rgbaResult[2] rgbaResult[3] = s_rgba[3] + progress * rgbaResult[3] this.fillStyle = `rgba(${rgbaResult[0]},${rgbaResult[1]},${rgbaResult[2]},${rgbaResult[3]})` } if (typeof arg.strokeStyle !== 'undefined') { const [rgbastr, rgba] = color.convertColorToRGBA(arg.strokeStyle); const [s_rgbas, s_rgba] = color.convertColorToRGBA(this['back_strokeStyle']); const rgbaResult = subtract(s_rgba, rgba, true) rgbaResult[0] = s_rgba[0] + progress * rgbaResult[0] rgbaResult[1] = s_rgba[1] + progress * rgbaResult[1] rgbaResult[2] = s_rgba[2] + progress * rgbaResult[2] rgbaResult[3] = s_rgba[3] + progress * rgbaResult[3] this.strokeStyle = `rgba(${rgbaResult[0]},${rgbaResult[1]},${rgbaResult[2]},${rgbaResult[3]})` } this.x = x this.y = y this.width = width this.height = height this.canvas.draw() }).then(() => { this.playing = false; return Promise.resolve(this) }) } }