vislite
Version:
灵活、快速、简单的数据可视化交互式跨端前端库
90 lines (70 loc) • 3.06 kB
text/typescript
import type CanvasType from '../types/Canvas'
import type CanvasOptionType from '../types/CanvasOption'
import OralCanvas from './common/canvas/index'
import { initOption } from './common/option'
class Canvas extends OralCanvas implements CanvasType {
private __canvas: HTMLCanvasElement
private __el: HTMLElement
constructor(el: HTMLElement | null, option: CanvasOptionType = {}, width: number = 0, height: number = 0) {
if (!el) {
throw new Error("VISLite Canvas:The mount point requires an HTMLElement type but encountered null.")
}
option = initOption(option, {
// 对外暴露自定义缩放倍率(为满足特殊场景,以简化使用)
// 2025年7月25日 于秦皇岛
scale: 2,
region: true,
willReadFrequently: false
})
width = width || el.clientWidth
height = height || el.clientHeight
let ViewCanvas: HTMLCanvasElement, RegionCanvas: HTMLCanvasElement | null = null
const _el = el as any
// 如果已经初始化过了
if (_el._vislite_canvas_) {
ViewCanvas = _el._vislite_canvas_[0]
RegionCanvas = _el._vislite_canvas_[1]
}
// 否则就初始化
else {
ViewCanvas = document.createElement('canvas')
el.appendChild(ViewCanvas)
if (option.region) {
RegionCanvas = document.createElement('canvas')
}
_el._vislite_canvas_ = [ViewCanvas, RegionCanvas]
el.setAttribute('vislite', 'Canvas')
}
// 设置画布大小
const canvasArray = [RegionCanvas, ViewCanvas]
for (let index = 0; index < canvasArray.length; index++) {
const canvas = canvasArray[index]
if (canvas) {
canvas.style.width = width + "px"
canvas.setAttribute('width', ((index === 1 ? option.scale as number : 1) * width) + "")
canvas.style.height = height + "px"
canvas.setAttribute('height', ((index === 1 ? option.scale as number : 1) * height) + "")
}
}
super(ViewCanvas, RegionCanvas, {
willReadFrequently: option.willReadFrequently,
}, option.scale)
this.__canvas = ViewCanvas
this.__el = el
this.painter.scale(option.scale as number, option.scale as number)
}
toDataURL(): Promise<string> {
return new Promise(resolve => {
resolve(this.__canvas.toDataURL())
})
}
bind(eventName: string, callback: (regionName: string, x: number, y: number) => void) {
this.__el.addEventListener(eventName, (event: any) => {
this.getRegion(event.offsetX, event.offsetY).then(regionName => {
callback(regionName, event.offsetX, event.offsetY)
})
})
return this
}
}
export default Canvas