@cataract6545/tmui
Version:
tm-vuetify是一个新势力由主题驱动的UI组件库,相比其它优势大,组件全,设计趋势紧跟未来。具有主题生成,主题实时切换,暗黑实时切换,lottie动画,图表等新颖功能,tmui TMUI
140 lines (132 loc) • 5.63 kB
text/typescript
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)
})
}
}