@leafer-in/corner 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/corner.cjs +29 -4
- package/dist/corner.esm.js +29 -4
- package/dist/corner.esm.min.js +1 -1
- package/dist/corner.esm.min.js.map +1 -1
- package/dist/corner.js +28 -4
- package/dist/corner.min.cjs +1 -1
- package/dist/corner.min.cjs.map +1 -1
- package/dist/corner.min.js +1 -1
- package/dist/corner.min.js.map +1 -1
- package/package.json +4 -4
- package/src/PathCorner.ts +27 -3
package/dist/corner.cjs
CHANGED
|
@@ -53,7 +53,7 @@ function getCorrectT(d, x, y, x1, y1, x2, y2, toX, toY) {
|
|
|
53
53
|
return Math.max(0, Math.min(.5, t));
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
const {M: M, L: L, C: C, Z: Z} = draw.PathCommandMap;
|
|
56
|
+
const {M: M, L: L, C: C, Z: Z} = draw.PathCommandMap, {abs: abs} = Math;
|
|
57
57
|
|
|
58
58
|
const {getCenterX: getCenterX, getCenterY: getCenterY} = draw.PointHelper;
|
|
59
59
|
|
|
@@ -61,7 +61,7 @@ const {arcTo: arcTo} = draw.PathCommandDataHelper;
|
|
|
61
61
|
|
|
62
62
|
draw.PathCorner.smooth = function smooth(data, cornerRadius, _cornerSmoothing) {
|
|
63
63
|
const radius = data.radius;
|
|
64
|
-
if (isNeedConvert(data)) data = draw.PathConvert.toCanvasData(data, true);
|
|
64
|
+
if (isNeedConvert(data)) data = draw.PathConvert.toCanvasData(data, true); else data = [ ...data ];
|
|
65
65
|
let command, lastCommand, commandLen;
|
|
66
66
|
let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r, x1, y1, x2, y2, toX, toY;
|
|
67
67
|
if (draw.isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0;
|
|
@@ -147,6 +147,9 @@ draw.PathCorner.smooth = function smooth(data, cornerRadius, _cornerSmoothing) {
|
|
|
147
147
|
toX = startX, toY = startY;
|
|
148
148
|
setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three);
|
|
149
149
|
break;
|
|
150
|
+
|
|
151
|
+
default:
|
|
152
|
+
smooth.push(C, x1, y1, x2, y2, x, y);
|
|
150
153
|
}
|
|
151
154
|
lastX = x;
|
|
152
155
|
lastY = y;
|
|
@@ -236,7 +239,16 @@ function findEndPoint(data, i) {
|
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
function setAfterC(data, i, cornerRadius, lastX, lastY, fromX, fromY, x1, y1, x2, y2, toX, toY) {
|
|
239
|
-
|
|
242
|
+
let targetX = x1, targetY = y1;
|
|
243
|
+
if (isSame(x1, fromX) && isSame(y1, fromY)) {
|
|
244
|
+
targetX = x2;
|
|
245
|
+
targetY = y2;
|
|
246
|
+
if (isSame(x2, fromX) && isSame(y2, fromY)) {
|
|
247
|
+
targetX = toX;
|
|
248
|
+
targetY = toY;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY);
|
|
240
252
|
const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
241
253
|
const two = draw.BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
242
254
|
const {left: left, right: right} = two;
|
|
@@ -250,7 +262,16 @@ function setAfterC(data, i, cornerRadius, lastX, lastY, fromX, fromY, x1, y1, x2
|
|
|
250
262
|
}
|
|
251
263
|
|
|
252
264
|
function setBeforeC(smooth, cornerRadius, fromX, fromY, x1, y1, x2, y2, toX, toY, nextX, nextY, three) {
|
|
253
|
-
|
|
265
|
+
let targetX = x2, targetY = y2;
|
|
266
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
267
|
+
targetX = x1;
|
|
268
|
+
targetY = y1;
|
|
269
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
270
|
+
targetX = fromX;
|
|
271
|
+
targetY = fromY;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY);
|
|
254
275
|
const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY);
|
|
255
276
|
const {left: left, right: right} = draw.BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
256
277
|
if (left && right) {
|
|
@@ -261,4 +282,8 @@ function setBeforeC(smooth, cornerRadius, fromX, fromY, x1, y1, x2, y2, toX, toY
|
|
|
261
282
|
}
|
|
262
283
|
}
|
|
263
284
|
|
|
285
|
+
function isSame(a, b) {
|
|
286
|
+
return abs(a - b) < .01;
|
|
287
|
+
}
|
|
288
|
+
|
|
264
289
|
draw.Plugin.add("corner");
|
package/dist/corner.esm.js
CHANGED
|
@@ -51,7 +51,7 @@ function getCorrectT(d, x, y, x1, y1, x2, y2, toX, toY) {
|
|
|
51
51
|
return Math.max(0, Math.min(.5, t));
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const {M: M, L: L, C: C, Z: Z} = PathCommandMap;
|
|
54
|
+
const {M: M, L: L, C: C, Z: Z} = PathCommandMap, {abs: abs} = Math;
|
|
55
55
|
|
|
56
56
|
const {getCenterX: getCenterX, getCenterY: getCenterY} = PointHelper;
|
|
57
57
|
|
|
@@ -59,7 +59,7 @@ const {arcTo: arcTo} = PathCommandDataHelper;
|
|
|
59
59
|
|
|
60
60
|
PathCorner.smooth = function smooth(data, cornerRadius, _cornerSmoothing) {
|
|
61
61
|
const radius = data.radius;
|
|
62
|
-
if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true);
|
|
62
|
+
if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true); else data = [ ...data ];
|
|
63
63
|
let command, lastCommand, commandLen;
|
|
64
64
|
let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r, x1, y1, x2, y2, toX, toY;
|
|
65
65
|
if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0;
|
|
@@ -145,6 +145,9 @@ PathCorner.smooth = function smooth(data, cornerRadius, _cornerSmoothing) {
|
|
|
145
145
|
toX = startX, toY = startY;
|
|
146
146
|
setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three);
|
|
147
147
|
break;
|
|
148
|
+
|
|
149
|
+
default:
|
|
150
|
+
smooth.push(C, x1, y1, x2, y2, x, y);
|
|
148
151
|
}
|
|
149
152
|
lastX = x;
|
|
150
153
|
lastY = y;
|
|
@@ -234,7 +237,16 @@ function findEndPoint(data, i) {
|
|
|
234
237
|
}
|
|
235
238
|
|
|
236
239
|
function setAfterC(data, i, cornerRadius, lastX, lastY, fromX, fromY, x1, y1, x2, y2, toX, toY) {
|
|
237
|
-
|
|
240
|
+
let targetX = x1, targetY = y1;
|
|
241
|
+
if (isSame(x1, fromX) && isSame(y1, fromY)) {
|
|
242
|
+
targetX = x2;
|
|
243
|
+
targetY = y2;
|
|
244
|
+
if (isSame(x2, fromX) && isSame(y2, fromY)) {
|
|
245
|
+
targetX = toX;
|
|
246
|
+
targetY = toY;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY);
|
|
238
250
|
const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
239
251
|
const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
240
252
|
const {left: left, right: right} = two;
|
|
@@ -248,7 +260,16 @@ function setAfterC(data, i, cornerRadius, lastX, lastY, fromX, fromY, x1, y1, x2
|
|
|
248
260
|
}
|
|
249
261
|
|
|
250
262
|
function setBeforeC(smooth, cornerRadius, fromX, fromY, x1, y1, x2, y2, toX, toY, nextX, nextY, three) {
|
|
251
|
-
|
|
263
|
+
let targetX = x2, targetY = y2;
|
|
264
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
265
|
+
targetX = x1;
|
|
266
|
+
targetY = y1;
|
|
267
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
268
|
+
targetX = fromX;
|
|
269
|
+
targetY = fromY;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY);
|
|
252
273
|
const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY);
|
|
253
274
|
const {left: left, right: right} = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
254
275
|
if (left && right) {
|
|
@@ -259,4 +280,8 @@ function setBeforeC(smooth, cornerRadius, fromX, fromY, x1, y1, x2, y2, toX, toY
|
|
|
259
280
|
}
|
|
260
281
|
}
|
|
261
282
|
|
|
283
|
+
function isSame(a, b) {
|
|
284
|
+
return abs(a - b) < .01;
|
|
285
|
+
}
|
|
286
|
+
|
|
262
287
|
Plugin.add("corner");
|
package/dist/corner.esm.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BezierHelper as t,PathCommandMap as e,PointHelper as a,PathCommandDataHelper as
|
|
1
|
+
import{BezierHelper as t,PathCommandMap as e,PointHelper as a,PathCommandDataHelper as r,PathCorner as s,PathConvert as n,isArray as c,isUndefined as h,PathNumberCommandLengthMap as u,Plugin as o}from"@leafer-ui/draw";function i(t,e,a,r,s,n,c){const h=r-e,u=s-a,o=n-e,i=c-a,f=Math.sqrt(h*h+u*u),l=Math.sqrt(o*o+i*i);if(f<.001||l<.001)return 0;const b=(h*o+u*i)/(f*l),M=Math.max(-.99999,Math.min(.99999,b));let k=t*Math.sqrt((1-M)/(1+M));const p=Math.min(f/2,l/2);return Math.min(k,p)}function f(e,a,r,s,n,c,h,u,o){if(e<=0)return 0;const i=Math.sqrt(Math.pow(u-a,2)+Math.pow(o-r,2));if(e>=i)return.5;const f=3*(s-a),l=3*(n-r);let b=Math.sqrt(f*f+l*l);b<1e-6&&(b=i||1);let M=Math.min(.5,e/b);const k={x:0,y:0};for(let i=0;i<5;i++){t.getPointAndSet(M,a,r,s,n,c,h,u,o,k);const i=k.x-a,f=k.y-r,l=Math.sqrt(i*i+f*f);if(l<1e-6){M*=1.5;continue}const b=(i*t.getDerivative(M,a,s,c,u)+f*t.getDerivative(M,r,n,h,o))/l;if(Math.abs(b)<1e-6)break;const p=M-(l-e)/b,g=Math.max(0,Math.min(.6,p));if(Math.abs(g-M)<1e-5){M=g;break}M=g}return Math.max(0,Math.min(.5,M))}const{M:l,L:b,C:M,Z:k}=e,{abs:p}=Math,{getCenterX:g,getCenterY:m}=a,{arcTo:d}=r;function w(t,e){let a,r,s,n;const c=t.length;for(;e<c;)switch(a=t[e],a){case l:return;case b:s=t[e+1],n=t[e+2],e+=3;break;case M:s=t[e+5],n=t[e+6],e+=7;break;case k:return{x:s,y:n};default:r=u[a],e+=r}}function x(e,a,r,s,n,c,h,u,o,l,b,M,k){let p=u,g=o;v(u,c)&&v(o,h)&&(p=l,g=b,v(l,c)&&v(b,h)&&(p=M,g=k));const m=f(i(r,c,h,s,n,p,g),c,h,u,o,l,b,M,k),d=t.cut(m,c,h,u,o,l,b,M,k),{left:w,right:x}=d;return w&&x&&(e[a+1]=x[0],e[a+2]=x[1],e[a+3]=x[2],e[a+4]=x[3]),d}function q(e,a,r,s,n,c,h,u,o,l,b,k,p){let g=h,m=u;v(g,o)&&v(m,l)&&(g=n,m=c,v(g,o)&&v(m,l)&&(g=r,m=s));const w=f(i(a,o,l,g,m,b,k),o,l,h,u,n,c,r,s),{left:x,right:q}=t.cut(1-w,r,s,n,c,h,u,o,l);x&&q?(e.push(M,x[0],x[1],x[2],x[3],x[4],x[5]),d(e,o,l,b,k,a,x[4],x[5],p)):e.push(M,n,c,h,u,o,l)}function v(t,e){return p(t-e)<.01}s.smooth=function(t,e,a){const r=t.radius;let s,o,i;t=function(t){let e,a=0;const r=t.length;for(;a<r;)switch(e=t[a],e){case l:case b:a+=3;break;case M:a+=7;break;case k:a+=1;break;default:return!0}return!1}(t)?n.toCanvasData(t,!0):[...t];let f,p,v,y,C,D,A,L=0,P=0,S=0,T=0,X=0,Y=0,Z=0,j=0,z=0,B=0,E=0;c(e)&&(e=e[0]||0);const F=t.length,G=9===F,H=[];for(;L<F;){switch(s=t[L],f=r?h(r[P])?e:r[P]:e,s){case l:X=B=t[L+1],Y=E=t[L+2],Z=f,L+=3;const e=w(t,L);switch(t[L]){case b:j=t[L+1],z=t[L+2],G?H.push(l,X,Y):e?H.push(l,g(X,j),m(Y,z)):H.push(l,X,Y);break;case M:if(e){const{left:a,right:r}=x(t,L,f,e.x,e.y,X,Y,t[L+1],t[L+2],t[L+3],t[L+4],t[L+5],t[L+6]);if(a&&r){H.push(l,j=a[4],z=a[5]);break}}default:H.push(l,j=X,z=Y)}break;case b:switch(S=t[L+1],T=t[L+2],L+=3,t[L]){case b:d(H,S,T,t[L+1],t[L+2],f,B,E,G);break;case M:const{left:e,right:a}=x(t,L,f,B,E,S,T,t[L+1],t[L+2],t[L+3],t[L+4],t[L+5],t[L+6]);e&&a?d(H,S,T,e[4],e[5],f,B,E,G):H.push(b,S,T);break;case k:d(H,S,T,X,Y,f,B,E,G);break;default:H.push(b,S,T)}B=S,E=T;break;case M:switch(p=t[L+1],v=t[L+2],y=t[L+3],C=t[L+4],S=t[L+5],T=t[L+6],L+=7,t[L]){case b:D=t[L+1],A=t[L+2],q(H,f,B,E,p,v,y,C,S,T,D,A,G);break;case M:H.push(M,p,v,y,C,S,T);break;case k:D=X,A=Y,q(H,f,B,E,p,v,y,C,S,T,D,A,G);break;default:H.push(M,p,v,y,C,S,T)}B=S,E=T;break;case k:o!==k&&(d(H,X,Y,j,z,Z,B,E,G),H.push(k)),L+=1;break;default:i=u[s];for(let e=0;e<i;e++)H.push(t[L+e]);L+=i}o=s,P++}return H},o.add("corner");
|
|
2
2
|
//# sourceMappingURL=corner.esm.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corner.esm.min.js","sources":["../../../../../../src/in/packages/corner/src/helper.ts","../../../../../../src/in/packages/corner/src/PathCorner.ts","../../../../../../src/in/packages/corner/src/index.ts"],"sourcesContent":["import { BezierHelper } from '@leafer-ui/draw'\n\n\n// 获取圆角切线距离\nexport function getTangentDistance(r: number, x: number, y: number, lastX: number, lastY: number, nextX: number, nextY: number): number {\n // 1. 构造入射向量 U (P -> lastP) 和出射向量 V (P -> nextP)\n const ux = lastX - x, uy = lastY - y\n const vx = nextX - x, vy = nextY - y\n\n // 2. 计算向量长度(平方和开方)\n const lenU = Math.sqrt(ux * ux + uy * uy)\n const lenV = Math.sqrt(vx * vx + vy * vy)\n\n // 3. 边界防御:若线段长度几乎为0,则不产生圆角\n if (lenU < 0.001 || lenV < 0.001) return 0\n\n // 4. 计算向量夹角余弦值 cos(θ) = (U·V) / (|U|*|V|)\n const cosTheta = (ux * vx + uy * vy) / (lenU * lenV)\n\n // 5. 精度钳位:防止浮点误差导致 cos 越界 [-1, 1],避开分母为0的情况\n const safeCos = Math.max(-0.99999, Math.min(0.99999, cosTheta))\n\n // 6. 核心几何推导:d = r * sqrt((1 - cosθ) / (1 + cosθ))\n let d = r * Math.sqrt((1 - safeCos) / (1 + safeCos))\n\n // 7. 【关键性能与安全约束】:最大距离不得超过相邻边长的一半\n // 这样可以确保相邻顶点的圆角不会发生几何重叠或路径自交。\n const maxD = Math.min(lenU / 2, lenV / 2)\n return Math.min(d, maxD)\n}\n\n// 精准定位贝塞尔曲线参数 t\nexport function getCorrectT(d: number, x: number, y: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): number {\n if (d <= 0) return 0\n\n // 1. 预估总弦长(起点到终点的直线距离)\n const chordLen = Math.sqrt((toX - x) ** 2 + (toY - y) ** 2)\n\n // 2. 边界保护:若要求的距离超过弦长,为了路径安全,强制限制在曲线 50% 处\n if (d >= chordLen) return 0.5\n\n // 3. 初始猜测值估算:利用 t=0 处的瞬时速度矢量 v(0) = 3*(P1 - P0)\n const vx0 = 3 * (x1 - x)\n const vy0 = 3 * (y1 - y)\n let v0mag = Math.sqrt(vx0 * vx0 + vy0 * vy0)\n\n // 【优化点】:若起点与控制点重合(初速度为0),降级使用弦长线性比例,防止 NaN\n if (v0mag < 1e-6) v0mag = chordLen || 1\n\n let t = Math.min(0.5, d / v0mag)\n const tempP = { x: 0, y: 0 }\n\n // 4. 牛顿迭代 (Newton-Raphson) 循环\n for (let i = 0; i < 5; i++) {\n // 获取当前参数 t 对应的坐标点\n BezierHelper.getPointAndSet(t, x, y, x1, y1, x2, y2, toX, toY, tempP)\n\n const dx = tempP.x - x\n const dy = tempP.y - y\n const currentDist = Math.sqrt(dx * dx + dy * dy)\n\n // 数值稳定性检查:若当前点过于靠近起点,尝试向外探测\n if (currentDist < 1e-6) {\n t = t * 1.5\n continue\n }\n\n // 计算当前 t 处的导数向量 (x', y')\n const vxt = BezierHelper.getDerivative(t, x, x1, x2, toX)\n const vyt = BezierHelper.getDerivative(t, y, y1, y2, toY)\n\n // 计算目标函数的导数 f'(t) = (dx*x' + dy*y') / currentDist\n const f_prime = (dx * vxt + dy * vyt) / currentDist\n\n // 如果导数过小,说明进入平台期或计算异常,停止迭代\n if (Math.abs(f_prime) < 1e-6) break\n\n // 牛顿法公式:t_next = t - f(t) / f'(t)\n const deltaT = (currentDist - d) / f_prime\n const nextT = t - deltaT\n\n // 【收敛域保护】:强制限制在 [0, 0.6] 范围内寻找最优解,防止迭代跳出贝塞尔曲线有效区间\n const safeNextT = Math.max(0, Math.min(0.6, nextT))\n\n // 精度满足 1e-5 (像素级精度) 提前退出\n if (Math.abs(safeNextT - t) < 1e-5) {\n t = safeNextT\n break\n }\n t = safeNextT\n }\n\n // 最终返回结果,上限截断在 0.5 处,确保圆弧不会占据整条曲线导致形状崩坏\n return Math.max(0, Math.min(0.5, t))\n}","import { IPathCommandData, IPathCommandDataWithRadius, IPointData } from '@leafer-ui/interface'\nimport { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLengthMap, isArray, isUndefined, PathCommandDataHelper, BezierHelper, PathConvert } from '@leafer-ui/draw'\n\nimport { getCorrectT, getTangentDistance } from './helper'\n\n\nconst { M, L, C, Z } = Command\nconst { getCenterX, getCenterY } = PointHelper\nconst { arcTo } = PathCommandDataHelper\n\nPathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {\n\n const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角\n if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)\n\n let command: number, lastCommand: number, commandLen\n let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number\n if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0\n\n const len = data.length, three = len === 9 // 3个点时可以加大圆角\n const smooth: IPathCommandData = []\n\n while (i < len) {\n command = data[i]\n r = radius ? (isUndefined(radius[countCommand]) ? cornerRadius : radius[countCommand]) : cornerRadius\n switch (command) {\n case M: //moveto(x, y)\n startX = lastX = data[i + 1]\n startY = lastY = data[i + 2]\n startR = r\n i += 3\n const end = findEndPoint(data, i)\n switch (data[i]) { // next command\n case L: // lineTo()\n secondX = data[i + 1]\n secondY = data[i + 2]\n if (three) smooth.push(M, startX, startY)\n else {\n if (end) smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))\n else smooth.push(M, startX, startY)\n }\n break\n case C: // bezierCurveTo()\n if (end) {\n const { left, right } = setAfterC(data, i, r, end.x, end.y, startX, startY, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) {\n smooth.push(M, secondX = left[4], secondY = left[5])\n break\n }\n }\n default:\n smooth.push(M, secondX = startX, secondY = startY)\n }\n break\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n switch (data[i]) { // next command\n case L: // lineTo()\n arcTo(smooth, x, y, data[i + 1], data[i + 2], r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n case C: // bezierCurveTo()\n const { left, right } = setAfterC(data, i, r, lastX, lastY, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) arcTo(smooth, x, y, left[4], left[5], r, lastX, lastY, three)\n else smooth.push(L, x, y)\n break\n case Z: // closePath()\n arcTo(smooth, x, y, startX, startY, r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n default:\n smooth.push(L, x, y)\n }\n lastX = x\n lastY = y\n break\n case C:\n x1 = data[i + 1]\n y1 = data[i + 2]\n x2 = data[i + 3]\n y2 = data[i + 4]\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n switch (data[i]) { // next command\n case L: // lineTo()\n toX = data[i + 1], toY = data[i + 2]\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n case C: //\n smooth.push(C, x1, y1, x2, y2, x, y)\n break\n case Z: // closePath()\n toX = startX, toY = startY\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n }\n lastX = x\n lastY = y\n break\n case Z: //closepath()\n if (lastCommand !== Z) { // fix: 重复的 Z 导致的问题\n arcTo(smooth, startX, startY, secondX, secondY, startR, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n smooth.push(Z)\n }\n i += 1\n break\n default:\n commandLen = PathNumberCommandLengthMap[command]\n for (let j = 0; j < commandLen; j++) smooth.push(data[i + j])\n i += commandLen\n }\n lastCommand = command\n countCommand++\n }\n\n return smooth\n}\n\n\nfunction isNeedConvert(data: IPathCommandData): boolean {\n let command: number, i = 0\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n i += 3\n break\n case L: //lineto(x, y)\n i += 3\n break\n case C: // bezierCurveTo()\n i += 7\n break\n case Z: //closepath()\n i += 1\n break\n default:\n return true\n }\n }\n return false\n}\n\nfunction findEndPoint(data: IPathCommandData, i: number): IPointData {\n let command: number, commandLen: number, x: number, y: number\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n return undefined\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n break\n case C: // bezierCurveTo()\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n break\n case Z: //closepath()\n return { x, y }\n default:\n commandLen = PathNumberCommandLengthMap[command]\n i += commandLen\n }\n }\n return undefined\n}\n\n\nfunction setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {\n const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, x1, y1)\n const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const { left, right } = two\n\n if (left && right) {\n data[i + 1] = right[0]; data[i + 2] = right[1]\n data[i + 3] = right[2]; data[i + 4] = right[3]\n }\n\n return two\n}\n\nfunction setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {\n const d = getTangentDistance(cornerRadius, toX, toY, x2, y2, nextX, nextY) // 反向\n const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向\n const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n\n if (left && right) {\n smooth.push(C, left[0], left[1], left[2], left[3], left[4], left[5])\n arcTo(smooth, toX, toY, nextX, nextY, cornerRadius, left[4], left[5], three)\n } else {\n smooth.push(C, x1, y1, x2, y2, toX, toY)\n }\n}","import { Plugin } from '@leafer-ui/draw'\nimport './PathCorner'\n\n\nPlugin.add('corner')"],"names":["getTangentDistance","r","x","y","lastX","lastY","nextX","nextY","ux","uy","vx","vy","lenU","Math","sqrt","lenV","cosTheta","safeCos","max","min","d","maxD","getCorrectT","x1","y1","x2","y2","toX","toY","chordLen","pow","vx0","vy0","v0mag","t","tempP","i","BezierHelper","getPointAndSet","dx","dy","currentDist","f_prime","getDerivative","abs","nextT","safeNextT","M","L","C","Z","Command","getCenterX","getCenterY","PointHelper","arcTo","PathCommandDataHelper","findEndPoint","data","command","commandLen","len","length","PathNumberCommandLengthMap","setAfterC","cornerRadius","fromX","fromY","two","cut","left","right","setBeforeC","smooth","three","push","PathCorner","_cornerSmoothing","radius","lastCommand","isNeedConvert","PathConvert","toCanvasData","countCommand","startX","startY","startR","secondX","secondY","isArray","isUndefined","end","j","Plugin","add"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"corner.esm.min.js","sources":["../../../../../../src/in/packages/corner/src/helper.ts","../../../../../../src/in/packages/corner/src/PathCorner.ts","../../../../../../src/in/packages/corner/src/index.ts"],"sourcesContent":["import { BezierHelper } from '@leafer-ui/draw'\n\n\n// 获取圆角切线距离\nexport function getTangentDistance(r: number, x: number, y: number, lastX: number, lastY: number, nextX: number, nextY: number): number {\n // 1. 构造入射向量 U (P -> lastP) 和出射向量 V (P -> nextP)\n const ux = lastX - x, uy = lastY - y\n const vx = nextX - x, vy = nextY - y\n\n // 2. 计算向量长度(平方和开方)\n const lenU = Math.sqrt(ux * ux + uy * uy)\n const lenV = Math.sqrt(vx * vx + vy * vy)\n\n // 3. 边界防御:若线段长度几乎为0,则不产生圆角\n if (lenU < 0.001 || lenV < 0.001) return 0\n\n // 4. 计算向量夹角余弦值 cos(θ) = (U·V) / (|U|*|V|)\n const cosTheta = (ux * vx + uy * vy) / (lenU * lenV)\n\n // 5. 精度钳位:防止浮点误差导致 cos 越界 [-1, 1],避开分母为0的情况\n const safeCos = Math.max(-0.99999, Math.min(0.99999, cosTheta))\n\n // 6. 核心几何推导:d = r * sqrt((1 - cosθ) / (1 + cosθ))\n let d = r * Math.sqrt((1 - safeCos) / (1 + safeCos))\n\n // 7. 【关键性能与安全约束】:最大距离不得超过相邻边长的一半\n // 这样可以确保相邻顶点的圆角不会发生几何重叠或路径自交。\n const maxD = Math.min(lenU / 2, lenV / 2)\n return Math.min(d, maxD)\n}\n\n// 精准定位贝塞尔曲线参数 t\nexport function getCorrectT(d: number, x: number, y: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): number {\n if (d <= 0) return 0\n\n // 1. 预估总弦长(起点到终点的直线距离)\n const chordLen = Math.sqrt((toX - x) ** 2 + (toY - y) ** 2)\n\n // 2. 边界保护:若要求的距离超过弦长,为了路径安全,强制限制在曲线 50% 处\n if (d >= chordLen) return 0.5\n\n // 3. 初始猜测值估算:利用 t=0 处的瞬时速度矢量 v(0) = 3*(P1 - P0)\n const vx0 = 3 * (x1 - x)\n const vy0 = 3 * (y1 - y)\n let v0mag = Math.sqrt(vx0 * vx0 + vy0 * vy0)\n\n // 【优化点】:若起点与控制点重合(初速度为0),降级使用弦长线性比例,防止 NaN\n if (v0mag < 1e-6) v0mag = chordLen || 1\n\n let t = Math.min(0.5, d / v0mag)\n const tempP = { x: 0, y: 0 }\n\n // 4. 牛顿迭代 (Newton-Raphson) 循环\n for (let i = 0; i < 5; i++) {\n // 获取当前参数 t 对应的坐标点\n BezierHelper.getPointAndSet(t, x, y, x1, y1, x2, y2, toX, toY, tempP)\n\n const dx = tempP.x - x\n const dy = tempP.y - y\n const currentDist = Math.sqrt(dx * dx + dy * dy)\n\n // 数值稳定性检查:若当前点过于靠近起点,尝试向外探测\n if (currentDist < 1e-6) {\n t = t * 1.5\n continue\n }\n\n // 计算当前 t 处的导数向量 (x', y')\n const vxt = BezierHelper.getDerivative(t, x, x1, x2, toX)\n const vyt = BezierHelper.getDerivative(t, y, y1, y2, toY)\n\n // 计算目标函数的导数 f'(t) = (dx*x' + dy*y') / currentDist\n const f_prime = (dx * vxt + dy * vyt) / currentDist\n\n // 如果导数过小,说明进入平台期或计算异常,停止迭代\n if (Math.abs(f_prime) < 1e-6) break\n\n // 牛顿法公式:t_next = t - f(t) / f'(t)\n const deltaT = (currentDist - d) / f_prime\n const nextT = t - deltaT\n\n // 【收敛域保护】:强制限制在 [0, 0.6] 范围内寻找最优解,防止迭代跳出贝塞尔曲线有效区间\n const safeNextT = Math.max(0, Math.min(0.6, nextT))\n\n // 精度满足 1e-5 (像素级精度) 提前退出\n if (Math.abs(safeNextT - t) < 1e-5) {\n t = safeNextT\n break\n }\n t = safeNextT\n }\n\n // 最终返回结果,上限截断在 0.5 处,确保圆弧不会占据整条曲线导致形状崩坏\n return Math.max(0, Math.min(0.5, t))\n}","import { IPathCommandData, IPathCommandDataWithRadius, IPointData } from '@leafer-ui/interface'\nimport { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLengthMap, isArray, isUndefined, PathCommandDataHelper, BezierHelper, PathConvert } from '@leafer-ui/draw'\n\nimport { getCorrectT, getTangentDistance } from './helper'\n\n\nconst { M, L, C, Z } = Command, { abs } = Math\nconst { getCenterX, getCenterY } = PointHelper\nconst { arcTo } = PathCommandDataHelper\n\nPathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {\n\n const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角\n if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)\n else data = [...data] // 防止C命令修改数据造成污染\n\n let command: number, lastCommand: number, commandLen\n let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number\n if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0\n\n const len = data.length, three = len === 9 // 3个点时可以加大圆角\n const smooth: IPathCommandData = []\n\n while (i < len) {\n command = data[i]\n r = radius ? (isUndefined(radius[countCommand]) ? cornerRadius : radius[countCommand]) : cornerRadius\n switch (command) {\n case M: //moveto(x, y)\n startX = lastX = data[i + 1]\n startY = lastY = data[i + 2]\n startR = r\n i += 3\n const end = findEndPoint(data, i)\n switch (data[i]) { // next command\n case L: // lineTo()\n secondX = data[i + 1]\n secondY = data[i + 2]\n if (three) smooth.push(M, startX, startY)\n else {\n if (end) smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))\n else smooth.push(M, startX, startY)\n }\n break\n case C: // bezierCurveTo()\n if (end) {\n const { left, right } = setAfterC(data, i, r, end.x, end.y, startX, startY, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) {\n smooth.push(M, secondX = left[4], secondY = left[5])\n break\n }\n }\n default:\n smooth.push(M, secondX = startX, secondY = startY)\n }\n break\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n switch (data[i]) { // next command\n case L: // lineTo()\n arcTo(smooth, x, y, data[i + 1], data[i + 2], r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n case C: // bezierCurveTo()\n const { left, right } = setAfterC(data, i, r, lastX, lastY, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) arcTo(smooth, x, y, left[4], left[5], r, lastX, lastY, three)\n else smooth.push(L, x, y)\n break\n case Z: // closePath()\n arcTo(smooth, x, y, startX, startY, r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n default:\n smooth.push(L, x, y)\n }\n lastX = x\n lastY = y\n break\n case C:\n x1 = data[i + 1]\n y1 = data[i + 2]\n x2 = data[i + 3]\n y2 = data[i + 4]\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n switch (data[i]) { // next command\n case L: // lineTo()\n toX = data[i + 1], toY = data[i + 2]\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n case C: //\n smooth.push(C, x1, y1, x2, y2, x, y)\n break\n case Z: // closePath()\n toX = startX, toY = startY\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n default:\n smooth.push(C, x1, y1, x2, y2, x, y)\n }\n lastX = x\n lastY = y\n break\n case Z: //closepath()\n if (lastCommand !== Z) { // fix: 重复的 Z 导致的问题\n arcTo(smooth, startX, startY, secondX, secondY, startR, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n smooth.push(Z)\n }\n i += 1\n break\n default:\n commandLen = PathNumberCommandLengthMap[command]\n for (let j = 0; j < commandLen; j++) smooth.push(data[i + j])\n i += commandLen\n }\n lastCommand = command\n countCommand++\n }\n\n return smooth\n}\n\n\nfunction isNeedConvert(data: IPathCommandData): boolean {\n let command: number, i = 0\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n i += 3\n break\n case L: //lineto(x, y)\n i += 3\n break\n case C: // bezierCurveTo()\n i += 7\n break\n case Z: //closepath()\n i += 1\n break\n default:\n return true\n }\n }\n return false\n}\n\nfunction findEndPoint(data: IPathCommandData, i: number): IPointData {\n let command: number, commandLen: number, x: number, y: number\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n return undefined\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n break\n case C: // bezierCurveTo()\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n break\n case Z: //closepath()\n return { x, y }\n default:\n commandLen = PathNumberCommandLengthMap[command]\n i += commandLen\n }\n }\n return undefined\n}\n\n\nfunction setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {\n let targetX = x1, targetY = y1\n if (isSame(x1, fromX) && isSame(y1, fromY)) {\n targetX = x2; targetY = y2\n if (isSame(x2, fromX) && isSame(y2, fromY)) {\n targetX = toX; targetY = toY\n }\n }\n\n const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY)\n const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const { left, right } = two\n\n if (left && right) {\n data[i + 1] = right[0]; data[i + 2] = right[1]\n data[i + 3] = right[2]; data[i + 4] = right[3]\n }\n\n return two\n}\n\nfunction setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {\n let targetX = x2, targetY = y2\n if (isSame(targetX, toX) && isSame(targetY, toY)) {\n targetX = x1; targetY = y1\n if (isSame(targetX, toX) && isSame(targetY, toY)) {\n targetX = fromX; targetY = fromY\n }\n }\n\n const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY) // 反向\n const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向\n const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n\n if (left && right) {\n smooth.push(C, left[0], left[1], left[2], left[3], left[4], left[5])\n arcTo(smooth, toX, toY, nextX, nextY, cornerRadius, left[4], left[5], three)\n } else {\n smooth.push(C, x1, y1, x2, y2, toX, toY)\n }\n}\n\n\nfunction isSame(a: number, b: number): boolean {\n return abs(a - b) < 0.01\n}","import { Plugin } from '@leafer-ui/draw'\nimport './PathCorner'\n\n\nPlugin.add('corner')"],"names":["getTangentDistance","r","x","y","lastX","lastY","nextX","nextY","ux","uy","vx","vy","lenU","Math","sqrt","lenV","cosTheta","safeCos","max","min","d","maxD","getCorrectT","x1","y1","x2","y2","toX","toY","chordLen","pow","vx0","vy0","v0mag","t","tempP","i","BezierHelper","getPointAndSet","dx","dy","currentDist","f_prime","getDerivative","abs","nextT","safeNextT","M","L","C","Z","Command","getCenterX","getCenterY","PointHelper","arcTo","PathCommandDataHelper","findEndPoint","data","command","commandLen","len","length","PathNumberCommandLengthMap","setAfterC","cornerRadius","fromX","fromY","targetX","targetY","isSame","two","cut","left","right","setBeforeC","smooth","three","push","a","b","PathCorner","_cornerSmoothing","radius","lastCommand","isNeedConvert","PathConvert","toCanvasData","countCommand","startX","startY","startR","secondX","secondY","isArray","isUndefined","end","j","Plugin","add"],"mappings":"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"}
|
package/dist/corner.js
CHANGED
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
}
|
|
50
50
|
return Math.max(0, Math.min(.5, t));
|
|
51
51
|
}
|
|
52
|
-
const {M: M, L: L, C: C, Z: Z} = draw.PathCommandMap;
|
|
52
|
+
const {M: M, L: L, C: C, Z: Z} = draw.PathCommandMap, {abs: abs} = Math;
|
|
53
53
|
const {getCenterX: getCenterX, getCenterY: getCenterY} = draw.PointHelper;
|
|
54
54
|
const {arcTo: arcTo} = draw.PathCommandDataHelper;
|
|
55
55
|
draw.PathCorner.smooth = function smooth(data, cornerRadius, _cornerSmoothing) {
|
|
56
56
|
const radius = data.radius;
|
|
57
|
-
if (isNeedConvert(data)) data = draw.PathConvert.toCanvasData(data, true);
|
|
57
|
+
if (isNeedConvert(data)) data = draw.PathConvert.toCanvasData(data, true); else data = [ ...data ];
|
|
58
58
|
let command, lastCommand, commandLen;
|
|
59
59
|
let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r, x1, y1, x2, y2, toX, toY;
|
|
60
60
|
if (draw.isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0;
|
|
@@ -140,6 +140,9 @@
|
|
|
140
140
|
toX = startX, toY = startY;
|
|
141
141
|
setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three);
|
|
142
142
|
break;
|
|
143
|
+
|
|
144
|
+
default:
|
|
145
|
+
smooth.push(C, x1, y1, x2, y2, x, y);
|
|
143
146
|
}
|
|
144
147
|
lastX = x;
|
|
145
148
|
lastY = y;
|
|
@@ -226,7 +229,16 @@
|
|
|
226
229
|
return undefined;
|
|
227
230
|
}
|
|
228
231
|
function setAfterC(data, i, cornerRadius, lastX, lastY, fromX, fromY, x1, y1, x2, y2, toX, toY) {
|
|
229
|
-
|
|
232
|
+
let targetX = x1, targetY = y1;
|
|
233
|
+
if (isSame(x1, fromX) && isSame(y1, fromY)) {
|
|
234
|
+
targetX = x2;
|
|
235
|
+
targetY = y2;
|
|
236
|
+
if (isSame(x2, fromX) && isSame(y2, fromY)) {
|
|
237
|
+
targetX = toX;
|
|
238
|
+
targetY = toY;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY);
|
|
230
242
|
const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
231
243
|
const two = draw.BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
232
244
|
const {left: left, right: right} = two;
|
|
@@ -239,7 +251,16 @@
|
|
|
239
251
|
return two;
|
|
240
252
|
}
|
|
241
253
|
function setBeforeC(smooth, cornerRadius, fromX, fromY, x1, y1, x2, y2, toX, toY, nextX, nextY, three) {
|
|
242
|
-
|
|
254
|
+
let targetX = x2, targetY = y2;
|
|
255
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
256
|
+
targetX = x1;
|
|
257
|
+
targetY = y1;
|
|
258
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
259
|
+
targetX = fromX;
|
|
260
|
+
targetY = fromY;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY);
|
|
243
264
|
const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY);
|
|
244
265
|
const {left: left, right: right} = draw.BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY);
|
|
245
266
|
if (left && right) {
|
|
@@ -249,5 +270,8 @@
|
|
|
249
270
|
smooth.push(C, x1, y1, x2, y2, toX, toY);
|
|
250
271
|
}
|
|
251
272
|
}
|
|
273
|
+
function isSame(a, b) {
|
|
274
|
+
return abs(a - b) < .01;
|
|
275
|
+
}
|
|
252
276
|
draw.Plugin.add("corner");
|
|
253
277
|
})(LeaferUI);
|
package/dist/corner.min.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("@leafer-ui/draw");function t(e,t,a,r,n,s,c){const h=r-t,i=n-a,
|
|
1
|
+
"use strict";var e=require("@leafer-ui/draw");function t(e,t,a,r,n,s,c){const h=r-t,i=n-a,u=s-t,o=c-a,f=Math.sqrt(h*h+i*i),l=Math.sqrt(u*u+o*o);if(f<.001||l<.001)return 0;const p=(h*u+i*o)/(f*l),b=Math.max(-.99999,Math.min(.99999,p));let M=e*Math.sqrt((1-b)/(1+b));const m=Math.min(f/2,l/2);return Math.min(M,m)}function a(t,a,r,n,s,c,h,i,u){if(t<=0)return 0;const o=Math.sqrt(Math.pow(i-a,2)+Math.pow(u-r,2));if(t>=o)return.5;const f=3*(n-a),l=3*(s-r);let p=Math.sqrt(f*f+l*l);p<1e-6&&(p=o||1);let b=Math.min(.5,t/p);const M={x:0,y:0};for(let o=0;o<5;o++){e.BezierHelper.getPointAndSet(b,a,r,n,s,c,h,i,u,M);const o=M.x-a,f=M.y-r,l=Math.sqrt(o*o+f*f);if(l<1e-6){b*=1.5;continue}const p=(o*e.BezierHelper.getDerivative(b,a,n,c,i)+f*e.BezierHelper.getDerivative(b,r,s,h,u))/l;if(Math.abs(p)<1e-6)break;const m=b-(l-t)/p,k=Math.max(0,Math.min(.6,m));if(Math.abs(k-b)<1e-5){b=k;break}b=k}return Math.max(0,Math.min(.5,b))}const{M:r,L:n,C:s,Z:c}=e.PathCommandMap,{abs:h}=Math,{getCenterX:i,getCenterY:u}=e.PointHelper,{arcTo:o}=e.PathCommandDataHelper;function f(t,a){let h,i,u,o;const f=t.length;for(;a<f;)switch(h=t[a],h){case r:return;case n:u=t[a+1],o=t[a+2],a+=3;break;case s:u=t[a+5],o=t[a+6],a+=7;break;case c:return{x:u,y:o};default:i=e.PathNumberCommandLengthMap[h],a+=i}}function l(r,n,s,c,h,i,u,o,f,l,p,M,m){let k=o,d=f;b(o,i)&&b(f,u)&&(k=l,d=p,b(l,i)&&b(p,u)&&(k=M,d=m));const g=a(t(s,i,u,c,h,k,d),i,u,o,f,l,p,M,m),C=e.BezierHelper.cut(g,i,u,o,f,l,p,M,m),{left:w,right:P}=C;return w&&P&&(r[n+1]=P[0],r[n+2]=P[1],r[n+3]=P[2],r[n+4]=P[3]),C}function p(r,n,c,h,i,u,f,l,p,M,m,k,d){let g=f,C=l;b(g,p)&&b(C,M)&&(g=i,C=u,b(g,p)&&b(C,M)&&(g=c,C=h));const w=a(t(n,p,M,g,C,m,k),p,M,f,l,i,u,c,h),{left:P,right:q}=e.BezierHelper.cut(1-w,c,h,i,u,f,l,p,M);P&&q?(r.push(s,P[0],P[1],P[2],P[3],P[4],P[5]),o(r,p,M,m,k,n,P[4],P[5],d)):r.push(s,i,u,f,l,p,M)}function b(e,t){return h(e-t)<.01}e.PathCorner.smooth=function(t,a,h){const b=t.radius;let M,m,k;t=function(e){let t,a=0;const h=e.length;for(;a<h;)switch(t=e[a],t){case r:case n:a+=3;break;case s:a+=7;break;case c:a+=1;break;default:return!0}return!1}(t)?e.PathConvert.toCanvasData(t,!0):[...t];let d,g,C,w,P,q,v,x=0,H=0,y=0,z=0,B=0,D=0,L=0,A=0,N=0,S=0,T=0;e.isArray(a)&&(a=a[0]||0);const U=t.length,X=9===U,Y=[];for(;x<U;){switch(M=t[x],d=b?e.isUndefined(b[H])?a:b[H]:a,M){case r:B=S=t[x+1],D=T=t[x+2],L=d,x+=3;const a=f(t,x);switch(t[x]){case n:A=t[x+1],N=t[x+2],X?Y.push(r,B,D):a?Y.push(r,i(B,A),u(D,N)):Y.push(r,B,D);break;case s:if(a){const{left:e,right:n}=l(t,x,d,a.x,a.y,B,D,t[x+1],t[x+2],t[x+3],t[x+4],t[x+5],t[x+6]);if(e&&n){Y.push(r,A=e[4],N=e[5]);break}}default:Y.push(r,A=B,N=D)}break;case n:switch(y=t[x+1],z=t[x+2],x+=3,t[x]){case n:o(Y,y,z,t[x+1],t[x+2],d,S,T,X);break;case s:const{left:e,right:a}=l(t,x,d,S,T,y,z,t[x+1],t[x+2],t[x+3],t[x+4],t[x+5],t[x+6]);e&&a?o(Y,y,z,e[4],e[5],d,S,T,X):Y.push(n,y,z);break;case c:o(Y,y,z,B,D,d,S,T,X);break;default:Y.push(n,y,z)}S=y,T=z;break;case s:switch(g=t[x+1],C=t[x+2],w=t[x+3],P=t[x+4],y=t[x+5],z=t[x+6],x+=7,t[x]){case n:q=t[x+1],v=t[x+2],p(Y,d,S,T,g,C,w,P,y,z,q,v,X);break;case s:Y.push(s,g,C,w,P,y,z);break;case c:q=B,v=D,p(Y,d,S,T,g,C,w,P,y,z,q,v,X);break;default:Y.push(s,g,C,w,P,y,z)}S=y,T=z;break;case c:m!==c&&(o(Y,B,D,A,N,L,S,T,X),Y.push(c)),x+=1;break;default:k=e.PathNumberCommandLengthMap[M];for(let e=0;e<k;e++)Y.push(t[x+e]);x+=k}m=M,H++}return Y},e.Plugin.add("corner");
|
|
2
2
|
//# sourceMappingURL=corner.min.cjs.map
|
package/dist/corner.min.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corner.min.cjs","sources":["../../../../../../src/in/packages/corner/src/helper.ts","../../../../../../src/in/packages/corner/src/PathCorner.ts","../../../../../../src/in/packages/corner/src/index.ts"],"sourcesContent":["import { BezierHelper } from '@leafer-ui/draw'\n\n\n// 获取圆角切线距离\nexport function getTangentDistance(r: number, x: number, y: number, lastX: number, lastY: number, nextX: number, nextY: number): number {\n // 1. 构造入射向量 U (P -> lastP) 和出射向量 V (P -> nextP)\n const ux = lastX - x, uy = lastY - y\n const vx = nextX - x, vy = nextY - y\n\n // 2. 计算向量长度(平方和开方)\n const lenU = Math.sqrt(ux * ux + uy * uy)\n const lenV = Math.sqrt(vx * vx + vy * vy)\n\n // 3. 边界防御:若线段长度几乎为0,则不产生圆角\n if (lenU < 0.001 || lenV < 0.001) return 0\n\n // 4. 计算向量夹角余弦值 cos(θ) = (U·V) / (|U|*|V|)\n const cosTheta = (ux * vx + uy * vy) / (lenU * lenV)\n\n // 5. 精度钳位:防止浮点误差导致 cos 越界 [-1, 1],避开分母为0的情况\n const safeCos = Math.max(-0.99999, Math.min(0.99999, cosTheta))\n\n // 6. 核心几何推导:d = r * sqrt((1 - cosθ) / (1 + cosθ))\n let d = r * Math.sqrt((1 - safeCos) / (1 + safeCos))\n\n // 7. 【关键性能与安全约束】:最大距离不得超过相邻边长的一半\n // 这样可以确保相邻顶点的圆角不会发生几何重叠或路径自交。\n const maxD = Math.min(lenU / 2, lenV / 2)\n return Math.min(d, maxD)\n}\n\n// 精准定位贝塞尔曲线参数 t\nexport function getCorrectT(d: number, x: number, y: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): number {\n if (d <= 0) return 0\n\n // 1. 预估总弦长(起点到终点的直线距离)\n const chordLen = Math.sqrt((toX - x) ** 2 + (toY - y) ** 2)\n\n // 2. 边界保护:若要求的距离超过弦长,为了路径安全,强制限制在曲线 50% 处\n if (d >= chordLen) return 0.5\n\n // 3. 初始猜测值估算:利用 t=0 处的瞬时速度矢量 v(0) = 3*(P1 - P0)\n const vx0 = 3 * (x1 - x)\n const vy0 = 3 * (y1 - y)\n let v0mag = Math.sqrt(vx0 * vx0 + vy0 * vy0)\n\n // 【优化点】:若起点与控制点重合(初速度为0),降级使用弦长线性比例,防止 NaN\n if (v0mag < 1e-6) v0mag = chordLen || 1\n\n let t = Math.min(0.5, d / v0mag)\n const tempP = { x: 0, y: 0 }\n\n // 4. 牛顿迭代 (Newton-Raphson) 循环\n for (let i = 0; i < 5; i++) {\n // 获取当前参数 t 对应的坐标点\n BezierHelper.getPointAndSet(t, x, y, x1, y1, x2, y2, toX, toY, tempP)\n\n const dx = tempP.x - x\n const dy = tempP.y - y\n const currentDist = Math.sqrt(dx * dx + dy * dy)\n\n // 数值稳定性检查:若当前点过于靠近起点,尝试向外探测\n if (currentDist < 1e-6) {\n t = t * 1.5\n continue\n }\n\n // 计算当前 t 处的导数向量 (x', y')\n const vxt = BezierHelper.getDerivative(t, x, x1, x2, toX)\n const vyt = BezierHelper.getDerivative(t, y, y1, y2, toY)\n\n // 计算目标函数的导数 f'(t) = (dx*x' + dy*y') / currentDist\n const f_prime = (dx * vxt + dy * vyt) / currentDist\n\n // 如果导数过小,说明进入平台期或计算异常,停止迭代\n if (Math.abs(f_prime) < 1e-6) break\n\n // 牛顿法公式:t_next = t - f(t) / f'(t)\n const deltaT = (currentDist - d) / f_prime\n const nextT = t - deltaT\n\n // 【收敛域保护】:强制限制在 [0, 0.6] 范围内寻找最优解,防止迭代跳出贝塞尔曲线有效区间\n const safeNextT = Math.max(0, Math.min(0.6, nextT))\n\n // 精度满足 1e-5 (像素级精度) 提前退出\n if (Math.abs(safeNextT - t) < 1e-5) {\n t = safeNextT\n break\n }\n t = safeNextT\n }\n\n // 最终返回结果,上限截断在 0.5 处,确保圆弧不会占据整条曲线导致形状崩坏\n return Math.max(0, Math.min(0.5, t))\n}","import { IPathCommandData, IPathCommandDataWithRadius, IPointData } from '@leafer-ui/interface'\nimport { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLengthMap, isArray, isUndefined, PathCommandDataHelper, BezierHelper, PathConvert } from '@leafer-ui/draw'\n\nimport { getCorrectT, getTangentDistance } from './helper'\n\n\nconst { M, L, C, Z } = Command\nconst { getCenterX, getCenterY } = PointHelper\nconst { arcTo } = PathCommandDataHelper\n\nPathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {\n\n const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角\n if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)\n\n let command: number, lastCommand: number, commandLen\n let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number\n if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0\n\n const len = data.length, three = len === 9 // 3个点时可以加大圆角\n const smooth: IPathCommandData = []\n\n while (i < len) {\n command = data[i]\n r = radius ? (isUndefined(radius[countCommand]) ? cornerRadius : radius[countCommand]) : cornerRadius\n switch (command) {\n case M: //moveto(x, y)\n startX = lastX = data[i + 1]\n startY = lastY = data[i + 2]\n startR = r\n i += 3\n const end = findEndPoint(data, i)\n switch (data[i]) { // next command\n case L: // lineTo()\n secondX = data[i + 1]\n secondY = data[i + 2]\n if (three) smooth.push(M, startX, startY)\n else {\n if (end) smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))\n else smooth.push(M, startX, startY)\n }\n break\n case C: // bezierCurveTo()\n if (end) {\n const { left, right } = setAfterC(data, i, r, end.x, end.y, startX, startY, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) {\n smooth.push(M, secondX = left[4], secondY = left[5])\n break\n }\n }\n default:\n smooth.push(M, secondX = startX, secondY = startY)\n }\n break\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n switch (data[i]) { // next command\n case L: // lineTo()\n arcTo(smooth, x, y, data[i + 1], data[i + 2], r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n case C: // bezierCurveTo()\n const { left, right } = setAfterC(data, i, r, lastX, lastY, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) arcTo(smooth, x, y, left[4], left[5], r, lastX, lastY, three)\n else smooth.push(L, x, y)\n break\n case Z: // closePath()\n arcTo(smooth, x, y, startX, startY, r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n default:\n smooth.push(L, x, y)\n }\n lastX = x\n lastY = y\n break\n case C:\n x1 = data[i + 1]\n y1 = data[i + 2]\n x2 = data[i + 3]\n y2 = data[i + 4]\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n switch (data[i]) { // next command\n case L: // lineTo()\n toX = data[i + 1], toY = data[i + 2]\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n case C: //\n smooth.push(C, x1, y1, x2, y2, x, y)\n break\n case Z: // closePath()\n toX = startX, toY = startY\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n }\n lastX = x\n lastY = y\n break\n case Z: //closepath()\n if (lastCommand !== Z) { // fix: 重复的 Z 导致的问题\n arcTo(smooth, startX, startY, secondX, secondY, startR, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n smooth.push(Z)\n }\n i += 1\n break\n default:\n commandLen = PathNumberCommandLengthMap[command]\n for (let j = 0; j < commandLen; j++) smooth.push(data[i + j])\n i += commandLen\n }\n lastCommand = command\n countCommand++\n }\n\n return smooth\n}\n\n\nfunction isNeedConvert(data: IPathCommandData): boolean {\n let command: number, i = 0\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n i += 3\n break\n case L: //lineto(x, y)\n i += 3\n break\n case C: // bezierCurveTo()\n i += 7\n break\n case Z: //closepath()\n i += 1\n break\n default:\n return true\n }\n }\n return false\n}\n\nfunction findEndPoint(data: IPathCommandData, i: number): IPointData {\n let command: number, commandLen: number, x: number, y: number\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n return undefined\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n break\n case C: // bezierCurveTo()\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n break\n case Z: //closepath()\n return { x, y }\n default:\n commandLen = PathNumberCommandLengthMap[command]\n i += commandLen\n }\n }\n return undefined\n}\n\n\nfunction setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {\n const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, x1, y1)\n const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const { left, right } = two\n\n if (left && right) {\n data[i + 1] = right[0]; data[i + 2] = right[1]\n data[i + 3] = right[2]; data[i + 4] = right[3]\n }\n\n return two\n}\n\nfunction setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {\n const d = getTangentDistance(cornerRadius, toX, toY, x2, y2, nextX, nextY) // 反向\n const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向\n const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n\n if (left && right) {\n smooth.push(C, left[0], left[1], left[2], left[3], left[4], left[5])\n arcTo(smooth, toX, toY, nextX, nextY, cornerRadius, left[4], left[5], three)\n } else {\n smooth.push(C, x1, y1, x2, y2, toX, toY)\n }\n}","import { Plugin } from '@leafer-ui/draw'\nimport './PathCorner'\n\n\nPlugin.add('corner')"],"names":["getTangentDistance","r","x","y","lastX","lastY","nextX","nextY","ux","uy","vx","vy","lenU","Math","sqrt","lenV","cosTheta","safeCos","max","min","d","maxD","getCorrectT","x1","y1","x2","y2","toX","toY","chordLen","pow","vx0","vy0","v0mag","t","tempP","i","BezierHelper","getPointAndSet","dx","dy","currentDist","f_prime","getDerivative","abs","nextT","safeNextT","M","L","C","Z","Command","getCenterX","getCenterY","PointHelper","arcTo","PathCommandDataHelper","findEndPoint","data","command","commandLen","len","length","PathNumberCommandLengthMap","setAfterC","cornerRadius","fromX","fromY","two","cut","left","right","setBeforeC","smooth","three","push","PathCorner","_cornerSmoothing","radius","lastCommand","isNeedConvert","PathConvert","toCanvasData","countCommand","startX","startY","startR","secondX","secondY","isArray","isUndefined","end","j","Plugin","add"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"corner.min.cjs","sources":["../../../../../../src/in/packages/corner/src/helper.ts","../../../../../../src/in/packages/corner/src/PathCorner.ts","../../../../../../src/in/packages/corner/src/index.ts"],"sourcesContent":["import { BezierHelper } from '@leafer-ui/draw'\n\n\n// 获取圆角切线距离\nexport function getTangentDistance(r: number, x: number, y: number, lastX: number, lastY: number, nextX: number, nextY: number): number {\n // 1. 构造入射向量 U (P -> lastP) 和出射向量 V (P -> nextP)\n const ux = lastX - x, uy = lastY - y\n const vx = nextX - x, vy = nextY - y\n\n // 2. 计算向量长度(平方和开方)\n const lenU = Math.sqrt(ux * ux + uy * uy)\n const lenV = Math.sqrt(vx * vx + vy * vy)\n\n // 3. 边界防御:若线段长度几乎为0,则不产生圆角\n if (lenU < 0.001 || lenV < 0.001) return 0\n\n // 4. 计算向量夹角余弦值 cos(θ) = (U·V) / (|U|*|V|)\n const cosTheta = (ux * vx + uy * vy) / (lenU * lenV)\n\n // 5. 精度钳位:防止浮点误差导致 cos 越界 [-1, 1],避开分母为0的情况\n const safeCos = Math.max(-0.99999, Math.min(0.99999, cosTheta))\n\n // 6. 核心几何推导:d = r * sqrt((1 - cosθ) / (1 + cosθ))\n let d = r * Math.sqrt((1 - safeCos) / (1 + safeCos))\n\n // 7. 【关键性能与安全约束】:最大距离不得超过相邻边长的一半\n // 这样可以确保相邻顶点的圆角不会发生几何重叠或路径自交。\n const maxD = Math.min(lenU / 2, lenV / 2)\n return Math.min(d, maxD)\n}\n\n// 精准定位贝塞尔曲线参数 t\nexport function getCorrectT(d: number, x: number, y: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): number {\n if (d <= 0) return 0\n\n // 1. 预估总弦长(起点到终点的直线距离)\n const chordLen = Math.sqrt((toX - x) ** 2 + (toY - y) ** 2)\n\n // 2. 边界保护:若要求的距离超过弦长,为了路径安全,强制限制在曲线 50% 处\n if (d >= chordLen) return 0.5\n\n // 3. 初始猜测值估算:利用 t=0 处的瞬时速度矢量 v(0) = 3*(P1 - P0)\n const vx0 = 3 * (x1 - x)\n const vy0 = 3 * (y1 - y)\n let v0mag = Math.sqrt(vx0 * vx0 + vy0 * vy0)\n\n // 【优化点】:若起点与控制点重合(初速度为0),降级使用弦长线性比例,防止 NaN\n if (v0mag < 1e-6) v0mag = chordLen || 1\n\n let t = Math.min(0.5, d / v0mag)\n const tempP = { x: 0, y: 0 }\n\n // 4. 牛顿迭代 (Newton-Raphson) 循环\n for (let i = 0; i < 5; i++) {\n // 获取当前参数 t 对应的坐标点\n BezierHelper.getPointAndSet(t, x, y, x1, y1, x2, y2, toX, toY, tempP)\n\n const dx = tempP.x - x\n const dy = tempP.y - y\n const currentDist = Math.sqrt(dx * dx + dy * dy)\n\n // 数值稳定性检查:若当前点过于靠近起点,尝试向外探测\n if (currentDist < 1e-6) {\n t = t * 1.5\n continue\n }\n\n // 计算当前 t 处的导数向量 (x', y')\n const vxt = BezierHelper.getDerivative(t, x, x1, x2, toX)\n const vyt = BezierHelper.getDerivative(t, y, y1, y2, toY)\n\n // 计算目标函数的导数 f'(t) = (dx*x' + dy*y') / currentDist\n const f_prime = (dx * vxt + dy * vyt) / currentDist\n\n // 如果导数过小,说明进入平台期或计算异常,停止迭代\n if (Math.abs(f_prime) < 1e-6) break\n\n // 牛顿法公式:t_next = t - f(t) / f'(t)\n const deltaT = (currentDist - d) / f_prime\n const nextT = t - deltaT\n\n // 【收敛域保护】:强制限制在 [0, 0.6] 范围内寻找最优解,防止迭代跳出贝塞尔曲线有效区间\n const safeNextT = Math.max(0, Math.min(0.6, nextT))\n\n // 精度满足 1e-5 (像素级精度) 提前退出\n if (Math.abs(safeNextT - t) < 1e-5) {\n t = safeNextT\n break\n }\n t = safeNextT\n }\n\n // 最终返回结果,上限截断在 0.5 处,确保圆弧不会占据整条曲线导致形状崩坏\n return Math.max(0, Math.min(0.5, t))\n}","import { IPathCommandData, IPathCommandDataWithRadius, IPointData } from '@leafer-ui/interface'\nimport { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLengthMap, isArray, isUndefined, PathCommandDataHelper, BezierHelper, PathConvert } from '@leafer-ui/draw'\n\nimport { getCorrectT, getTangentDistance } from './helper'\n\n\nconst { M, L, C, Z } = Command, { abs } = Math\nconst { getCenterX, getCenterY } = PointHelper\nconst { arcTo } = PathCommandDataHelper\n\nPathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {\n\n const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角\n if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)\n else data = [...data] // 防止C命令修改数据造成污染\n\n let command: number, lastCommand: number, commandLen\n let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number\n if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0\n\n const len = data.length, three = len === 9 // 3个点时可以加大圆角\n const smooth: IPathCommandData = []\n\n while (i < len) {\n command = data[i]\n r = radius ? (isUndefined(radius[countCommand]) ? cornerRadius : radius[countCommand]) : cornerRadius\n switch (command) {\n case M: //moveto(x, y)\n startX = lastX = data[i + 1]\n startY = lastY = data[i + 2]\n startR = r\n i += 3\n const end = findEndPoint(data, i)\n switch (data[i]) { // next command\n case L: // lineTo()\n secondX = data[i + 1]\n secondY = data[i + 2]\n if (three) smooth.push(M, startX, startY)\n else {\n if (end) smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))\n else smooth.push(M, startX, startY)\n }\n break\n case C: // bezierCurveTo()\n if (end) {\n const { left, right } = setAfterC(data, i, r, end.x, end.y, startX, startY, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) {\n smooth.push(M, secondX = left[4], secondY = left[5])\n break\n }\n }\n default:\n smooth.push(M, secondX = startX, secondY = startY)\n }\n break\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n switch (data[i]) { // next command\n case L: // lineTo()\n arcTo(smooth, x, y, data[i + 1], data[i + 2], r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n case C: // bezierCurveTo()\n const { left, right } = setAfterC(data, i, r, lastX, lastY, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) arcTo(smooth, x, y, left[4], left[5], r, lastX, lastY, three)\n else smooth.push(L, x, y)\n break\n case Z: // closePath()\n arcTo(smooth, x, y, startX, startY, r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n default:\n smooth.push(L, x, y)\n }\n lastX = x\n lastY = y\n break\n case C:\n x1 = data[i + 1]\n y1 = data[i + 2]\n x2 = data[i + 3]\n y2 = data[i + 4]\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n switch (data[i]) { // next command\n case L: // lineTo()\n toX = data[i + 1], toY = data[i + 2]\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n case C: //\n smooth.push(C, x1, y1, x2, y2, x, y)\n break\n case Z: // closePath()\n toX = startX, toY = startY\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n default:\n smooth.push(C, x1, y1, x2, y2, x, y)\n }\n lastX = x\n lastY = y\n break\n case Z: //closepath()\n if (lastCommand !== Z) { // fix: 重复的 Z 导致的问题\n arcTo(smooth, startX, startY, secondX, secondY, startR, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n smooth.push(Z)\n }\n i += 1\n break\n default:\n commandLen = PathNumberCommandLengthMap[command]\n for (let j = 0; j < commandLen; j++) smooth.push(data[i + j])\n i += commandLen\n }\n lastCommand = command\n countCommand++\n }\n\n return smooth\n}\n\n\nfunction isNeedConvert(data: IPathCommandData): boolean {\n let command: number, i = 0\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n i += 3\n break\n case L: //lineto(x, y)\n i += 3\n break\n case C: // bezierCurveTo()\n i += 7\n break\n case Z: //closepath()\n i += 1\n break\n default:\n return true\n }\n }\n return false\n}\n\nfunction findEndPoint(data: IPathCommandData, i: number): IPointData {\n let command: number, commandLen: number, x: number, y: number\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n return undefined\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n break\n case C: // bezierCurveTo()\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n break\n case Z: //closepath()\n return { x, y }\n default:\n commandLen = PathNumberCommandLengthMap[command]\n i += commandLen\n }\n }\n return undefined\n}\n\n\nfunction setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {\n let targetX = x1, targetY = y1\n if (isSame(x1, fromX) && isSame(y1, fromY)) {\n targetX = x2; targetY = y2\n if (isSame(x2, fromX) && isSame(y2, fromY)) {\n targetX = toX; targetY = toY\n }\n }\n\n const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY)\n const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const { left, right } = two\n\n if (left && right) {\n data[i + 1] = right[0]; data[i + 2] = right[1]\n data[i + 3] = right[2]; data[i + 4] = right[3]\n }\n\n return two\n}\n\nfunction setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {\n let targetX = x2, targetY = y2\n if (isSame(targetX, toX) && isSame(targetY, toY)) {\n targetX = x1; targetY = y1\n if (isSame(targetX, toX) && isSame(targetY, toY)) {\n targetX = fromX; targetY = fromY\n }\n }\n\n const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY) // 反向\n const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向\n const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n\n if (left && right) {\n smooth.push(C, left[0], left[1], left[2], left[3], left[4], left[5])\n arcTo(smooth, toX, toY, nextX, nextY, cornerRadius, left[4], left[5], three)\n } else {\n smooth.push(C, x1, y1, x2, y2, toX, toY)\n }\n}\n\n\nfunction isSame(a: number, b: number): boolean {\n return abs(a - b) < 0.01\n}","import { Plugin } from '@leafer-ui/draw'\nimport './PathCorner'\n\n\nPlugin.add('corner')"],"names":["getTangentDistance","r","x","y","lastX","lastY","nextX","nextY","ux","uy","vx","vy","lenU","Math","sqrt","lenV","cosTheta","safeCos","max","min","d","maxD","getCorrectT","x1","y1","x2","y2","toX","toY","chordLen","pow","vx0","vy0","v0mag","t","tempP","i","BezierHelper","getPointAndSet","dx","dy","currentDist","f_prime","getDerivative","abs","nextT","safeNextT","M","L","C","Z","Command","getCenterX","getCenterY","PointHelper","arcTo","PathCommandDataHelper","findEndPoint","data","command","commandLen","len","length","PathNumberCommandLengthMap","setAfterC","cornerRadius","fromX","fromY","targetX","targetY","isSame","two","cut","left","right","setBeforeC","smooth","three","push","a","b","PathCorner","_cornerSmoothing","radius","lastCommand","isNeedConvert","PathConvert","toCanvasData","countCommand","startX","startY","startR","secondX","secondY","isArray","isUndefined","end","j","Plugin","add"],"mappings":"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"}
|
package/dist/corner.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e){"use strict";function t(e,t,a,r,n,s,c){const h=r-t,i=n-a,o=s-t,u=c-a,f=Math.sqrt(h*h+i*i),l=Math.sqrt(o*o+u*u);if(f<.001||l<.001)return 0;const p=(h*o+i*u)/(f*l),
|
|
1
|
+
!function(e){"use strict";function t(e,t,a,r,n,s,c){const h=r-t,i=n-a,o=s-t,u=c-a,f=Math.sqrt(h*h+i*i),l=Math.sqrt(o*o+u*u);if(f<.001||l<.001)return 0;const p=(h*o+i*u)/(f*l),b=Math.max(-.99999,Math.min(.99999,p));let M=e*Math.sqrt((1-b)/(1+b));const m=Math.min(f/2,l/2);return Math.min(M,m)}function a(t,a,r,n,s,c,h,i,o){if(t<=0)return 0;const u=Math.sqrt(Math.pow(i-a,2)+Math.pow(o-r,2));if(t>=u)return.5;const f=3*(n-a),l=3*(s-r);let p=Math.sqrt(f*f+l*l);p<1e-6&&(p=u||1);let b=Math.min(.5,t/p);const M={x:0,y:0};for(let u=0;u<5;u++){e.BezierHelper.getPointAndSet(b,a,r,n,s,c,h,i,o,M);const u=M.x-a,f=M.y-r,l=Math.sqrt(u*u+f*f);if(l<1e-6){b*=1.5;continue}const p=(u*e.BezierHelper.getDerivative(b,a,n,c,i)+f*e.BezierHelper.getDerivative(b,r,s,h,o))/l;if(Math.abs(p)<1e-6)break;const m=b-(l-t)/p,k=Math.max(0,Math.min(.6,m));if(Math.abs(k-b)<1e-5){b=k;break}b=k}return Math.max(0,Math.min(.5,b))}const{M:r,L:n,C:s,Z:c}=e.PathCommandMap,{abs:h}=Math,{getCenterX:i,getCenterY:o}=e.PointHelper,{arcTo:u}=e.PathCommandDataHelper;function f(t,a){let h,i,o,u;const f=t.length;for(;a<f;)switch(h=t[a],h){case r:return;case n:o=t[a+1],u=t[a+2],a+=3;break;case s:o=t[a+5],u=t[a+6],a+=7;break;case c:return{x:o,y:u};default:i=e.PathNumberCommandLengthMap[h],a+=i}}function l(r,n,s,c,h,i,o,u,f,l,p,M,m){let k=u,d=f;b(u,i)&&b(f,o)&&(k=l,d=p,b(l,i)&&b(p,o)&&(k=M,d=m));const g=a(t(s,i,o,c,h,k,d),i,o,u,f,l,p,M,m),C=e.BezierHelper.cut(g,i,o,u,f,l,p,M,m),{left:P,right:w}=C;return P&&w&&(r[n+1]=w[0],r[n+2]=w[1],r[n+3]=w[2],r[n+4]=w[3]),C}function p(r,n,c,h,i,o,f,l,p,M,m,k,d){let g=f,C=l;b(g,p)&&b(C,M)&&(g=i,C=o,b(g,p)&&b(C,M)&&(g=c,C=h));const P=a(t(n,p,M,g,C,m,k),p,M,f,l,i,o,c,h),{left:w,right:x}=e.BezierHelper.cut(1-P,c,h,i,o,f,l,p,M);w&&x?(r.push(s,w[0],w[1],w[2],w[3],w[4],w[5]),u(r,p,M,m,k,n,w[4],w[5],d)):r.push(s,i,o,f,l,p,M)}function b(e,t){return h(e-t)<.01}e.PathCorner.smooth=function(t,a,h){const b=t.radius;let M,m,k;t=function(e){let t,a=0;const h=e.length;for(;a<h;)switch(t=e[a],t){case r:case n:a+=3;break;case s:a+=7;break;case c:a+=1;break;default:return!0}return!1}(t)?e.PathConvert.toCanvasData(t,!0):[...t];let d,g,C,P,w,x,H,q=0,v=0,y=0,z=0,B=0,D=0,L=0,A=0,N=0,U=0,I=0;e.isArray(a)&&(a=a[0]||0);const S=t.length,T=9===S,X=[];for(;q<S;){switch(M=t[q],d=b?e.isUndefined(b[v])?a:b[v]:a,M){case r:B=U=t[q+1],D=I=t[q+2],L=d,q+=3;const a=f(t,q);switch(t[q]){case n:A=t[q+1],N=t[q+2],T?X.push(r,B,D):a?X.push(r,i(B,A),o(D,N)):X.push(r,B,D);break;case s:if(a){const{left:e,right:n}=l(t,q,d,a.x,a.y,B,D,t[q+1],t[q+2],t[q+3],t[q+4],t[q+5],t[q+6]);if(e&&n){X.push(r,A=e[4],N=e[5]);break}}default:X.push(r,A=B,N=D)}break;case n:switch(y=t[q+1],z=t[q+2],q+=3,t[q]){case n:u(X,y,z,t[q+1],t[q+2],d,U,I,T);break;case s:const{left:e,right:a}=l(t,q,d,U,I,y,z,t[q+1],t[q+2],t[q+3],t[q+4],t[q+5],t[q+6]);e&&a?u(X,y,z,e[4],e[5],d,U,I,T):X.push(n,y,z);break;case c:u(X,y,z,B,D,d,U,I,T);break;default:X.push(n,y,z)}U=y,I=z;break;case s:switch(g=t[q+1],C=t[q+2],P=t[q+3],w=t[q+4],y=t[q+5],z=t[q+6],q+=7,t[q]){case n:x=t[q+1],H=t[q+2],p(X,d,U,I,g,C,P,w,y,z,x,H,T);break;case s:X.push(s,g,C,P,w,y,z);break;case c:x=B,H=D,p(X,d,U,I,g,C,P,w,y,z,x,H,T);break;default:X.push(s,g,C,P,w,y,z)}U=y,I=z;break;case c:m!==c&&(u(X,B,D,A,N,L,U,I,T),X.push(c)),q+=1;break;default:k=e.PathNumberCommandLengthMap[M];for(let e=0;e<k;e++)X.push(t[q+e]);q+=k}m=M,v++}return X},e.Plugin.add("corner")}(LeaferUI);
|
|
2
2
|
//# sourceMappingURL=corner.min.js.map
|
package/dist/corner.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corner.min.js","sources":["../../../../../../src/in/packages/corner/src/helper.ts","../../../../../../src/in/packages/corner/src/PathCorner.ts","../../../../../../src/in/packages/corner/src/index.ts"],"sourcesContent":["import { BezierHelper } from '@leafer-ui/draw'\n\n\n// 获取圆角切线距离\nexport function getTangentDistance(r: number, x: number, y: number, lastX: number, lastY: number, nextX: number, nextY: number): number {\n // 1. 构造入射向量 U (P -> lastP) 和出射向量 V (P -> nextP)\n const ux = lastX - x, uy = lastY - y\n const vx = nextX - x, vy = nextY - y\n\n // 2. 计算向量长度(平方和开方)\n const lenU = Math.sqrt(ux * ux + uy * uy)\n const lenV = Math.sqrt(vx * vx + vy * vy)\n\n // 3. 边界防御:若线段长度几乎为0,则不产生圆角\n if (lenU < 0.001 || lenV < 0.001) return 0\n\n // 4. 计算向量夹角余弦值 cos(θ) = (U·V) / (|U|*|V|)\n const cosTheta = (ux * vx + uy * vy) / (lenU * lenV)\n\n // 5. 精度钳位:防止浮点误差导致 cos 越界 [-1, 1],避开分母为0的情况\n const safeCos = Math.max(-0.99999, Math.min(0.99999, cosTheta))\n\n // 6. 核心几何推导:d = r * sqrt((1 - cosθ) / (1 + cosθ))\n let d = r * Math.sqrt((1 - safeCos) / (1 + safeCos))\n\n // 7. 【关键性能与安全约束】:最大距离不得超过相邻边长的一半\n // 这样可以确保相邻顶点的圆角不会发生几何重叠或路径自交。\n const maxD = Math.min(lenU / 2, lenV / 2)\n return Math.min(d, maxD)\n}\n\n// 精准定位贝塞尔曲线参数 t\nexport function getCorrectT(d: number, x: number, y: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): number {\n if (d <= 0) return 0\n\n // 1. 预估总弦长(起点到终点的直线距离)\n const chordLen = Math.sqrt((toX - x) ** 2 + (toY - y) ** 2)\n\n // 2. 边界保护:若要求的距离超过弦长,为了路径安全,强制限制在曲线 50% 处\n if (d >= chordLen) return 0.5\n\n // 3. 初始猜测值估算:利用 t=0 处的瞬时速度矢量 v(0) = 3*(P1 - P0)\n const vx0 = 3 * (x1 - x)\n const vy0 = 3 * (y1 - y)\n let v0mag = Math.sqrt(vx0 * vx0 + vy0 * vy0)\n\n // 【优化点】:若起点与控制点重合(初速度为0),降级使用弦长线性比例,防止 NaN\n if (v0mag < 1e-6) v0mag = chordLen || 1\n\n let t = Math.min(0.5, d / v0mag)\n const tempP = { x: 0, y: 0 }\n\n // 4. 牛顿迭代 (Newton-Raphson) 循环\n for (let i = 0; i < 5; i++) {\n // 获取当前参数 t 对应的坐标点\n BezierHelper.getPointAndSet(t, x, y, x1, y1, x2, y2, toX, toY, tempP)\n\n const dx = tempP.x - x\n const dy = tempP.y - y\n const currentDist = Math.sqrt(dx * dx + dy * dy)\n\n // 数值稳定性检查:若当前点过于靠近起点,尝试向外探测\n if (currentDist < 1e-6) {\n t = t * 1.5\n continue\n }\n\n // 计算当前 t 处的导数向量 (x', y')\n const vxt = BezierHelper.getDerivative(t, x, x1, x2, toX)\n const vyt = BezierHelper.getDerivative(t, y, y1, y2, toY)\n\n // 计算目标函数的导数 f'(t) = (dx*x' + dy*y') / currentDist\n const f_prime = (dx * vxt + dy * vyt) / currentDist\n\n // 如果导数过小,说明进入平台期或计算异常,停止迭代\n if (Math.abs(f_prime) < 1e-6) break\n\n // 牛顿法公式:t_next = t - f(t) / f'(t)\n const deltaT = (currentDist - d) / f_prime\n const nextT = t - deltaT\n\n // 【收敛域保护】:强制限制在 [0, 0.6] 范围内寻找最优解,防止迭代跳出贝塞尔曲线有效区间\n const safeNextT = Math.max(0, Math.min(0.6, nextT))\n\n // 精度满足 1e-5 (像素级精度) 提前退出\n if (Math.abs(safeNextT - t) < 1e-5) {\n t = safeNextT\n break\n }\n t = safeNextT\n }\n\n // 最终返回结果,上限截断在 0.5 处,确保圆弧不会占据整条曲线导致形状崩坏\n return Math.max(0, Math.min(0.5, t))\n}","import { IPathCommandData, IPathCommandDataWithRadius, IPointData } from '@leafer-ui/interface'\nimport { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLengthMap, isArray, isUndefined, PathCommandDataHelper, BezierHelper, PathConvert } from '@leafer-ui/draw'\n\nimport { getCorrectT, getTangentDistance } from './helper'\n\n\nconst { M, L, C, Z } = Command\nconst { getCenterX, getCenterY } = PointHelper\nconst { arcTo } = PathCommandDataHelper\n\nPathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {\n\n const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角\n if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)\n\n let command: number, lastCommand: number, commandLen\n let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number\n if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0\n\n const len = data.length, three = len === 9 // 3个点时可以加大圆角\n const smooth: IPathCommandData = []\n\n while (i < len) {\n command = data[i]\n r = radius ? (isUndefined(radius[countCommand]) ? cornerRadius : radius[countCommand]) : cornerRadius\n switch (command) {\n case M: //moveto(x, y)\n startX = lastX = data[i + 1]\n startY = lastY = data[i + 2]\n startR = r\n i += 3\n const end = findEndPoint(data, i)\n switch (data[i]) { // next command\n case L: // lineTo()\n secondX = data[i + 1]\n secondY = data[i + 2]\n if (three) smooth.push(M, startX, startY)\n else {\n if (end) smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))\n else smooth.push(M, startX, startY)\n }\n break\n case C: // bezierCurveTo()\n if (end) {\n const { left, right } = setAfterC(data, i, r, end.x, end.y, startX, startY, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) {\n smooth.push(M, secondX = left[4], secondY = left[5])\n break\n }\n }\n default:\n smooth.push(M, secondX = startX, secondY = startY)\n }\n break\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n switch (data[i]) { // next command\n case L: // lineTo()\n arcTo(smooth, x, y, data[i + 1], data[i + 2], r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n case C: // bezierCurveTo()\n const { left, right } = setAfterC(data, i, r, lastX, lastY, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) arcTo(smooth, x, y, left[4], left[5], r, lastX, lastY, three)\n else smooth.push(L, x, y)\n break\n case Z: // closePath()\n arcTo(smooth, x, y, startX, startY, r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n default:\n smooth.push(L, x, y)\n }\n lastX = x\n lastY = y\n break\n case C:\n x1 = data[i + 1]\n y1 = data[i + 2]\n x2 = data[i + 3]\n y2 = data[i + 4]\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n switch (data[i]) { // next command\n case L: // lineTo()\n toX = data[i + 1], toY = data[i + 2]\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n case C: //\n smooth.push(C, x1, y1, x2, y2, x, y)\n break\n case Z: // closePath()\n toX = startX, toY = startY\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n }\n lastX = x\n lastY = y\n break\n case Z: //closepath()\n if (lastCommand !== Z) { // fix: 重复的 Z 导致的问题\n arcTo(smooth, startX, startY, secondX, secondY, startR, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n smooth.push(Z)\n }\n i += 1\n break\n default:\n commandLen = PathNumberCommandLengthMap[command]\n for (let j = 0; j < commandLen; j++) smooth.push(data[i + j])\n i += commandLen\n }\n lastCommand = command\n countCommand++\n }\n\n return smooth\n}\n\n\nfunction isNeedConvert(data: IPathCommandData): boolean {\n let command: number, i = 0\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n i += 3\n break\n case L: //lineto(x, y)\n i += 3\n break\n case C: // bezierCurveTo()\n i += 7\n break\n case Z: //closepath()\n i += 1\n break\n default:\n return true\n }\n }\n return false\n}\n\nfunction findEndPoint(data: IPathCommandData, i: number): IPointData {\n let command: number, commandLen: number, x: number, y: number\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n return undefined\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n break\n case C: // bezierCurveTo()\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n break\n case Z: //closepath()\n return { x, y }\n default:\n commandLen = PathNumberCommandLengthMap[command]\n i += commandLen\n }\n }\n return undefined\n}\n\n\nfunction setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {\n const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, x1, y1)\n const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const { left, right } = two\n\n if (left && right) {\n data[i + 1] = right[0]; data[i + 2] = right[1]\n data[i + 3] = right[2]; data[i + 4] = right[3]\n }\n\n return two\n}\n\nfunction setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {\n const d = getTangentDistance(cornerRadius, toX, toY, x2, y2, nextX, nextY) // 反向\n const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向\n const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n\n if (left && right) {\n smooth.push(C, left[0], left[1], left[2], left[3], left[4], left[5])\n arcTo(smooth, toX, toY, nextX, nextY, cornerRadius, left[4], left[5], three)\n } else {\n smooth.push(C, x1, y1, x2, y2, toX, toY)\n }\n}","import { Plugin } from '@leafer-ui/draw'\nimport './PathCorner'\n\n\nPlugin.add('corner')"],"names":["getTangentDistance","r","x","y","lastX","lastY","nextX","nextY","ux","uy","vx","vy","lenU","Math","sqrt","lenV","cosTheta","safeCos","max","min","d","maxD","getCorrectT","x1","y1","x2","y2","toX","toY","chordLen","pow","vx0","vy0","v0mag","t","tempP","i","BezierHelper","getPointAndSet","dx","dy","currentDist","f_prime","getDerivative","abs","nextT","safeNextT","M","L","C","Z","Command","getCenterX","getCenterY","PointHelper","arcTo","PathCommandDataHelper","findEndPoint","data","command","commandLen","len","length","PathNumberCommandLengthMap","setAfterC","cornerRadius","fromX","fromY","two","cut","left","right","setBeforeC","smooth","three","push","PathCorner","_cornerSmoothing","radius","lastCommand","isNeedConvert","PathConvert","toCanvasData","countCommand","startX","startY","startR","secondX","secondY","isArray","isUndefined","end","j","Plugin","add"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"corner.min.js","sources":["../../../../../../src/in/packages/corner/src/helper.ts","../../../../../../src/in/packages/corner/src/PathCorner.ts","../../../../../../src/in/packages/corner/src/index.ts"],"sourcesContent":["import { BezierHelper } from '@leafer-ui/draw'\n\n\n// 获取圆角切线距离\nexport function getTangentDistance(r: number, x: number, y: number, lastX: number, lastY: number, nextX: number, nextY: number): number {\n // 1. 构造入射向量 U (P -> lastP) 和出射向量 V (P -> nextP)\n const ux = lastX - x, uy = lastY - y\n const vx = nextX - x, vy = nextY - y\n\n // 2. 计算向量长度(平方和开方)\n const lenU = Math.sqrt(ux * ux + uy * uy)\n const lenV = Math.sqrt(vx * vx + vy * vy)\n\n // 3. 边界防御:若线段长度几乎为0,则不产生圆角\n if (lenU < 0.001 || lenV < 0.001) return 0\n\n // 4. 计算向量夹角余弦值 cos(θ) = (U·V) / (|U|*|V|)\n const cosTheta = (ux * vx + uy * vy) / (lenU * lenV)\n\n // 5. 精度钳位:防止浮点误差导致 cos 越界 [-1, 1],避开分母为0的情况\n const safeCos = Math.max(-0.99999, Math.min(0.99999, cosTheta))\n\n // 6. 核心几何推导:d = r * sqrt((1 - cosθ) / (1 + cosθ))\n let d = r * Math.sqrt((1 - safeCos) / (1 + safeCos))\n\n // 7. 【关键性能与安全约束】:最大距离不得超过相邻边长的一半\n // 这样可以确保相邻顶点的圆角不会发生几何重叠或路径自交。\n const maxD = Math.min(lenU / 2, lenV / 2)\n return Math.min(d, maxD)\n}\n\n// 精准定位贝塞尔曲线参数 t\nexport function getCorrectT(d: number, x: number, y: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): number {\n if (d <= 0) return 0\n\n // 1. 预估总弦长(起点到终点的直线距离)\n const chordLen = Math.sqrt((toX - x) ** 2 + (toY - y) ** 2)\n\n // 2. 边界保护:若要求的距离超过弦长,为了路径安全,强制限制在曲线 50% 处\n if (d >= chordLen) return 0.5\n\n // 3. 初始猜测值估算:利用 t=0 处的瞬时速度矢量 v(0) = 3*(P1 - P0)\n const vx0 = 3 * (x1 - x)\n const vy0 = 3 * (y1 - y)\n let v0mag = Math.sqrt(vx0 * vx0 + vy0 * vy0)\n\n // 【优化点】:若起点与控制点重合(初速度为0),降级使用弦长线性比例,防止 NaN\n if (v0mag < 1e-6) v0mag = chordLen || 1\n\n let t = Math.min(0.5, d / v0mag)\n const tempP = { x: 0, y: 0 }\n\n // 4. 牛顿迭代 (Newton-Raphson) 循环\n for (let i = 0; i < 5; i++) {\n // 获取当前参数 t 对应的坐标点\n BezierHelper.getPointAndSet(t, x, y, x1, y1, x2, y2, toX, toY, tempP)\n\n const dx = tempP.x - x\n const dy = tempP.y - y\n const currentDist = Math.sqrt(dx * dx + dy * dy)\n\n // 数值稳定性检查:若当前点过于靠近起点,尝试向外探测\n if (currentDist < 1e-6) {\n t = t * 1.5\n continue\n }\n\n // 计算当前 t 处的导数向量 (x', y')\n const vxt = BezierHelper.getDerivative(t, x, x1, x2, toX)\n const vyt = BezierHelper.getDerivative(t, y, y1, y2, toY)\n\n // 计算目标函数的导数 f'(t) = (dx*x' + dy*y') / currentDist\n const f_prime = (dx * vxt + dy * vyt) / currentDist\n\n // 如果导数过小,说明进入平台期或计算异常,停止迭代\n if (Math.abs(f_prime) < 1e-6) break\n\n // 牛顿法公式:t_next = t - f(t) / f'(t)\n const deltaT = (currentDist - d) / f_prime\n const nextT = t - deltaT\n\n // 【收敛域保护】:强制限制在 [0, 0.6] 范围内寻找最优解,防止迭代跳出贝塞尔曲线有效区间\n const safeNextT = Math.max(0, Math.min(0.6, nextT))\n\n // 精度满足 1e-5 (像素级精度) 提前退出\n if (Math.abs(safeNextT - t) < 1e-5) {\n t = safeNextT\n break\n }\n t = safeNextT\n }\n\n // 最终返回结果,上限截断在 0.5 处,确保圆弧不会占据整条曲线导致形状崩坏\n return Math.max(0, Math.min(0.5, t))\n}","import { IPathCommandData, IPathCommandDataWithRadius, IPointData } from '@leafer-ui/interface'\nimport { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLengthMap, isArray, isUndefined, PathCommandDataHelper, BezierHelper, PathConvert } from '@leafer-ui/draw'\n\nimport { getCorrectT, getTangentDistance } from './helper'\n\n\nconst { M, L, C, Z } = Command, { abs } = Math\nconst { getCenterX, getCenterY } = PointHelper\nconst { arcTo } = PathCommandDataHelper\n\nPathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {\n\n const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角\n if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)\n else data = [...data] // 防止C命令修改数据造成污染\n\n let command: number, lastCommand: number, commandLen\n let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number\n if (isArray(cornerRadius)) cornerRadius = cornerRadius[0] || 0\n\n const len = data.length, three = len === 9 // 3个点时可以加大圆角\n const smooth: IPathCommandData = []\n\n while (i < len) {\n command = data[i]\n r = radius ? (isUndefined(radius[countCommand]) ? cornerRadius : radius[countCommand]) : cornerRadius\n switch (command) {\n case M: //moveto(x, y)\n startX = lastX = data[i + 1]\n startY = lastY = data[i + 2]\n startR = r\n i += 3\n const end = findEndPoint(data, i)\n switch (data[i]) { // next command\n case L: // lineTo()\n secondX = data[i + 1]\n secondY = data[i + 2]\n if (three) smooth.push(M, startX, startY)\n else {\n if (end) smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))\n else smooth.push(M, startX, startY)\n }\n break\n case C: // bezierCurveTo()\n if (end) {\n const { left, right } = setAfterC(data, i, r, end.x, end.y, startX, startY, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) {\n smooth.push(M, secondX = left[4], secondY = left[5])\n break\n }\n }\n default:\n smooth.push(M, secondX = startX, secondY = startY)\n }\n break\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n switch (data[i]) { // next command\n case L: // lineTo()\n arcTo(smooth, x, y, data[i + 1], data[i + 2], r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n case C: // bezierCurveTo()\n const { left, right } = setAfterC(data, i, r, lastX, lastY, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])\n if (left && right) arcTo(smooth, x, y, left[4], left[5], r, lastX, lastY, three)\n else smooth.push(L, x, y)\n break\n case Z: // closePath()\n arcTo(smooth, x, y, startX, startY, r, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n break\n default:\n smooth.push(L, x, y)\n }\n lastX = x\n lastY = y\n break\n case C:\n x1 = data[i + 1]\n y1 = data[i + 2]\n x2 = data[i + 3]\n y2 = data[i + 4]\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n switch (data[i]) { // next command\n case L: // lineTo()\n toX = data[i + 1], toY = data[i + 2]\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n case C: //\n smooth.push(C, x1, y1, x2, y2, x, y)\n break\n case Z: // closePath()\n toX = startX, toY = startY\n setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)\n break\n default:\n smooth.push(C, x1, y1, x2, y2, x, y)\n }\n lastX = x\n lastY = y\n break\n case Z: //closepath()\n if (lastCommand !== Z) { // fix: 重复的 Z 导致的问题\n arcTo(smooth, startX, startY, secondX, secondY, startR, lastX, lastY, three) // use arcTo(x1, y1, x2, y2, radius)\n smooth.push(Z)\n }\n i += 1\n break\n default:\n commandLen = PathNumberCommandLengthMap[command]\n for (let j = 0; j < commandLen; j++) smooth.push(data[i + j])\n i += commandLen\n }\n lastCommand = command\n countCommand++\n }\n\n return smooth\n}\n\n\nfunction isNeedConvert(data: IPathCommandData): boolean {\n let command: number, i = 0\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n i += 3\n break\n case L: //lineto(x, y)\n i += 3\n break\n case C: // bezierCurveTo()\n i += 7\n break\n case Z: //closepath()\n i += 1\n break\n default:\n return true\n }\n }\n return false\n}\n\nfunction findEndPoint(data: IPathCommandData, i: number): IPointData {\n let command: number, commandLen: number, x: number, y: number\n const len = data.length\n while (i < len) {\n command = data[i]\n switch (command) {\n case M: //moveto(x, y)\n return undefined\n case L: //lineto(x, y)\n x = data[i + 1]\n y = data[i + 2]\n i += 3\n break\n case C: // bezierCurveTo()\n x = data[i + 5]\n y = data[i + 6]\n i += 7\n break\n case Z: //closepath()\n return { x, y }\n default:\n commandLen = PathNumberCommandLengthMap[command]\n i += commandLen\n }\n }\n return undefined\n}\n\n\nfunction setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {\n let targetX = x1, targetY = y1\n if (isSame(x1, fromX) && isSame(y1, fromY)) {\n targetX = x2; targetY = y2\n if (isSame(x2, fromX) && isSame(y2, fromY)) {\n targetX = toX; targetY = toY\n }\n }\n\n const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY)\n const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n const { left, right } = two\n\n if (left && right) {\n data[i + 1] = right[0]; data[i + 2] = right[1]\n data[i + 3] = right[2]; data[i + 4] = right[3]\n }\n\n return two\n}\n\nfunction setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {\n let targetX = x2, targetY = y2\n if (isSame(targetX, toX) && isSame(targetY, toY)) {\n targetX = x1; targetY = y1\n if (isSame(targetX, toX) && isSame(targetY, toY)) {\n targetX = fromX; targetY = fromY\n }\n }\n\n const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY) // 反向\n const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向\n const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)\n\n if (left && right) {\n smooth.push(C, left[0], left[1], left[2], left[3], left[4], left[5])\n arcTo(smooth, toX, toY, nextX, nextY, cornerRadius, left[4], left[5], three)\n } else {\n smooth.push(C, x1, y1, x2, y2, toX, toY)\n }\n}\n\n\nfunction isSame(a: number, b: number): boolean {\n return abs(a - b) < 0.01\n}","import { Plugin } from '@leafer-ui/draw'\nimport './PathCorner'\n\n\nPlugin.add('corner')"],"names":["getTangentDistance","r","x","y","lastX","lastY","nextX","nextY","ux","uy","vx","vy","lenU","Math","sqrt","lenV","cosTheta","safeCos","max","min","d","maxD","getCorrectT","x1","y1","x2","y2","toX","toY","chordLen","pow","vx0","vy0","v0mag","t","tempP","i","BezierHelper","getPointAndSet","dx","dy","currentDist","f_prime","getDerivative","abs","nextT","safeNextT","M","L","C","Z","Command","getCenterX","getCenterY","PointHelper","arcTo","PathCommandDataHelper","findEndPoint","data","command","commandLen","len","length","PathNumberCommandLengthMap","setAfterC","cornerRadius","fromX","fromY","targetX","targetY","isSame","two","cut","left","right","setBeforeC","smooth","three","push","a","b","PathCorner","_cornerSmoothing","radius","lastCommand","isNeedConvert","PathConvert","toCanvasData","countCommand","startX","startY","startR","secondX","secondY","isArray","isUndefined","end","j","Plugin","add"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-in/corner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "@leafer-in/corner",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"leaferjs"
|
|
35
35
|
],
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@leafer-ui/draw": "^2.0.
|
|
38
|
-
"@leafer-ui/interface": "^2.0.
|
|
39
|
-
"@leafer-in/interface": "^2.0.
|
|
37
|
+
"@leafer-ui/draw": "^2.0.8",
|
|
38
|
+
"@leafer-ui/interface": "^2.0.8",
|
|
39
|
+
"@leafer-in/interface": "^2.0.8"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/PathCorner.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { PathCorner, PointHelper, PathCommandMap as Command, PathNumberCommandLe
|
|
|
4
4
|
import { getCorrectT, getTangentDistance } from './helper'
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
const { M, L, C, Z } = Command
|
|
7
|
+
const { M, L, C, Z } = Command, { abs } = Math
|
|
8
8
|
const { getCenterX, getCenterY } = PointHelper
|
|
9
9
|
const { arcTo } = PathCommandDataHelper
|
|
10
10
|
|
|
@@ -12,6 +12,7 @@ PathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number
|
|
|
12
12
|
|
|
13
13
|
const radius = (data as any as IPathCommandDataWithRadius).radius // 独立圆角
|
|
14
14
|
if (isNeedConvert(data)) data = PathConvert.toCanvasData(data, true)
|
|
15
|
+
else data = [...data] // 防止C命令修改数据造成污染
|
|
15
16
|
|
|
16
17
|
let command: number, lastCommand: number, commandLen
|
|
17
18
|
let i = 0, countCommand = 0, x = 0, y = 0, startX = 0, startY = 0, startR = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0, r: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number
|
|
@@ -94,6 +95,8 @@ PathCorner.smooth = function smooth(data: IPathCommandData, cornerRadius: number
|
|
|
94
95
|
toX = startX, toY = startY
|
|
95
96
|
setBeforeC(smooth, r, lastX, lastY, x1, y1, x2, y2, x, y, toX, toY, three)
|
|
96
97
|
break
|
|
98
|
+
default:
|
|
99
|
+
smooth.push(C, x1, y1, x2, y2, x, y)
|
|
97
100
|
}
|
|
98
101
|
lastX = x
|
|
99
102
|
lastY = y
|
|
@@ -173,7 +176,15 @@ function findEndPoint(data: IPathCommandData, i: number): IPointData {
|
|
|
173
176
|
|
|
174
177
|
|
|
175
178
|
function setAfterC(data: IPathCommandData, i: number, cornerRadius: number, lastX: number, lastY: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number) {
|
|
176
|
-
|
|
179
|
+
let targetX = x1, targetY = y1
|
|
180
|
+
if (isSame(x1, fromX) && isSame(y1, fromY)) {
|
|
181
|
+
targetX = x2; targetY = y2
|
|
182
|
+
if (isSame(x2, fromX) && isSame(y2, fromY)) {
|
|
183
|
+
targetX = toX; targetY = toY
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const d = getTangentDistance(cornerRadius, fromX, fromY, lastX, lastY, targetX, targetY)
|
|
177
188
|
const t = getCorrectT(d, fromX, fromY, x1, y1, x2, y2, toX, toY)
|
|
178
189
|
const two = BezierHelper.cut(t, fromX, fromY, x1, y1, x2, y2, toX, toY)
|
|
179
190
|
const { left, right } = two
|
|
@@ -187,7 +198,15 @@ function setAfterC(data: IPathCommandData, i: number, cornerRadius: number, last
|
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
function setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, nextX: number, nextY: number, three: boolean) {
|
|
190
|
-
|
|
201
|
+
let targetX = x2, targetY = y2
|
|
202
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
203
|
+
targetX = x1; targetY = y1
|
|
204
|
+
if (isSame(targetX, toX) && isSame(targetY, toY)) {
|
|
205
|
+
targetX = fromX; targetY = fromY
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const d = getTangentDistance(cornerRadius, toX, toY, targetX, targetY, nextX, nextY) // 反向
|
|
191
210
|
const t = getCorrectT(d, toX, toY, x2, y2, x1, y1, fromX, fromY) // 反向
|
|
192
211
|
const { left, right } = BezierHelper.cut(1 - t, fromX, fromY, x1, y1, x2, y2, toX, toY)
|
|
193
212
|
|
|
@@ -197,4 +216,9 @@ function setBeforeC(smooth: IPathCommandData, cornerRadius: number, fromX: numbe
|
|
|
197
216
|
} else {
|
|
198
217
|
smooth.push(C, x1, y1, x2, y2, toX, toY)
|
|
199
218
|
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
function isSame(a: number, b: number): boolean {
|
|
223
|
+
return abs(a - b) < 0.01
|
|
200
224
|
}
|