@octane-xplat/smooth-corners 0.14.0 → 0.15.0

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.
@@ -1,95 +0,0 @@
1
- import { generateCommands } from "./path.js";
2
- import { Color, Utils } from "@nativescript/core";
3
- //#region src/apply.android.ts
4
- /** Android smooth-corners apply — custom Drawable paints background +
5
- * border along the generated path; a ViewOutlineProvider clips children
6
- * (`setPath` API 30+, `setConvexPath` 21–29 for convex curves); `shadow`
7
- * maps to `elevation`, which follows the outline. The `android` global is
8
- * touched only inside functions so the module is import-safe on iOS. */
9
- var PATH_KEY = "__smoothPath";
10
- function toAndroidPath(cmds) {
11
- const p = new android.graphics.Path();
12
- for (const c of cmds) switch (c.c) {
13
- case "M":
14
- p.moveTo(c.x, c.y);
15
- break;
16
- case "L":
17
- p.lineTo(c.x, c.y);
18
- break;
19
- case "C":
20
- p.cubicTo(c.x1, c.y1, c.x2, c.y2, c.x, c.y);
21
- break;
22
- case "A": {
23
- const rect = new android.graphics.RectF(c.cx - c.r, c.cy - c.r, c.cx + c.r, c.cy + c.r);
24
- p.arcTo(rect, c.startDeg, c.sweepDeg, false);
25
- break;
26
- }
27
- case "Z": p.close();
28
- }
29
- return p;
30
- }
31
- function makeDrawable(state) {
32
- return android.graphics.drawable.Drawable.extend({
33
- draw(canvas) {
34
- const path = state.path;
35
- if (!path) return;
36
- const bg = state.view?.backgroundColor ?? state.view?.style?.backgroundColor;
37
- const border = state.props.border;
38
- if (bg) {
39
- const paint = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG);
40
- paint.setStyle(android.graphics.Paint.Style.FILL);
41
- paint.setColor(new Color(bg).android);
42
- canvas.drawPath(path, paint);
43
- }
44
- if (border && border.width > 0 && border.color) {
45
- const paint = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG);
46
- paint.setStyle(android.graphics.Paint.Style.STROKE);
47
- paint.setStrokeWidth(Utils.layout.toDevicePixels(border.width) * 2);
48
- paint.setColor(new Color(border.color).android);
49
- canvas.drawPath(path, paint);
50
- }
51
- },
52
- getOpacity() {
53
- return android.graphics.PixelFormat.TRANSLUCENT;
54
- },
55
- setAlpha(_a) {},
56
- setColorFilter(_f) {}
57
- });
58
- }
59
- /** Clip the inner box: outline provider + background/border drawable. */
60
- function applySmoothClip(view, props) {
61
- const s = view?.[PATH_KEY] ?? (view[PATH_KEY] = {
62
- view,
63
- props,
64
- path: null,
65
- drawable: null
66
- });
67
- s.props = props;
68
- const v = view?.android;
69
- const size = view?.getActualSize?.();
70
- if (!v || !size || size.width <= 0 || size.height <= 0) return;
71
- s.path = toAndroidPath(generateCommands(Utils.layout.toDevicePixels(size.width), Utils.layout.toDevicePixels(size.height), props.corners));
72
- const path = s.path;
73
- v.setOutlineProvider(new (android.view.ViewOutlineProvider.extend({ getOutline(target, outline) {
74
- if (!path) return;
75
- if (android.os.Build.VERSION.SDK_INT >= 30) outline.setPath(path);
76
- else try {
77
- outline.setConvexPath(path);
78
- } catch {
79
- outline.setRect(0, 0, target.getWidth(), target.getHeight());
80
- }
81
- } }))());
82
- v.setClipToOutline(true);
83
- if (!s.drawable) {
84
- s.drawable = makeDrawable(s);
85
- v.setBackground(s.drawable);
86
- }
87
- s.drawable.setBounds(0, 0, v.getWidth(), v.getHeight());
88
- v.invalidate();
89
- if (props.shadow) v.setElevation(Utils.layout.toDevicePixels(props.shadow.blur ?? 8));
90
- }
91
- /** Android needs no separate shadow layer — `elevation` follows the inner
92
- * view's outline directly, so the outer hook is a no-op. */
93
- function applySmoothShadow(_view, _props) {}
94
- //#endregion
95
- export { applySmoothClip, applySmoothShadow };
@@ -1,92 +0,0 @@
1
- import { generateCommands } from "./path.js";
2
- import { Color } from "@nativescript/core";
3
- //#region src/apply.ios.ts
4
- /** iOS smooth-corners apply — CAShapeLayer mask on the inner view,
5
- * layer.shadow* on the outer. Native globals resolve lazily inside these
6
- * functions so the module is import-safe on Android bundles. */
7
- var rad = (deg) => deg * Math.PI / 180;
8
- function toCGPath(cmds) {
9
- const p = CGPathCreateMutable();
10
- for (const c of cmds) switch (c.c) {
11
- case "M":
12
- CGPathMoveToPoint(p, null, c.x, c.y);
13
- break;
14
- case "L":
15
- CGPathAddLineToPoint(p, null, c.x, c.y);
16
- break;
17
- case "C":
18
- CGPathAddCurveToPoint(p, null, c.x1, c.y1, c.x2, c.y2, c.x, c.y);
19
- break;
20
- case "A":
21
- CGPathAddArc(p, null, c.cx, c.cy, c.r, rad(c.startDeg), rad(c.startDeg + c.sweepDeg), c.sweepDeg < 0);
22
- break;
23
- case "Z": CGPathCloseSubpath(p);
24
- }
25
- return p;
26
- }
27
- var MASK_KEY = "__smoothMask";
28
- var BORDER_KEY = "__smoothBorder";
29
- function sizeOf(view) {
30
- const size = view?.getActualSize?.();
31
- return size && size.width > 0 && size.height > 0 ? {
32
- w: size.width,
33
- h: size.height
34
- } : null;
35
- }
36
- /** Clip the inner box: layer mask + optional border stroke layer. */
37
- function applySmoothClip(view, props) {
38
- const v = view?.ios;
39
- const size = v && sizeOf(view);
40
- if (!v || !size) return;
41
- const path = toCGPath(generateCommands(size.w, size.h, props.corners));
42
- let mask = v[MASK_KEY];
43
- if (!mask) {
44
- mask = CAShapeLayer.new();
45
- v[MASK_KEY] = mask;
46
- }
47
- mask.path = path;
48
- v.layer.mask = mask;
49
- let borderLayer = v[BORDER_KEY];
50
- const border = props.border;
51
- if (border && border.width > 0 && border.color) {
52
- if (!borderLayer) {
53
- borderLayer = CAShapeLayer.new();
54
- v[BORDER_KEY] = borderLayer;
55
- v.layer.addSublayer(borderLayer);
56
- }
57
- borderLayer.frame = v.layer.bounds;
58
- borderLayer.path = path;
59
- borderLayer.fillColor = null;
60
- borderLayer.strokeColor = new Color(border.color).ios.CGColor;
61
- borderLayer.lineWidth = border.width * 2;
62
- } else if (borderLayer) {
63
- borderLayer.removeFromSuperlayer();
64
- v[BORDER_KEY] = null;
65
- }
66
- }
67
- /** Drop shadow on the outer view (a masked layer can't show its own). */
68
- function applySmoothShadow(view, props) {
69
- const layer = view?.ios?.layer;
70
- if (!layer) return;
71
- const shadow = props.shadow;
72
- if (!shadow) {
73
- layer.shadowPath = null;
74
- layer.shadowOpacity = 0;
75
- return;
76
- }
77
- const size = sizeOf(view);
78
- if (!size) return;
79
- const spread = shadow.spread ?? 0;
80
- const w = size.w + spread * 2;
81
- const h = size.h + spread * 2;
82
- layer.shadowPath = toCGPath(generateCommands(w, h, props.corners));
83
- layer.shadowOffset = {
84
- width: (shadow.offsetX ?? 0) - spread,
85
- height: (shadow.offsetY ?? 0) - spread
86
- };
87
- layer.shadowColor = new Color(shadow.color ?? "#000000").ios.CGColor;
88
- layer.shadowOpacity = shadow.opacity ?? .35;
89
- layer.shadowRadius = shadow.blur ?? 0;
90
- }
91
- //#endregion
92
- export { applySmoothClip, applySmoothShadow };
@@ -1,61 +0,0 @@
1
- //#region src/layout-child.ts
2
- var OUTER_STYLE_KEYS = [
3
- "width",
4
- "height",
5
- "margin",
6
- "marginTop",
7
- "marginRight",
8
- "marginBottom",
9
- "marginLeft"
10
- ];
11
- var MARGIN_KEYS = [
12
- "margin",
13
- "marginTop",
14
- "marginRight",
15
- "marginBottom",
16
- "marginLeft"
17
- ];
18
- /** The inner box's `style` — everything except margins, which belong to the
19
- * element's border box and move out to the wrapper. Width/height stay: the
20
- * AppKit inner stack cannot stretch along its parent's main axis, so it
21
- * must keep its own size. */
22
- function paintedStyle(style) {
23
- if (!style || typeof style !== "object") return style;
24
- const next = { ...style };
25
- for (const key of MARGIN_KEYS) delete next[key];
26
- return next;
27
- }
28
- var CHILD_PROPS_ALWAYS = [
29
- "row",
30
- "col",
31
- "rowSpan",
32
- "colSpan",
33
- "left",
34
- "top",
35
- "horizontalAlignment",
36
- "verticalAlignment",
37
- "flexGrow",
38
- "flexShrink",
39
- "alignSelf",
40
- "order"
41
- ];
42
- var CHILD_PROPS_IF_SET = [
43
- "dock",
44
- "right",
45
- "bottom"
46
- ];
47
- /** Parent-layout metadata — must land on the OUTER wrapper, the node the
48
- * parent layout reads as its child. Values forward under the host's own
49
- * attribute names. */
50
- function outerLayoutProps(props) {
51
- const result = {};
52
- for (const key of CHILD_PROPS_ALWAYS) result[key] = props[key];
53
- for (const key of CHILD_PROPS_IF_SET) if (props[key] !== void 0) result[key] = props[key];
54
- const source = props.style && typeof props.style === "object" ? props.style : {};
55
- const style = {};
56
- for (const key of OUTER_STYLE_KEYS) if (source[key] !== void 0) style[key] = source[key];
57
- result.style = Object.keys(style).length > 0 ? style : void 0;
58
- return result;
59
- }
60
- //#endregion
61
- export { outerLayoutProps, paintedStyle };
@@ -1,424 +0,0 @@
1
- import { a as st, i as ft, p as ot } from "../../../node_modules/.pnpm/@lisse_core@0.7.2/node_modules/@lisse/core/dist/chunk-BL6ZAFLB.js";
2
- //#region src/path.ts
3
- /** Shared smooth-corner path generation — pure TS, no DOM. Emits one
4
- * `PathCommand[]` (absolute coords, arcs already center-parameterized) that
5
- * web stringifies to `d`, iOS feeds `CGPathAdd*`, Android feeds
6
- * `android.graphics.Path`, and macOS feeds `NSBezierPath`.
7
- *
8
- * Lisse curves (`squircle`/`superellipse`/`clothoid`/`arc`) delegate to
9
- * `@lisse/core/path`; `continuous` is our own builder — the Rosenfeld
10
- * `UIBezierPath` constants reproducing Apple's fixed continuous corner
11
- * (~0.25 px from SwiftUI `.continuous`; Lisse issue #103 /
12
- * tools/apple-continuous-export). */
13
- function resolveOne(c) {
14
- const cfg = typeof c === "number" ? { radius: c } : c ?? { radius: 0 };
15
- return {
16
- radius: cfg.radius,
17
- curve: cfg.curve ?? "continuous",
18
- smoothing: cfg.smoothing ?? .65,
19
- exponent: cfg.exponent ?? 4,
20
- preserveSmoothing: cfg.preserveSmoothing ?? true
21
- };
22
- }
23
- function resolveOptions(options) {
24
- if (typeof options === "number") {
25
- const c = resolveOne(options);
26
- return {
27
- topLeft: c,
28
- topRight: c,
29
- bottomRight: c,
30
- bottomLeft: c
31
- };
32
- }
33
- if ("radius" in options) {
34
- const c = resolveOne(options);
35
- return {
36
- topLeft: c,
37
- topRight: c,
38
- bottomRight: c,
39
- bottomLeft: c
40
- };
41
- }
42
- const p = options;
43
- return {
44
- topLeft: resolveOne(p.topLeft),
45
- topRight: resolveOne(p.topRight),
46
- bottomRight: resolveOne(p.bottomRight),
47
- bottomLeft: resolveOne(p.bottomLeft)
48
- };
49
- }
50
- /** Shoulder extent along each adjacent edge, as a multiple of R. */
51
- var CONT_P = 1.528665;
52
- var CONT_CURVE = [
53
- [1.08849296, 0],
54
- [.86840694, 0],
55
- [.63149379, .07491139],
56
- [.37282383, .16905956],
57
- [.16905956, .37282383],
58
- [.07491139, .63149379],
59
- [0, .86840694],
60
- [0, 1.08849296],
61
- [0, 1.52866498]
62
- ];
63
- var CONT_CURVE_YX = CONT_CURVE.map(([x, y]) => [y, x]);
64
- /** Absolute `C` commands for one continuous corner. `p` returned separately —
65
- * the tangent distance from the vertex along the incoming edge. */
66
- function continuousCorner(w, h, radius, budget, orient) {
67
- const r = Math.min(radius, budget / CONT_P);
68
- const p = CONT_P * r;
69
- if (r <= 0) return {
70
- p: 0,
71
- cmds: []
72
- };
73
- let fx;
74
- let fy;
75
- let seq = CONT_CURVE;
76
- switch (orient) {
77
- case "TR":
78
- fx = (x, _y) => w - x * r;
79
- fy = (_x, y) => y * r;
80
- break;
81
- case "BR":
82
- fx = (x, _y) => w - x * r;
83
- fy = (_x, y) => h - y * r;
84
- seq = CONT_CURVE_YX;
85
- break;
86
- case "BL":
87
- fx = (x, _y) => x * r;
88
- fy = (_x, y) => h - y * r;
89
- break;
90
- case "TL":
91
- fx = (x, _y) => x * r;
92
- fy = (_x, y) => 0 + y * r;
93
- seq = CONT_CURVE_YX;
94
- }
95
- const cmds = [];
96
- for (let i = 0; i < seq.length; i += 3) {
97
- const [c1, c2, e] = [
98
- seq[i],
99
- seq[i + 1],
100
- seq[i + 2]
101
- ];
102
- cmds.push({
103
- c: "C",
104
- x1: fx(c1[0], c1[1]),
105
- y1: fy(c1[0], c1[1]),
106
- x2: fx(c2[0], c2[1]),
107
- y2: fy(c2[0], c2[1]),
108
- x: fx(e[0], e[1]),
109
- y: fy(e[0], e[1])
110
- });
111
- }
112
- return {
113
- p,
114
- cmds
115
- };
116
- }
117
- /** Parse a curve builder's per-orient relative segment starting at `pen`.
118
- * Returns absolute commands. Lisse segments only emit `c`/`a`/`l`. */
119
- function segmentCommands(seg, pen) {
120
- return parsePath(seg, pen.x, pen.y).filter((c) => c.c !== "M");
121
- }
122
- var TOKEN = /[a-zA-Z]|[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
123
- var ARITY = {
124
- M: 2,
125
- L: 2,
126
- H: 1,
127
- V: 1,
128
- C: 6,
129
- S: 4,
130
- Q: 4,
131
- T: 2,
132
- A: 7,
133
- Z: 0
134
- };
135
- /** Endpoint→center for a circular SVG arc (φ=0 — every Lisse emitter).
136
- * Non-circular or rotated arcs throw: unsupported is loud, not silent. */
137
- function arcToCenter(x0, y0, rx, ry, rot, largeArc, sweep, x1, y1) {
138
- if (x0 === x1 && y0 === y1) return null;
139
- if (rx <= 0 || ry <= 0) return null;
140
- if (rx !== ry || rot !== 0) throw new Error(`smooth-corners: only circular unrotated arcs are supported (got a ${rx} ${ry} ${rot})`);
141
- const dx = (x0 - x1) / 2;
142
- const dy = (y0 - y1) / 2;
143
- const d2 = dx * dx + dy * dy;
144
- let r = rx;
145
- const lambda = d2 / (r * r);
146
- if (lambda > 1) r *= Math.sqrt(lambda);
147
- const h = Math.sqrt(Math.max(0, (r * r - d2) / d2));
148
- const sign = largeArc !== sweep ? 1 : -1;
149
- const cx = (x0 + x1) / 2 + sign * h * dy;
150
- const cy = (y0 + y1) / 2 - sign * h * dx;
151
- const deg = (v) => v * 180 / Math.PI;
152
- const start = deg(Math.atan2(y0 - cy, x0 - cx));
153
- let sweepDeg = deg(Math.atan2(y1 - cy, x1 - cx)) - start;
154
- if (sweep && sweepDeg <= 0) sweepDeg += 360;
155
- if (!sweep && sweepDeg >= 0) sweepDeg -= 360;
156
- return {
157
- c: "A",
158
- cx,
159
- cy,
160
- r,
161
- startDeg: start,
162
- sweepDeg,
163
- x: x1,
164
- y: y1
165
- };
166
- }
167
- /** Parse an SVG `d` string (or relative corner segment) into absolute
168
- * `PathCommand[]`. Supports M L H V C S Q T A Z; `pen` seeds relative
169
- * commands when parsing a mid-path segment. */
170
- function parsePath(d, penX = 0, penY = 0) {
171
- const tokens = d.match(TOKEN) ?? [];
172
- const out = [];
173
- let i = 0;
174
- let cmd = "";
175
- let px = penX;
176
- let py = penY;
177
- let sx = penX;
178
- let sy = penY;
179
- const num = () => {
180
- const t = tokens[i++];
181
- const n = Number(t);
182
- if (!Number.isFinite(n)) throw new Error(`smooth-corners: bad path token '${t}' in '${d}'`);
183
- return n;
184
- };
185
- while (i < tokens.length) {
186
- const t = tokens[i];
187
- if (/[a-zA-Z]/.test(t)) {
188
- cmd = t;
189
- i++;
190
- if (cmd === "Z" || cmd === "z") {
191
- out.push({ c: "Z" });
192
- px = sx;
193
- py = sy;
194
- continue;
195
- }
196
- }
197
- if (!cmd) throw new Error(`smooth-corners: path data missing command: '${d}'`);
198
- const rel = cmd === cmd.toLowerCase();
199
- const upper = cmd.toUpperCase();
200
- if (ARITY[upper] === void 0) throw new Error(`smooth-corners: unsupported path command '${cmd}'`);
201
- if (upper === "S" || upper === "Q" || upper === "T") throw new Error(`smooth-corners: '${upper}' commands are not supported`);
202
- switch (upper) {
203
- case "M": {
204
- const x = num() + (rel ? px : 0);
205
- const y = num() + (rel ? py : 0);
206
- out.push({
207
- c: "M",
208
- x,
209
- y
210
- });
211
- px = sx = x;
212
- py = sy = y;
213
- cmd = rel ? "l" : "L";
214
- break;
215
- }
216
- case "L": {
217
- const x = num() + (rel ? px : 0);
218
- const y = num() + (rel ? py : 0);
219
- out.push({
220
- c: "L",
221
- x,
222
- y
223
- });
224
- px = x;
225
- py = y;
226
- break;
227
- }
228
- case "H": {
229
- const x = num() + (rel ? px : 0);
230
- out.push({
231
- c: "L",
232
- x,
233
- y: py
234
- });
235
- px = x;
236
- break;
237
- }
238
- case "V": {
239
- const y = num() + (rel ? py : 0);
240
- out.push({
241
- c: "L",
242
- x: px,
243
- y
244
- });
245
- py = y;
246
- break;
247
- }
248
- case "C": {
249
- const x1 = num() + (rel ? px : 0);
250
- const y1 = num() + (rel ? py : 0);
251
- const x2 = num() + (rel ? px : 0);
252
- const y2 = num() + (rel ? py : 0);
253
- const x = num() + (rel ? px : 0);
254
- const y = num() + (rel ? py : 0);
255
- out.push({
256
- c: "C",
257
- x1,
258
- y1,
259
- x2,
260
- y2,
261
- x,
262
- y
263
- });
264
- px = x;
265
- py = y;
266
- break;
267
- }
268
- case "A": {
269
- const rx = num();
270
- const ry = num();
271
- const rot = num();
272
- const fa = num();
273
- const fs = num();
274
- const x = num() + (rel ? px : 0);
275
- const y = num() + (rel ? py : 0);
276
- const arc = arcToCenter(px, py, rx, ry, rot, fa, fs, x, y);
277
- if (arc) out.push(arc);
278
- else out.push({
279
- c: "L",
280
- x,
281
- y
282
- });
283
- px = x;
284
- py = y;
285
- break;
286
- }
287
- }
288
- }
289
- return out;
290
- }
291
- function lisseCornerSeg(corner, radius, budget, orient, pen) {
292
- const out = ft(corner.curve)({
293
- cornerRadius: radius,
294
- smoothing: corner.smoothing,
295
- exponent: corner.exponent,
296
- preserveSmoothing: corner.preserveSmoothing,
297
- roundingAndSmoothingBudget: budget
298
- });
299
- return {
300
- p: out.p,
301
- cmds: segmentCommands(out.pathSegment(orient), pen)
302
- };
303
- }
304
- function cornerCmds(corner, normalized, orient, pen, w, h) {
305
- if (corner.curve === "continuous") return continuousCorner(w, h, normalized.radius, normalized.roundingAndSmoothingBudget, orient);
306
- return lisseCornerSeg(corner, normalized.radius, normalized.roundingAndSmoothingBudget, orient, pen);
307
- }
308
- var RECT = [
309
- {
310
- c: "M",
311
- x: 0,
312
- y: 0
313
- },
314
- {
315
- c: "L",
316
- x: 0,
317
- y: 0
318
- },
319
- {
320
- c: "L",
321
- x: 0,
322
- y: 0
323
- },
324
- {
325
- c: "L",
326
- x: 0,
327
- y: 0
328
- },
329
- { c: "Z" }
330
- ];
331
- /** Absolute command list for the smooth-cornered rect. When no corner uses
332
- * `continuous`, delegates to `@lisse/core` `generatePath` (keeping its
333
- * capsule/blend fast paths) and parses the result; otherwise stitches
334
- * per-corner segments itself (per-corner mixing with `continuous`). */
335
- function generateCommands(width, height, options) {
336
- if (width <= 0 || height <= 0) return RECT;
337
- const corners = resolveOptions(options);
338
- if (!(corners.topLeft.curve === "continuous" || corners.topRight.curve === "continuous" || corners.bottomRight.curve === "continuous" || corners.bottomLeft.curve === "continuous")) return parsePath(ot(width, height, lisseOptions(corners)));
339
- const normalized = st({
340
- topLeftCornerRadius: corners.topLeft.radius,
341
- topRightCornerRadius: corners.topRight.radius,
342
- bottomRightCornerRadius: corners.bottomRight.radius,
343
- bottomLeftCornerRadius: corners.bottomLeft.radius,
344
- width,
345
- height
346
- });
347
- const emit = (corner, n, orient, entryX, entryY) => cornerCmds(corner, n, orient, {
348
- x: entryX,
349
- y: entryY
350
- }, width, height);
351
- const pTL = previewP(corners.topLeft, normalized.topLeft, "TL", width, height);
352
- const pTR = previewP(corners.topRight, normalized.topRight, "TR", width, height);
353
- const pBR = previewP(corners.bottomRight, normalized.bottomRight, "BR", width, height);
354
- const pBL = previewP(corners.bottomLeft, normalized.bottomLeft, "BL", width, height);
355
- const out = [{
356
- c: "M",
357
- x: pTL,
358
- y: 0
359
- }];
360
- out.push({
361
- c: "L",
362
- x: width - pTR,
363
- y: 0
364
- });
365
- const tr = emit(corners.topRight, normalized.topRight, "TR", width - pTR, 0);
366
- out.push(...tr.cmds);
367
- out.push({
368
- c: "L",
369
- x: width,
370
- y: height - pBR
371
- });
372
- const br = emit(corners.bottomRight, normalized.bottomRight, "BR", width, height - pBR);
373
- out.push(...br.cmds);
374
- out.push({
375
- c: "L",
376
- x: pBL,
377
- y: height
378
- });
379
- const bl = emit(corners.bottomLeft, normalized.bottomLeft, "BL", pBL, height);
380
- out.push(...bl.cmds);
381
- out.push({
382
- c: "L",
383
- x: 0,
384
- y: pTL
385
- });
386
- const tl = emit(corners.topLeft, normalized.topLeft, "TL", 0, pTL);
387
- out.push(...tl.cmds);
388
- out.push({ c: "Z" });
389
- return out;
390
- }
391
- /** A corner's tangent distance without emitting commands (cheap for
392
- * continuous; re-runs the lisse builder for other curves — called once per
393
- * frame per corner, acceptable). */
394
- function previewP(corner, n, orient, w, h) {
395
- return cornerCmds(corner, n, orient, {
396
- x: 0,
397
- y: 0
398
- }, w, h).p;
399
- }
400
- function lisseOptions(corners) {
401
- const { topLeft: a, topRight: b, bottomRight: c, bottomLeft: d } = corners;
402
- if (a.radius === b.radius && a.radius === c.radius && a.radius === d.radius && a.curve === b.curve && a.curve === c.curve && a.curve === d.curve && a.smoothing === b.smoothing && a.smoothing === c.smoothing && a.smoothing === d.smoothing && a.exponent === b.exponent && a.exponent === c.exponent && a.exponent === d.exponent && a.preserveSmoothing === b.preserveSmoothing && a.preserveSmoothing === c.preserveSmoothing && a.preserveSmoothing === d.preserveSmoothing) return {
403
- radius: a.radius,
404
- curve: a.curve,
405
- smoothing: a.smoothing,
406
- exponent: a.exponent,
407
- preserveSmoothing: a.preserveSmoothing
408
- };
409
- const per = (c) => ({
410
- radius: c.radius,
411
- curve: c.curve,
412
- smoothing: c.smoothing,
413
- exponent: c.exponent,
414
- preserveSmoothing: c.preserveSmoothing
415
- });
416
- return {
417
- topLeft: per(a),
418
- topRight: per(b),
419
- bottomRight: per(c),
420
- bottomLeft: per(d)
421
- };
422
- }
423
- //#endregion
424
- export { generateCommands, parsePath };
package/dist/web/index.js DELETED
@@ -1,2 +0,0 @@
1
- import { SmoothCorners } from "./packages/smooth-corners/src/SmoothCorners.web.tsrx.js";
2
- export { SmoothCorners };