|
@@ -1,3 +1,29 @@
|
|
|
+/*
|
|
|
+ * *********************************************************************************************************************
|
|
|
+ *
|
|
|
+ * !!
|
|
|
+ * .F88X
|
|
|
+ * X8888Y
|
|
|
+ * .}888888N;
|
|
|
+ * i888888N; .:! .I$WI:
|
|
|
+ * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
|
|
|
+ * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I
|
|
|
+ * +888888N; .8888888Y "&&8Y.}8,
|
|
|
+ * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i
|
|
|
+ * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$*
|
|
|
+ * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I
|
|
|
+ * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
|
|
|
+ * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
|
|
|
+ * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I
|
|
|
+ * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/
|
|
|
+ * .:R888888I
|
|
|
+ * .&888888I Copyright (c) 2009-2020. 博锐尚格科技股份有限公司
|
|
|
+ * ~8888'
|
|
|
+ * .!88~ All rights reserved.
|
|
|
+ *
|
|
|
+ * *********************************************************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
import { SPaintEngine } from "./SPaintEngine";
|
|
|
import {
|
|
|
SBrushType,
|
|
@@ -14,17 +40,17 @@ import {
|
|
|
STextBaseLine,
|
|
|
STextDirection
|
|
|
} from "..";
|
|
|
-import { SPath2D } from "../SPath2D";
|
|
|
+import { SPath } from "../SPath";
|
|
|
|
|
|
/**
|
|
|
- * Canvas绘制引擎基类
|
|
|
+ * Canvas 绘制引擎基类
|
|
|
*
|
|
|
- * @author 庞利祥(sybotan@126.com)
|
|
|
+ * @author 庞利祥 <sybotan@126.com>
|
|
|
*/
|
|
|
export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
- /** 画布对象 */
|
|
|
+ /** 画布对象 */
|
|
|
private readonly _canvas: CanvasRenderingContext2D;
|
|
|
- /** 融合类型 */
|
|
|
+ /** 融合类型 */
|
|
|
static gcoList = [
|
|
|
"copy",
|
|
|
"destination-atop",
|
|
@@ -43,214 +69,103 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
/**
|
|
|
* 绘制引擎类型
|
|
|
*
|
|
|
- * @return 返回Canvas绘制引擎类型
|
|
|
+ * @return 返回 Canvas 绘制引擎类型
|
|
|
*/
|
|
|
get type(): SPaintEngineType {
|
|
|
return SPaintEngineType.Canvas;
|
|
|
- } // Get type
|
|
|
+ }
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
// 构造函数
|
|
|
/**
|
|
|
* 构造函数
|
|
|
*
|
|
|
- * @param canvas canvas对象
|
|
|
+ * @param canvas canvas对象
|
|
|
*/
|
|
|
constructor(canvas: CanvasRenderingContext2D) {
|
|
|
super();
|
|
|
this._canvas = canvas;
|
|
|
this._canvas.imageSmoothingEnabled = true;
|
|
|
- // this._canvas.imageSmoothingQuality;
|
|
|
- } // Constructor()
|
|
|
+ }
|
|
|
|
|
|
// =================================================================================================================
|
|
|
// 绘制图形
|
|
|
- /**
|
|
|
- * 设置裁剪路径
|
|
|
- *
|
|
|
- * @param path 裁剪路径
|
|
|
- */
|
|
|
- setClip(path: Path2D): void {
|
|
|
- this.setMatrix();
|
|
|
- // this._canvas.stroke(path);
|
|
|
- this._canvas.fill(path);
|
|
|
- this._canvas.clip();
|
|
|
- } // Function setClip()
|
|
|
|
|
|
/**
|
|
|
* 清空矩形区域
|
|
|
*
|
|
|
- * @param rect 矩形
|
|
|
+ * @param rect 矩形
|
|
|
*/
|
|
|
clearRect(rect: SRect): void {
|
|
|
this.setMatrix();
|
|
|
this._canvas.clearRect(rect.x, rect.y, rect.width, rect.height);
|
|
|
- } // Function clearRect()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * 绘制空心矩形
|
|
|
+ * 绘制矩形
|
|
|
*
|
|
|
- * @param rect 矩形
|
|
|
+ * @param rect 矩形
|
|
|
*/
|
|
|
drawRect(rect: SRect): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- this._canvas.fillRect(rect.x, rect.y, rect.width, rect.height);
|
|
|
- this._canvas.strokeRect(rect.x, rect.y, rect.width, rect.height);
|
|
|
- } // Function drawRect()
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.rect(rect.x, rect.y, rect.width, rect.height);
|
|
|
+ this._canvas.stroke();
|
|
|
+ this._canvas.fill();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制圆形
|
|
|
*
|
|
|
- * @param cx 圆心X坐标
|
|
|
- * @param cy 圆心X坐标
|
|
|
- * @param r 圆半径
|
|
|
+ * @param cx 圆心 x 坐标
|
|
|
+ * @param cy 圆心 y 坐标
|
|
|
+ * @param r 圆半径
|
|
|
*/
|
|
|
drawCircle(cx: number, cy: number, r: number): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- this._canvas.beginPath();
|
|
|
- this._canvas.arc(cx, cy, r, 0, 2 * Math.PI, true);
|
|
|
- this._canvas.fill();
|
|
|
- this._canvas.stroke();
|
|
|
- } // Function drawCircle()
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.arc(cx, cy, r, 0, 2 * Math.PI, true);
|
|
|
+ this._canvas.fill();
|
|
|
+ this._canvas.stroke();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制椭圆
|
|
|
*
|
|
|
- * @param cx 圆点X坐标
|
|
|
- * @param cy 圆点Y坐标
|
|
|
- * @param rx 水平半径
|
|
|
- * @param ry 垂直半径
|
|
|
+ * @param cx 圆点 X 坐标
|
|
|
+ * @param cy 圆点 Y 坐标
|
|
|
+ * @param rx 水平半径
|
|
|
+ * @param ry 垂直半径
|
|
|
*/
|
|
|
drawEllipse(cx: number, cy: number, rx: number, ry: number): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- this._canvas.beginPath();
|
|
|
- this._canvas.ellipse(cx, cy, rx, ry, 0.5, 0, 2 * Math.PI, true);
|
|
|
- } // Function drawEllipse()
|
|
|
-
|
|
|
- /**
|
|
|
- * 绘制椭圆弧
|
|
|
- *
|
|
|
- * @param x 椭圆所在矩形X坐标
|
|
|
- * @param y 椭圆所在矩形Y坐标
|
|
|
- * @param width 椭圆所在矩形宽度
|
|
|
- * @param height 椭圆所在矩形高度
|
|
|
- * @param startAngle 开始角度(单位弧度)
|
|
|
- * @param endAngle 结束角度(单位弧度)
|
|
|
- */
|
|
|
- drawArc(
|
|
|
- x: number,
|
|
|
- y: number,
|
|
|
- width: number,
|
|
|
- height: number,
|
|
|
- startAngle: number,
|
|
|
- endAngle: number
|
|
|
- ): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- let p = SPath2D.arc(x, y, width, height, startAngle, endAngle);
|
|
|
- let path = new Path2D(
|
|
|
- SPath2D.arc(x, y, width, height, startAngle, endAngle)
|
|
|
- );
|
|
|
- this._canvas.stroke(path);
|
|
|
- } // Function drawArc()
|
|
|
-
|
|
|
- /**
|
|
|
- * 绘制椭圆弦弧
|
|
|
- *
|
|
|
- * @param x 椭圆所在矩形X坐标
|
|
|
- * @param y 椭圆所在矩形Y坐标
|
|
|
- * @param width 椭圆所在矩形宽度
|
|
|
- * @param height 椭圆所在矩形高度
|
|
|
- * @param startAngle 开始角度(单位弧度)
|
|
|
- * @param endAngle 结束角度(单位弧度)
|
|
|
- */
|
|
|
- drawChord(
|
|
|
- x: number,
|
|
|
- y: number,
|
|
|
- width: number,
|
|
|
- height: number,
|
|
|
- startAngle: number,
|
|
|
- endAngle: number
|
|
|
- ): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- let path = new Path2D(
|
|
|
- SPath2D.chord(x, y, width, height, startAngle, endAngle)
|
|
|
- );
|
|
|
-
|
|
|
- this._canvas.fill(path);
|
|
|
- this._canvas.stroke(path);
|
|
|
- } // Function drawChord()
|
|
|
-
|
|
|
- /**
|
|
|
- * 绘制椭圆饼
|
|
|
- *
|
|
|
- * @param x 椭圆所在矩形X坐标
|
|
|
- * @param y 椭圆所在矩形Y坐标
|
|
|
- * @param width 椭圆所在矩形宽度
|
|
|
- * @param height 椭圆所在矩形高度
|
|
|
- * @param startAngle 开始角度(单位弧度)
|
|
|
- * @param endAngle 结束角度(单位弧度)
|
|
|
- */
|
|
|
- drawPie(
|
|
|
- x: number,
|
|
|
- y: number,
|
|
|
- width: number,
|
|
|
- height: number,
|
|
|
- startAngle: number,
|
|
|
- endAngle: number
|
|
|
- ): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- let path = new Path2D(
|
|
|
- SPath2D.pie(x, y, width, height, startAngle, endAngle)
|
|
|
- );
|
|
|
- this._canvas.fill(path);
|
|
|
- this._canvas.stroke(path);
|
|
|
- } // Function drawPie()
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.ellipse(cx, cy, rx, ry, 0, 0, 2 * Math.PI, true);
|
|
|
+ this._canvas.fill();
|
|
|
+ this._canvas.stroke();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制线段
|
|
|
*
|
|
|
- * @param line 线段
|
|
|
+ * @param line 线段
|
|
|
*/
|
|
|
drawLine(line: SLine): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
- this._canvas.beginPath();
|
|
|
- this._canvas.moveTo(line.x1, line.y1);
|
|
|
- this._canvas.lineTo(line.x2, line.y2);
|
|
|
- this._canvas.stroke();
|
|
|
- } // Function drawLine()
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.moveTo(line.x1, line.y1);
|
|
|
+ this._canvas.lineTo(line.x2, line.y2);
|
|
|
+ this._canvas.stroke();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制折线
|
|
|
*
|
|
|
- * @param points 折线折点
|
|
|
+ * @param points 折线折点
|
|
|
*/
|
|
|
drawPolyline(points: SPoint[]): void {
|
|
|
// 折线至少要有2个节点
|
|
@@ -258,25 +173,20 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
-
|
|
|
- this._canvas.beginPath();
|
|
|
- this._canvas.moveTo(points[0].x, points[0].y);
|
|
|
- for (let p of points) {
|
|
|
- this._canvas.lineTo(p.x, p.y);
|
|
|
- }
|
|
|
-
|
|
|
- this._canvas.stroke();
|
|
|
- } // Function drawPolyline()
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.moveTo(points[0].x, points[0].y);
|
|
|
+ for (let p of points) {
|
|
|
+ this._canvas.lineTo(p.x, p.y);
|
|
|
+ }
|
|
|
+ this._canvas.stroke();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制多边形
|
|
|
*
|
|
|
- * @param points 多边形顶点
|
|
|
+ * @param points 多边形顶点
|
|
|
*/
|
|
|
drawPolygon(points: SPoint[]): void {
|
|
|
// 多边形至少要有3个节点
|
|
@@ -284,68 +194,57 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
-
|
|
|
- this._canvas.beginPath();
|
|
|
- this._canvas.moveTo(points[0].x, points[0].y);
|
|
|
- for (let p of points) {
|
|
|
- this._canvas.lineTo(p.x, p.y);
|
|
|
- }
|
|
|
- this._canvas.closePath();
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.moveTo(points[0].x, points[0].y);
|
|
|
+ for (let p of points) {
|
|
|
+ this._canvas.lineTo(p.x, p.y);
|
|
|
+ }
|
|
|
+ this._canvas.closePath();
|
|
|
|
|
|
- this._canvas.fill();
|
|
|
- this._canvas.stroke();
|
|
|
- } // Function drawPolygon()
|
|
|
+ this._canvas.fill();
|
|
|
+ this._canvas.stroke();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制路径
|
|
|
*
|
|
|
- * @param path 路径
|
|
|
+ * @param path 路径
|
|
|
*/
|
|
|
- drawPath(path: SPath2D): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
-
|
|
|
- this._canvas.fill(path._path);
|
|
|
- this._canvas.stroke(path._path);
|
|
|
- } // Function drawPath()
|
|
|
+ drawPath(path: SPath): void {
|
|
|
+ this.init((): void => {
|
|
|
+ this.drawWay(path);
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制文本
|
|
|
*
|
|
|
- * @param text 文本内容
|
|
|
- * @param x X坐标
|
|
|
- * @param y Y坐标
|
|
|
- * @param maxWidth 最大宽度
|
|
|
+ * @param text 文本内容
|
|
|
+ * @param x X 坐标
|
|
|
+ * @param y Y 坐标
|
|
|
+ * @param maxWidth 最大宽度
|
|
|
*/
|
|
|
drawText(text: string, x: number, y: number, maxWidth?: number): void {
|
|
|
- this.setMatrix();
|
|
|
- this.setPen();
|
|
|
- this.setBrush();
|
|
|
- this.setFont();
|
|
|
- this.setComposite();
|
|
|
- this.setShadow();
|
|
|
-
|
|
|
- if (maxWidth == undefined) {
|
|
|
- this._canvas.fillText(text, x, y);
|
|
|
- } else {
|
|
|
- this._canvas.fillText(text, x, y, maxWidth);
|
|
|
- }
|
|
|
- } // Function drawText()
|
|
|
+ this.init((): void => {
|
|
|
+ this.setFont();
|
|
|
+ if (maxWidth == undefined) {
|
|
|
+ this._canvas.strokeText(text, x, y);
|
|
|
+ this._canvas.fillText(text, x, y);
|
|
|
+ } else {
|
|
|
+ this._canvas.strokeText(text, x, y);
|
|
|
+ this._canvas.fillText(text, x, y, maxWidth);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 绘制图片
|
|
|
*
|
|
|
* @param img 图片
|
|
|
- * @param x X坐标
|
|
|
- * @param y Y坐标
|
|
|
+ * @param x X 坐标
|
|
|
+ * @param y Y 坐标
|
|
|
* @param width 宽度
|
|
|
* @param height 高度
|
|
|
*/
|
|
@@ -356,66 +255,131 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
width?: number,
|
|
|
height?: number
|
|
|
): void {
|
|
|
- this.setMatrix();
|
|
|
- try {
|
|
|
- if (width == undefined) {
|
|
|
- this._canvas.drawImage(img, x, y);
|
|
|
- } else {
|
|
|
- this._canvas.drawImage(img, x, y, width, height as number);
|
|
|
+ this.init((): void => {
|
|
|
+ try {
|
|
|
+ if (width == undefined) {
|
|
|
+ this._canvas.drawImage(img, x, y);
|
|
|
+ } else {
|
|
|
+ this._canvas.drawImage(img, x, y, width, height as number);
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
}
|
|
|
- } catch (e) {
|
|
|
- console.log(e);
|
|
|
- }
|
|
|
- } // Function drawImage()
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 预测量文本宽度
|
|
|
*
|
|
|
- * @param text 预测的文本
|
|
|
- * @return 文本长度像素
|
|
|
- * */
|
|
|
+ * @param text 预测的文本
|
|
|
+ * @return 文本长度像素
|
|
|
+ */
|
|
|
textWidth(text: string): number {
|
|
|
return this._canvas.measureText(text).width;
|
|
|
- } // Function textWidth()
|
|
|
-
|
|
|
- // /**
|
|
|
- // * 绘制带导角空心矩形
|
|
|
- // *
|
|
|
- // * @param x X坐标
|
|
|
- // * @param y Y坐标
|
|
|
- // * @param w 宽度
|
|
|
- // * @param h 高度
|
|
|
- // * @param r 导角半径
|
|
|
- // */
|
|
|
- // drawRoundedRect(x: number, y: number, w: number, h: number, r: number): void {
|
|
|
- // this.canvas.beginPath();
|
|
|
- // this.canvas.moveTo(x, y + r);
|
|
|
- // this.canvas.lineTo(x, y + h - r);
|
|
|
- // this.canvas.quadraticCurveTo(x, y + h, x + r, y + h);
|
|
|
- // this.canvas.lineTo(x + w - r,y + h);
|
|
|
- // this.canvas.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
|
|
|
- // this.canvas.lineTo(x + w, y + r);
|
|
|
- // this.canvas.quadraticCurveTo(x + w, y, x + w - r, y);
|
|
|
- // this.canvas.lineTo(x + r, y);
|
|
|
- // this.canvas.quadraticCurveTo(x, y, x,y + r);
|
|
|
- // this.canvas.fill();
|
|
|
- // this.canvas.stroke();
|
|
|
- // } // Function drawRoundedRect()
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 绘制二次贝塞尔曲线
|
|
|
+ *
|
|
|
+ * @param cp1x 控制点 X 坐标
|
|
|
+ * @param cp1y 控制点 Y 坐标
|
|
|
+ * @param x 结束点 X 坐标
|
|
|
+ * @param y 结束点 Y 坐标
|
|
|
+ */
|
|
|
+ quadraticCurveTo(cp1x: number, cp1y: number, x: number, y: number): void {
|
|
|
+ this._canvas.quadraticCurveTo(cp1x, cp1y, x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 绘制三次贝塞尔曲线
|
|
|
+ *
|
|
|
+ * @param cp1x 起始点控制点 X 坐标
|
|
|
+ * @param cp1y 起始点控制点 Y 坐标
|
|
|
+ * @param cp2x 结束点控制点 X 坐标
|
|
|
+ * @param cp2y 结束点控制点 Y 坐标
|
|
|
+ * @param x 结束点X坐标
|
|
|
+ * @param y 结束点Y坐标
|
|
|
+ */
|
|
|
+ bezierCurveTo(
|
|
|
+ cp1x: number,
|
|
|
+ cp1y: number,
|
|
|
+ cp2x: number,
|
|
|
+ cp2y: number,
|
|
|
+ x: number,
|
|
|
+ y: number
|
|
|
+ ): void {
|
|
|
+ this._canvas.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 绘制带导角空心矩形
|
|
|
+ *
|
|
|
+ * @param rect 矩形
|
|
|
+ * @param r 导角半径
|
|
|
+ */
|
|
|
+ drawRoundRect(rect: SRect, r: number): void {
|
|
|
+ this.init((): void => {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ this._canvas.moveTo(rect.x, rect.y + r);
|
|
|
+ this._canvas.lineTo(rect.x, rect.bottom - r);
|
|
|
+ this._canvas.quadraticCurveTo(
|
|
|
+ rect.x,
|
|
|
+ rect.bottom,
|
|
|
+ rect.x + r,
|
|
|
+ rect.bottom
|
|
|
+ );
|
|
|
+ this._canvas.lineTo(rect.right - r, rect.bottom);
|
|
|
+ this._canvas.quadraticCurveTo(
|
|
|
+ rect.right,
|
|
|
+ rect.bottom,
|
|
|
+ rect.right,
|
|
|
+ rect.bottom - r
|
|
|
+ );
|
|
|
+ this._canvas.lineTo(rect.right, rect.y + r);
|
|
|
+ this._canvas.quadraticCurveTo(
|
|
|
+ rect.right,
|
|
|
+ rect.y,
|
|
|
+ rect.right - r,
|
|
|
+ rect.y
|
|
|
+ );
|
|
|
+ this._canvas.lineTo(rect.x + r, rect.y);
|
|
|
+ this._canvas.quadraticCurveTo(rect.x, rect.y, rect.x, rect.y + r);
|
|
|
+ this._canvas.fill();
|
|
|
+ this._canvas.stroke();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置字体
|
|
|
*
|
|
|
- * @param font 字体
|
|
|
+ * @param font 字体
|
|
|
*/
|
|
|
changeFont(font: SFont): void {
|
|
|
this._canvas.font = `${font.size}px ${font.name}`;
|
|
|
this.setTextAlign(font.textAlign);
|
|
|
this.setBaseLine(font.textBaseLine);
|
|
|
this.setTextDirection(font.textDirection);
|
|
|
- } // Function changeFont()
|
|
|
+ }
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
// 私有函数
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置整体绘制状态
|
|
|
+ *
|
|
|
+ * @param fn 绘制图形的具体函数
|
|
|
+ */
|
|
|
+ private init(fn: Function): void {
|
|
|
+ this.setMatrix();
|
|
|
+ this.setPen();
|
|
|
+ this.setBrush();
|
|
|
+ this.setComposite();
|
|
|
+ this.setShadow();
|
|
|
+ this.setClip();
|
|
|
+ this.setGlobalAlpha();
|
|
|
+ fn();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 设置画笔
|
|
|
*/
|
|
@@ -438,12 +402,12 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
}
|
|
|
|
|
|
this.setLineCapStyle(this.state.pen.lineCapStyle);
|
|
|
- } // Function setPen()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 线段端点风格
|
|
|
*
|
|
|
- * @param style 风格
|
|
|
+ * @param style 风格
|
|
|
*/
|
|
|
private setLineCapStyle(style: SLineCapStyle): void {
|
|
|
if (style == undefined) return;
|
|
@@ -454,7 +418,7 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
} else {
|
|
|
this._canvas.lineCap = "butt";
|
|
|
}
|
|
|
- } // Set lineCapStyle
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置画刷
|
|
@@ -499,7 +463,7 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
this._canvas.fillStyle = drawGradient;
|
|
|
}
|
|
|
}
|
|
|
- } // Function setBrush()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置融合
|
|
@@ -507,7 +471,7 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
private setComposite(): void {
|
|
|
this._canvas.globalCompositeOperation =
|
|
|
SCanvasPaintEngine.gcoList[this.state._composite];
|
|
|
- } // Function setComposite()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置阴影
|
|
@@ -528,7 +492,7 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
this._canvas.shadowOffsetX = 0;
|
|
|
this._canvas.shadowOffsetY = 0;
|
|
|
}
|
|
|
- } // Function setShadow()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置字体
|
|
@@ -538,12 +502,12 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
this.setTextAlign(this.state.font.textAlign);
|
|
|
this.setBaseLine(this.state.font.textBaseLine);
|
|
|
this.setTextDirection(this.state.font.textDirection);
|
|
|
- } // Function setFont()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 文本对齐选项
|
|
|
*
|
|
|
- * @param value 对齐方式
|
|
|
+ * @param value 对齐方式
|
|
|
*/
|
|
|
private setTextAlign(value: STextAlign): void {
|
|
|
if (value == undefined) {
|
|
@@ -560,12 +524,12 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
} else {
|
|
|
this._canvas.textAlign = "right";
|
|
|
}
|
|
|
- } // Function setTextAlign()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置文本基线对齐选项
|
|
|
*
|
|
|
- * @param value 对齐方式
|
|
|
+ * @param value 对齐方式
|
|
|
*/
|
|
|
private setBaseLine(value: STextBaseLine): void {
|
|
|
if (value == undefined) {
|
|
@@ -584,12 +548,12 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
} else {
|
|
|
this._canvas.textBaseline = "bottom";
|
|
|
}
|
|
|
- } // Set textBaseLine()
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置文本方向选项
|
|
|
*
|
|
|
- * @param value 文本方向
|
|
|
+ * @param value 文本方向
|
|
|
*/
|
|
|
private setTextDirection(value: STextDirection): void {
|
|
|
if (value == undefined) {
|
|
@@ -602,7 +566,7 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
} else {
|
|
|
this._canvas.direction = "rtl";
|
|
|
}
|
|
|
- } // Set textDirection
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 设置变型矩阵
|
|
@@ -616,5 +580,83 @@ export class SCanvasPaintEngine extends SPaintEngine {
|
|
|
this.state.matrix.e,
|
|
|
this.state.matrix.f
|
|
|
);
|
|
|
- } // Function setMatrix()
|
|
|
-} // class SPaintEngine
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置裁剪路径
|
|
|
+ */
|
|
|
+ setClip(): void {
|
|
|
+ if (this.state.clip) {
|
|
|
+ this.drawWay(this.state.clip);
|
|
|
+ this._canvas.clip();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 绘制路径
|
|
|
+ */
|
|
|
+ private drawWay(path: SPath): void {
|
|
|
+ this._canvas.beginPath();
|
|
|
+ path.cmdList.forEach((cmd): void => {
|
|
|
+ if (cmd.command == "L") {
|
|
|
+ this._canvas.lineTo(cmd.args[0], cmd.args[1]);
|
|
|
+ } else if (cmd.command == "M") {
|
|
|
+ this._canvas.moveTo(cmd.args[0], cmd.args[1]);
|
|
|
+ } else if (cmd.command == "Z") {
|
|
|
+ this._canvas.closePath();
|
|
|
+ } else if (cmd.command == "Q") {
|
|
|
+ this._canvas.quadraticCurveTo(
|
|
|
+ cmd.args[0],
|
|
|
+ cmd.args[1],
|
|
|
+ cmd.args[2],
|
|
|
+ cmd.args[3]
|
|
|
+ );
|
|
|
+ } else if (cmd.command == "T") {
|
|
|
+ // @ts-ignore
|
|
|
+ this._canvas.bezierCurveTo(
|
|
|
+ cmd.args[0],
|
|
|
+ cmd.args[1],
|
|
|
+ cmd.args[2],
|
|
|
+ cmd.args[3],
|
|
|
+ cmd.args[4]
|
|
|
+ );
|
|
|
+ } else if (cmd.command == "Ellipse") {
|
|
|
+ this._canvas.ellipse(
|
|
|
+ cmd.args[0],
|
|
|
+ cmd.args[1],
|
|
|
+ cmd.args[2],
|
|
|
+ cmd.args[3],
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ Math.PI * 2
|
|
|
+ );
|
|
|
+ } else if (cmd.command == "Arc") {
|
|
|
+ this._canvas.arc(
|
|
|
+ cmd.args[0],
|
|
|
+ cmd.args[1],
|
|
|
+ cmd.args[2],
|
|
|
+ cmd.args[3],
|
|
|
+ cmd.args[4],
|
|
|
+ cmd.args[5] == 1
|
|
|
+ );
|
|
|
+ } else if (cmd.command == "ArcTo") {
|
|
|
+ this._canvas.arcTo(
|
|
|
+ cmd.args[0],
|
|
|
+ cmd.args[1],
|
|
|
+ cmd.args[2],
|
|
|
+ cmd.args[3],
|
|
|
+ cmd.args[4]
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this._canvas.fill();
|
|
|
+ this._canvas.stroke();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置绘制透明度
|
|
|
+ */
|
|
|
+ private setGlobalAlpha(): void {
|
|
|
+ this._canvas.globalAlpha = this.state.globalAlpha;
|
|
|
+ }
|
|
|
+}
|