feat:提交
This commit is contained in:
251
tests/dev1/dataHandle/common/drawing/svgDrawing.ts
Normal file
251
tests/dev1/dataHandle/common/drawing/svgDrawing.ts
Normal file
@@ -0,0 +1,251 @@
|
||||
import type {
|
||||
DrawImageOption, DrawLineOption, DrawLinePolygonOption, DrawPathContext, DrawRectOption,
|
||||
DrawTextOption,
|
||||
} from './base.js'
|
||||
import
|
||||
{ Drawing,
|
||||
} from './base.js'
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
const canvasCtx = canvas.getContext('2d')
|
||||
export class SvgDrawing extends Drawing
|
||||
{
|
||||
svg: SVGElement
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(
|
||||
width: number | string,
|
||||
height: number | string,
|
||||
scale: number = 0.8,
|
||||
)
|
||||
{
|
||||
super()
|
||||
this.scale = scale
|
||||
this.width = Number(width)
|
||||
this.height = Number(height)
|
||||
this.svg = this.createElement('svg')
|
||||
// this.svg.setAttribute('width', this.width.toString());//(Number(width) * this.scale)
|
||||
// this.svg.setAttribute('height', this.height.toString());//(Number(height) * this.scale)
|
||||
// this.svg.style.transform = 'scale(' + this.scale + ')';
|
||||
// this.svg.style.transformOrigin = 'left top';
|
||||
this.svg.setAttribute('viewBox', `0 0 ${width} ${height}`)
|
||||
}
|
||||
|
||||
private createElement(name)
|
||||
{
|
||||
return document.createElementNS('http://www.w3.org/2000/svg', name)
|
||||
}
|
||||
|
||||
toHTML(): string
|
||||
{
|
||||
return this.svg.outerHTML
|
||||
}
|
||||
|
||||
clearAll()
|
||||
{
|
||||
this.svg.innerHTML = ''
|
||||
}
|
||||
|
||||
drawPath(path: DrawPathContext, option: DrawLineOption)
|
||||
{
|
||||
let el = this.createElement('path')
|
||||
|
||||
let pathStr = ''
|
||||
for (const item of path.data)
|
||||
{
|
||||
switch (item.method)
|
||||
{
|
||||
case 'M':
|
||||
pathStr += `M ${item.args.join(' ')} `
|
||||
break
|
||||
case 'L':
|
||||
pathStr += `L ${item.args.join(' ')} `
|
||||
break
|
||||
}
|
||||
}
|
||||
el.setAttribute('d', pathStr)
|
||||
el.setAttribute('stroke-width', option.lineWidth.toString())
|
||||
el.setAttribute('stroke', option.strokeStyle)
|
||||
this.svg.appendChild(el)
|
||||
}
|
||||
|
||||
drawLine(
|
||||
x0: number,
|
||||
y0: number,
|
||||
x1: number,
|
||||
y1: number,
|
||||
option: DrawLineOption,
|
||||
)
|
||||
{
|
||||
let el = this.createElement('line')
|
||||
el.setAttribute('x1', x0.toString()) // (Number(x0) * this.scale)
|
||||
el.setAttribute('y1', y0.toString()) // (Number(y0) * this.scale)
|
||||
el.setAttribute('x2', x1.toString()) // (Number(x1) * this.scale)
|
||||
el.setAttribute('y2', y1.toString()) // (Number(y1) * this.scale)
|
||||
el.setAttribute('stroke', option.strokeStyle)
|
||||
el.setAttribute('fill', 'rgba(0,0,0,0)')
|
||||
el.setAttribute('stroke-width', option.lineWidth.toString())
|
||||
this.svg.appendChild(el)
|
||||
}
|
||||
|
||||
drawRect(
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
option: DrawRectOption,
|
||||
)
|
||||
{
|
||||
let el = this.createElement('rect')
|
||||
el.setAttribute('x', x.toString()) // ((x + option.baseLine / 2) * this.scale)
|
||||
el.setAttribute('y', y.toString()) // ((y + option.baseLine) * this.scale)
|
||||
el.setAttribute('width', width.toString()) // (Number(width) * this.scale)
|
||||
el.setAttribute('height', height.toString()) // (Number(height) * this.scale)
|
||||
if (option.fillStyle)
|
||||
{
|
||||
el.setAttribute('fill', option.fillStyle)
|
||||
el.setAttribute('stroke', option.strokeStyle)
|
||||
} else
|
||||
{
|
||||
el.setAttribute('fill', 'rgba(1,1,1,0)')
|
||||
el.setAttribute('stroke', option.strokeStyle)
|
||||
el.setAttribute(
|
||||
'stroke-width',
|
||||
(Math.floor(option.lineWidth) + 0.5).toString(),
|
||||
)
|
||||
}
|
||||
this.svg.appendChild(el)
|
||||
}
|
||||
|
||||
drawText(text: string, x: number, y: number, option: DrawTextOption)
|
||||
{
|
||||
let el = this.createElement('text')
|
||||
el.setAttribute('x', x.toString()) // (Number(x) * this.scale) option['CncDict'] ? (x - Number(option.fontSize) / 6).toString() :
|
||||
el.setAttribute('y', y.toString()) // (Number(y) * this.scale)
|
||||
el.style.dominantBaseline = 'text-before-edge'
|
||||
if (option.resetFont)
|
||||
{
|
||||
el.style.dominantBaseline = 'middle'
|
||||
el.setAttribute('text-anchor', 'middle')
|
||||
}
|
||||
el.setAttribute('fill', option.fillStyle)
|
||||
el.setAttribute('font-size', `${option.fontSize}px`)
|
||||
el.setAttribute('font-weight', option.fontWeight)
|
||||
el.setAttribute('font-family', option.fontFamily)
|
||||
if (option.overflowText)
|
||||
{
|
||||
el.setAttribute('textLength', option.maxWidth.toString())
|
||||
el.setAttribute('lengthAdjust', 'spacingAndGlyphs')
|
||||
}
|
||||
el.setAttribute('alignment-baseline', option.textBaseline)
|
||||
switch (option.textAlign)
|
||||
{
|
||||
case 'start':
|
||||
el.setAttribute('text-anchor', 'left')
|
||||
break
|
||||
case 'center':
|
||||
el.setAttribute('text-anchor', 'middle')
|
||||
break
|
||||
case 'right':
|
||||
el.setAttribute('text-anchor', 'end')
|
||||
break
|
||||
}
|
||||
|
||||
if (typeof text === 'string')
|
||||
{
|
||||
el.innerHTML = text.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>')
|
||||
} else
|
||||
{
|
||||
el.innerHTML = text
|
||||
}
|
||||
|
||||
this.svg.appendChild(el)
|
||||
}
|
||||
|
||||
drawForeignObjectText(
|
||||
text: string,
|
||||
x: number,
|
||||
y: number,
|
||||
option: DrawTextOption,
|
||||
)
|
||||
{
|
||||
// let el = this.createElement('foreignObject');
|
||||
// el.setAttribute('x',x.toString());
|
||||
// el.setAttribute('y',y.toString());
|
||||
// el.setAttribute('width',option.maxWidth.toString());
|
||||
// el.setAttribute('height',option['maxHeight'].toString());
|
||||
// let span = this.createElement('span');
|
||||
// span.style.dominantBaseline = 'text-before-edge';
|
||||
// if(option['resetFont']){
|
||||
// span.style.dominantBaseline = 'middle';
|
||||
// span.style.textAnchor = 'middle';
|
||||
// }
|
||||
// span.style.fontSize = option.fontSize + 'px';
|
||||
// span.style.fontWeight = option.fontWeight;
|
||||
// span.style.fontFamily = option.fontFamily;
|
||||
// span.style.display = 'inline-block';
|
||||
// span.style.width = option.maxWidth + 'px';
|
||||
// span.style.height = option['maxHeight'] + 'px';
|
||||
// span.style.overflow = 'hidden';
|
||||
// span.innerHTML = text;
|
||||
// el.appendChild(span);
|
||||
// this.svg.appendChild(el);
|
||||
}
|
||||
|
||||
async drawImage(
|
||||
source: CanvasImageSource,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
option: DrawImageOption,
|
||||
)
|
||||
{
|
||||
let src = ''
|
||||
if (source instanceof ImageBitmap)
|
||||
{
|
||||
canvas.width = source.width
|
||||
canvas.height = source.height
|
||||
canvasCtx.clearRect(0, 0, source.width, source.height)
|
||||
canvasCtx.drawImage(source, 0, 0, source.width, source.height)
|
||||
src = canvas.toDataURL()
|
||||
} else if (source instanceof HTMLImageElement)
|
||||
{
|
||||
src = source.src
|
||||
}
|
||||
return new Promise((resolve, reject) =>
|
||||
{
|
||||
let el = this.createElement('image')
|
||||
el.setAttribute('x', x.toString()) // (Number(x) * this.scale)
|
||||
el.setAttribute('y', y.toString()) // (Number(y) * this.scale)
|
||||
el.setAttribute('width', width.toString()) // (Number(width) * this.scale)
|
||||
el.setAttribute('height', height.toString()) // (Number(height) * this.scale)
|
||||
el.setAttribute('xlink:href', src)
|
||||
el.setAttribute('preserveAspectRatio', 'none meet')
|
||||
this.svg.appendChild(el)
|
||||
resolve(null)
|
||||
})
|
||||
}
|
||||
|
||||
drawLinePolygon(points: Array<any>, option: DrawLinePolygonOption)
|
||||
{
|
||||
let el = this.createElement('polygon')
|
||||
let pointsStr = ''
|
||||
for (let i = 0; i < points.length; i++)
|
||||
{
|
||||
if (i == points.length - 1)
|
||||
{
|
||||
pointsStr += `${points[i].x} ${points[i].y}`
|
||||
} else
|
||||
{
|
||||
pointsStr += `${points[i].x} ${points[i].y},`
|
||||
}
|
||||
}
|
||||
el.setAttribute('points', pointsStr)
|
||||
el.setAttribute('fill', option.isFill ? option.fillStyle : 'none')
|
||||
el.setAttribute('stroke', option.strokeStyle)
|
||||
el.setAttribute('stroke-width', option.lineWidth.toString())// 添加多段线的线宽--xyh
|
||||
this.svg.appendChild(el)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user