Files
cut-abstractions/tests/dev1/dataHandle/common/drawing/canvasDrawing.ts

198 lines
5.0 KiB
TypeScript
Raw Normal View History

2025-07-22 18:22:31 +08:00
import { createBmpFile } from '../bmp.js'
import { getFileExt } from '../file.js'
import type {
DrawImageOption,
DrawLineOption,
DrawLinePolygonOption,
DrawPathContext,
DrawRectOption,
DrawTextOption } from './base.js'
import
{
Drawing,
} from './base.js'
export class CanvasDrawing extends Drawing {
canvas: HTMLCanvasElement
ctx: CanvasRenderingContext2D
// isCaching: boolean;
outputType: string = 'png'
orgWidth: number
orgHeight: number
toHTML(): string {
let img = new Image(this.canvas.width, this.canvas.height)
img.src = this.canvas.toDataURL(`image/${this.outputType}`)
return img.outerHTML
}
clearAll() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
}
/**
*
*/
constructor(
canvas: HTMLCanvasElement,
// isCaching: boolean = false,
) {
super()
this.canvas = canvas
this.width = this.orgWidth = canvas.width = canvas.width
this.height = this.orgHeight = canvas.height = canvas.height
// this.isCaching = isCaching;
this.ctx = this.canvas.getContext('2d')
}
drawPath(path: DrawPathContext, option: DrawLineOption) {
this.ctx.beginPath()
for (const item of path.data) {
switch (item.method) {
case 'M':
this.ctx.moveTo(item.args[0], item.args[1])
break
case 'L':
this.ctx.lineTo(item.args[0], item.args[1])
break
}
}
this.ctx.lineWidth = option.lineWidth
this.ctx.strokeStyle = option.strokeStyle
this.ctx.stroke()
}
drawLine(
x0: number,
y0: number,
x1: number,
y1: number,
option: DrawLineOption,
) {
this.ctx.lineWidth = option.lineWidth
this.ctx.strokeStyle = option.strokeStyle
this.ctx.beginPath()
this.ctx.moveTo(x0, y0)
this.ctx.lineTo(x1, y1)
this.ctx.stroke()
}
drawRect(
x: number,
y: number,
width: number,
height: number,
option: DrawRectOption,
) {
this.ctx.lineWidth = option.lineWidth
this.ctx.strokeStyle = option.strokeStyle
this.ctx.fillStyle = option.fillStyle
if (option.fillStyle) {
this.ctx.fillRect(x, y, width, height)
} else {
this.ctx.strokeRect(x, y, width, height)
}
}
drawText(text: string, x: number, y: number, option: DrawTextOption) {
this.ctx.textAlign = option.textAlign as CanvasTextAlign
this.ctx.textBaseline = option.textBaseline as CanvasTextBaseline
this.ctx.fillStyle = option.fillStyle
this.ctx.font
= `${option.fontWeight} ${option.fontSize}px ${option.fontFamily}`
this.ctx.fillText(text, x, y, option.maxWidth)
}
drawForeignObjectText(
text: string,
x: number,
y: number,
option: DrawTextOption,
) {}
imageCache: Map<string, HTMLImageElement> = new Map()
drawImage(
source: CanvasImageSource,
x: number,
y: number,
width: number,
height: number,
option: DrawImageOption,
border: number,
) {
return new Promise((resolve, reject) => {
this.ctx.drawImage(source, x + border, y + border, width, height)
resolve(null)
})
}
drawLinePolygon(points: Array<any>, option: DrawLinePolygonOption) {
this.ctx.beginPath()
this.ctx.moveTo(points[0].x, points[0].y)
for (let i = 1; i < points.length; i++) {
this.ctx.lineTo(points[i].x, points[i].y)
}
this.ctx.closePath()
this.ctx.stroke()
if (option.isFill)
{
this.ctx.fillStyle = option.fillStyle
this.ctx.fill()
}
}
setScale(value: number) {
this.scale = value
this.canvas.width = this.width = this.orgWidth * value
this.canvas.height = this.height = this.orgHeight * value
this.ctx.scale(value, value)
}
// resize(width: number, height: number)
// {
// let oldWidth = this.width;
// let oldHeight = this.height;
// if (oldWidth != width || oldHeight != height)
// {
// let newCanvas = document.createElement('canvas');
// this.width = newCanvas.width = width;
// this.height = newCanvas.height = height;
// let newCtx = newCanvas.getContext('2d');
// newCtx.drawImage(this.canvas, 0, 0, oldWidth, oldHeight, 0, 0, width, height);
// this.canvas = newCanvas;
// this.ctx = newCtx;
// }
// }
exportFile(nameOrType: string, param: string): Promise<Blob | Uint8Array> {
let mimeType = 'image/png'
let ext = getFileExt(nameOrType)
if (ext === null) {
ext = nameOrType
}
let paramDic: { [key: string]: string } = {}
if (param != null) {
for (const item of param.split('&')) {
let kv = item.split('=')
paramDic[kv[0]] = kv[1]
}
}
switch (ext) {
case 'bmp':
let data = createBmpFile(
this.ctx.getImageData(0, 0, this.width, this.height),
paramDic,
)
return Promise.resolve(new Uint8Array(data))
case 'jpg':
case 'jpeg':
mimeType = 'image/jpeg'
break
}
return new Promise<Blob>((resolve) => {
this.canvas.toBlob((data: Blob) => {
resolve(data)
}, mimeType)
})
}
}