123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- import { SPoint } from "./index";
- import {SStringBuilder} from "@persagy-web/base/lib";
- /**
- * Path对象
- *
- * @author 庞利祥(sybotan@126.com)
- */
- export class SPath2D {
- /** 内部path对象 */
- _path = new Path2D();
- private svgBuilder = new SStringBuilder();
- /**
- * svg数据值
- */
- svgPath(): string {
- return this.svgBuilder.toString(" ");
- } // Function svgPath()
- /**
- * 添加路径
- *
- * @param path 添加的路径
- */
- addPath(path: SPath2D): void {
- this._path.addPath(path._path);
- this.svgBuilder.append(path.svgBuilder.toString(" "))
- } // Function addPath()
- /**
- * 移动到指定位置
- *
- * @param x x坐标
- * @param y y坐标
- */
- moveTo(x: number, y: number): void {
- this._path.moveTo(x, y);
- this.svgBuilder.append(`M ${x} ${y}`);
- } // Function moveTo()
- /**
- * 从当前位置到指定位置画直线
- *
- * @param x x坐标
- * @param y y坐标
- */
- lineTo(x: number, y: number): void {
- this._path.lineTo(x, y);
- this.svgBuilder.append(`L ${x} ${y}`);
- } // Function moveTo()
- /**
- * 矩形
- *
- * @param x 左上角x坐标
- * @param y 左上角y坐标
- * @param width 宽度
- * @param height 高度
- */
- rect(x: number, y: number, width: number, height: number): void {
- let r = x + width;
- let b = y + height;
- this._path.moveTo(x, y);
- this._path.lineTo(r, y);
- this._path.lineTo(r, b);
- this._path.lineTo(x, b);
- this._path.closePath();
- this.svgBuilder.append(`M ${x} ${y} L${r} ${y} L${r} ${b} L${x} ${b} Z`);
- // // 逆时针
- // this._path.moveTo(x, y);
- // this._path.lineTo(r, y);
- // this._path.lineTo(r, b);
- // this._path.lineTo(x, b);
- // this._path.closePath();
- // this.svgBuilder.append(`M ${x} ${y} L${r} ${y} L${} ${} L${} ${} L${} ${}`);
- } // Function rect()
- /**
- * 绘制折线
- *
- * @param points 折线折点
- */
- polyline(points: SPoint[]): void {
- if (points.length < 2) {
- return;
- }
- points.map((it: SPoint, index: number): void => {
- if (index == 0) {
- this._path.moveTo(it.x, it.y);
- this.svgBuilder.append(`M ${it.x} ${it.y}`);
- } else {
- this._path.lineTo(it.x, it.y);
- this.svgBuilder.append(`L ${it.x} ${it.y}`);
- }
- });
- } // Function drawPolyline()
- /**
- * 绘制多边形
- *
- * @param points 多边形顶点
- */
- polygon(points: SPoint[]): void {
- if (points.length < 3) {
- return;
- }
- points.map((it: SPoint, index: number): void => {
- if (index == 0) {
- this._path.moveTo(it.x, it.y);
- this.svgBuilder.append(`M ${it.x} ${it.y}`);
- } else {
- this._path.lineTo(it.x, it.y);
- this.svgBuilder.append(`L ${it.x} ${it.y}`);
- }
- });
- this._path.closePath();
- this.svgBuilder.append(`Z`);
- } // Functin polygon()
- /**
- * 椭圆弧
- *
- * @param x 椭圆所在矩形X坐标
- * @param y 椭圆所在矩形Y坐标
- * @param width 椭圆所在矩形宽度
- * @param height 椭圆所在矩形高度
- * @param startAngle 开始角度(单位弧度)
- * @param endAngle 结束角度(单位弧度)
- */
- static arc(
- x: number,
- y: number,
- width: number,
- height: number,
- startAngle: number,
- endAngle: number
- ): string {
- let a = width / 2;
- let b = height / 2;
- let p1 = SPath2D.arcPoint(a, b, startAngle);
- let p2 = SPath2D.arcPoint(a, b, endAngle);
- let large = SPath2D.largeArcFlag(startAngle, endAngle);
- p1.x = x + a + p1.x;
- p1.y = y + b - p1.y;
- p2.x = x + a + p2.x;
- p2.y = y + b - p2.y;
- return `M ${p1.x} ${p1.y} A ${a} ${b} 0 ${large} 0 ${p2.x} ${p2.y}`;
- } // Function arc()
- /**
- * 绘制椭圆弦弧
- *
- * @param x 椭圆所在矩形X坐标
- * @param y 椭圆所在矩形Y坐标
- * @param width 椭圆所在矩形宽度
- * @param height 椭圆所在矩形高度
- * @param startAngle 开始角度(单位弧度)
- * @param endAngle 结束角度(单位弧度)
- */
- static chord(
- x: number,
- y: number,
- width: number,
- height: number,
- startAngle: number,
- endAngle: number
- ): string {
- let a = width / 2;
- let b = height / 2;
- let p1 = SPath2D.arcPoint(a, b, startAngle);
- let p2 = SPath2D.arcPoint(a, b, endAngle);
- let large = SPath2D.largeArcFlag(startAngle, endAngle);
- p1.x = x + a + p1.x;
- p1.y = y + b - p1.y;
- p2.x = x + a + p2.x;
- p2.y = y + b - p2.y;
- return `M ${p1.x} ${p1.y} A ${a} ${b} 0 ${large} 0 ${p2.x} ${p2.y} Z`;
- } // Function chord()
- /**
- * 绘制椭圆饼
- *
- * @param x 椭圆所在矩形X坐标
- * @param y 椭圆所在矩形Y坐标
- * @param width 椭圆所在矩形宽度
- * @param height 椭圆所在矩形高度
- * @param startAngle 开始角度(单位弧度)
- * @param endAngle 结束角度(单位弧度)
- */
- static pie(
- x: number,
- y: number,
- width: number,
- height: number,
- startAngle: number,
- endAngle: number
- ): string {
- let a = width / 2;
- let b = height / 2;
- let p1 = SPath2D.arcPoint(a, b, startAngle);
- let p2 = SPath2D.arcPoint(a, b, endAngle);
- let large = SPath2D.largeArcFlag(startAngle, endAngle);
- p1.x = x + a + p1.x;
- p1.y = y + b - p1.y;
- p2.x = x + a + p2.x;
- p2.y = y + b - p2.y;
- return `M ${x + a} ${y + b} L ${p1.x} ${
- p1.y
- } A ${a} ${b} 0 ${large} 0 ${p2.x} ${p2.y} Z`;
- } // Function pie()
- /**
- * 计算大弧标志
- *
- * @param startAngle 启动角度(单位弧度)
- * @param endAngle 结束角度(单位弧度)
- */
- static largeArcFlag(startAngle: number, endAngle: number): number {
- return ((Math.abs(endAngle - startAngle) * 180) / Math.PI) % 360 >
- 179.99999
- ? 1
- : 0;
- } // Function largeArcFlag()
- // https://blog.csdn.net/xiamentingtao/article/details/85804823
- static arcPoint(a: number, b: number, angle: number): SPoint {
- let p = new SPoint();
- if (angle >= 0) {
- angle = angle - Math.floor(angle / Math.PI / 2) * 2 * Math.PI;
- } else {
- angle = angle + Math.ceil(-angle / Math.PI / 2) * 2 * Math.PI;
- }
- if (Math.abs(Math.PI / 2 - angle) <= 0.000001) {
- p.x = 0;
- p.y = b;
- } else if (Math.abs((Math.PI * 3) / 2 - angle) <= 0.000001) {
- p.x = 0;
- p.y = -b;
- } else if (Math.PI / 2 < angle && angle < (Math.PI * 3) / 2) {
- p.x =
- -(a * b) /
- Math.sqrt(b * b + a * a * Math.tan(angle) * Math.tan(angle));
- p.y =
- -(a * b * Math.tan(angle)) /
- Math.sqrt(b * b + a * a * Math.tan(angle) * Math.tan(angle));
- } else {
- p.x =
- (a * b) /
- Math.sqrt(b * b + a * a * Math.tan(angle) * Math.tan(angle));
- p.y =
- (a * b * Math.tan(angle)) /
- Math.sqrt(b * b + a * a * Math.tan(angle) * Math.tan(angle));
- }
- return p;
- } // Function arcPoint()
- } // Class SPath2D
|