canvu-react 0.3.30 → 0.3.32

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/react.js CHANGED
@@ -279,40 +279,29 @@ function resolveStrokeStyle(item) {
279
279
  function strokeOpacityAttr(style) {
280
280
  return style.strokeOpacity != null ? ` stroke-opacity="${style.strokeOpacity}"` : "";
281
281
  }
282
- function clampNumber(value, min, max) {
283
- return Math.min(max, Math.max(min, value));
284
- }
285
282
  function svgNumber(value) {
286
283
  if (!Number.isFinite(value)) return "0";
287
- return Number(value.toFixed(3)).toString();
288
- }
289
- function architecturalCloudScallopCount(length, depth) {
290
- if (length <= 1e-6) return 0;
291
- return Math.max(1, Math.round(length / Math.max(depth * 2.05, 8)));
292
- }
293
- function appendHorizontalScallops(segments, startX, endX, y, controlY, count) {
294
- if (count <= 0) return;
295
- const step = (endX - startX) / count;
296
- for (let index = 1; index <= count; index += 1) {
297
- const x0 = startX + step * (index - 1);
298
- const x1 = index === count ? endX : startX + step * index;
299
- const cx = (x0 + x1) / 2;
300
- segments.push(
301
- `Q${svgNumber(cx)} ${svgNumber(controlY)} ${svgNumber(x1)} ${svgNumber(y)}`
302
- );
303
- }
304
- }
305
- function appendVerticalScallops(segments, startY, endY, x, controlX, count) {
306
- if (count <= 0) return;
307
- const step = (endY - startY) / count;
308
- for (let index = 1; index <= count; index += 1) {
309
- const y0 = startY + step * (index - 1);
310
- const y1 = index === count ? endY : startY + step * index;
311
- const cy = (y0 + y1) / 2;
312
- segments.push(
313
- `Q${svgNumber(controlX)} ${svgNumber(cy)} ${svgNumber(x)} ${svgNumber(y1)}`
314
- );
315
- }
284
+ const rounded = Math.round(value * 100) / 100;
285
+ return Number.isInteger(rounded) ? String(rounded) : String(rounded);
286
+ }
287
+ function approximateEllipsePerimeter(rx, ry) {
288
+ if (rx <= 0 || ry <= 0) return 0;
289
+ return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
290
+ }
291
+ function architecturalCloudScallopCount(rx, ry, amplitude) {
292
+ const perimeter = approximateEllipsePerimeter(rx, ry);
293
+ const targetScallopLength = Math.max(10, amplitude * 2);
294
+ let count = Math.max(12, Math.round(perimeter / targetScallopLength));
295
+ if (count % 2 === 1) count += 1;
296
+ return count;
297
+ }
298
+ function pointOnSuperellipse(centerX, centerY, radiusX, radiusY, theta, exponent) {
299
+ const cosTheta = Math.cos(theta);
300
+ const sinTheta = Math.sin(theta);
301
+ return [
302
+ centerX + Math.sign(cosTheta) * radiusX * Math.abs(cosTheta) ** (2 / exponent),
303
+ centerY + Math.sign(sinTheta) * radiusY * Math.abs(sinTheta) ** (2 / exponent)
304
+ ];
316
305
  }
317
306
  function buildRectSvg(width, height, style = DEFAULT_STROKE_STYLE) {
318
307
  return `<rect width="${width}" height="${height}" fill="none" stroke="${style.stroke}" stroke-width="${style.strokeWidth}" rx="4"${strokeOpacityAttr(style)} />`;
@@ -326,53 +315,41 @@ function buildArchitecturalCloudPathD(width, height, strokeWidth = DEFAULT_STROK
326
315
  const w = Math.max(0, width);
327
316
  const h = Math.max(0, height);
328
317
  if (w <= 0 || h <= 0) return "";
329
- const inset = Math.min(w / 2, h / 2, Math.max(0.5, strokeWidth / 2));
330
- const x0 = inset;
331
- const y0 = inset;
332
- const x1 = Math.max(x0, w - inset);
333
- const y1 = Math.max(y0, h - inset);
334
- const innerW = Math.max(0, x1 - x0);
335
- const innerH = Math.max(0, y1 - y0);
336
- if (innerW <= 0 || innerH <= 0) return "";
337
- const maxDepth = Math.max(0.5, Math.min(innerW, innerH) * 0.18);
338
- const depth = clampNumber(Math.min(w, h) * 0.08, 2, Math.min(12, maxDepth));
339
- const corner = Math.min(depth * 1.2, innerW / 2, innerH / 2);
340
- const topStart = x0 + corner;
341
- const topEnd = x1 - corner;
342
- const rightStart = y0 + corner;
343
- const rightEnd = y1 - corner;
344
- const bottomStart = x1 - corner;
345
- const bottomEnd = x0 + corner;
346
- const leftStart = y1 - corner;
347
- const leftEnd = y0 + corner;
348
- const topCount = architecturalCloudScallopCount(topEnd - topStart, depth);
349
- const rightCount = architecturalCloudScallopCount(rightEnd - rightStart, depth);
350
- const bottomCount = architecturalCloudScallopCount(bottomStart - bottomEnd, depth);
351
- const leftCount = architecturalCloudScallopCount(leftStart - leftEnd, depth);
352
- const segments = [`M${svgNumber(topStart)} ${svgNumber(y0)}`];
353
- appendHorizontalScallops(segments, topStart, topEnd, y0, y0 + depth, topCount);
354
- segments.push(
355
- `Q${svgNumber(x1)} ${svgNumber(y0)} ${svgNumber(x1)} ${svgNumber(rightStart)}`
356
- );
357
- appendVerticalScallops(segments, rightStart, rightEnd, x1, x1 - depth, rightCount);
358
- segments.push(
359
- `Q${svgNumber(x1)} ${svgNumber(y1)} ${svgNumber(bottomStart)} ${svgNumber(y1)}`
360
- );
361
- appendHorizontalScallops(
362
- segments,
363
- bottomStart,
364
- bottomEnd,
365
- y1,
366
- y1 - depth,
367
- bottomCount
368
- );
369
- segments.push(
370
- `Q${svgNumber(x0)} ${svgNumber(y1)} ${svgNumber(x0)} ${svgNumber(leftStart)}`
371
- );
372
- appendVerticalScallops(segments, leftStart, leftEnd, x0, x0 + depth, leftCount);
373
- segments.push(
374
- `Q${svgNumber(x0)} ${svgNumber(y0)} ${svgNumber(topStart)} ${svgNumber(y0)} Z`
318
+ const inset = Math.max(0.5, strokeWidth / 2);
319
+ const outerRx = Math.max(0, w / 2 - inset);
320
+ const outerRy = Math.max(0, h / 2 - inset);
321
+ if (outerRx <= 0 || outerRy <= 0) return "";
322
+ const baseExponent = 3.6;
323
+ const amplitude = Math.min(
324
+ outerRx * 0.45,
325
+ outerRy * 0.45,
326
+ Math.max(2, Math.min(7, Math.min(w, h) * 0.035))
375
327
  );
328
+ const innerRx = Math.max(0, outerRx - amplitude);
329
+ const innerRy = Math.max(0, outerRy - amplitude);
330
+ const scallopCount = architecturalCloudScallopCount(innerRx, innerRy, amplitude);
331
+ const angleStep = Math.PI * 2 / scallopCount;
332
+ const cx = w / 2;
333
+ const cy = h / 2;
334
+ const startAngle = -Math.PI / 2;
335
+ const pointOnArchitecturalCloud = (theta, radiusX, radiusY) => pointOnSuperellipse(cx, cy, radiusX, radiusY, theta, baseExponent);
336
+ const [startX, startY] = pointOnArchitecturalCloud(startAngle, innerRx, innerRy);
337
+ const segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];
338
+ for (let index = 0; index < scallopCount; index += 1) {
339
+ const segmentStart = startAngle + index * angleStep;
340
+ const segmentMid = segmentStart + angleStep / 2;
341
+ const segmentEnd = segmentStart + angleStep;
342
+ const [controlX, controlY] = pointOnArchitecturalCloud(
343
+ segmentMid,
344
+ outerRx,
345
+ outerRy
346
+ );
347
+ const [endX, endY] = pointOnArchitecturalCloud(segmentEnd, innerRx, innerRy);
348
+ segments.push(
349
+ `Q${svgNumber(controlX)} ${svgNumber(controlY)} ${svgNumber(endX)} ${svgNumber(endY)}`
350
+ );
351
+ }
352
+ segments.push("Z");
376
353
  return segments.join(" ");
377
354
  }
378
355
  function buildArchitecturalCloudSvg(width, height, style = DEFAULT_STROKE_STYLE) {
@@ -3129,6 +3106,7 @@ function ShapeContextMenu({
3129
3106
  }
3130
3107
  return createPortal(menu, document.body);
3131
3108
  }
3109
+ var architecturalCloudIconPath = "M11 3 Q15.72 1.11 16.44 3.31 Q19.25 2.05 18.39 4.28 Q20.81 4.17 19 7 Q20.81 9.83 18.39 9.72 Q19.25 11.95 16.44 10.69 Q15.72 12.89 11 11 Q6.28 12.89 5.56 10.69 Q2.75 11.95 3.61 9.72 Q1.19 9.83 3 7 Q1.19 4.17 3.61 4.28 Q2.75 2.05 5.56 3.31 Q6.28 1.11 11 3 Z";
3132
3110
  var base = {
3133
3111
  width: 20,
3134
3112
  height: 20,
@@ -3160,7 +3138,7 @@ function IconEllipse(props) {
3160
3138
  return /* @__PURE__ */ jsx("svg", { ...base, ...props, "aria-hidden": true, children: /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "12", rx: "9", ry: "6" }) });
3161
3139
  }
3162
3140
  function IconArchitecturalCloud(props) {
3163
- return /* @__PURE__ */ jsx("svg", { ...base, ...props, "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M6.5 7.5Q4.4 7.5 4.4 9.4Q3 9.9 3 11.6Q3 13.5 5.2 13.5Q5.8 16 8.3 15.2Q9.2 17.2 11.3 15.7Q12.8 17 14.3 15.5Q16.5 16.4 17 14Q20.7 13.7 20.2 10.9Q21 8.5 18 8.3Q17.2 5.9 14.8 6.7Q13.2 5.2 11.5 6.5Q9.1 5.1 7.8 7.2Q7.2 7.2 6.5 7.5Z" }) });
3141
+ return /* @__PURE__ */ jsx("svg", { ...base, ...props, "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: architecturalCloudIconPath, transform: "translate(1 5)" }) });
3164
3142
  }
3165
3143
  function IconLine(props) {
3166
3144
  return /* @__PURE__ */ jsx("svg", { ...base, ...props, "aria-hidden": true, children: /* @__PURE__ */ jsx("line", { x1: "5", y1: "19", x2: "19", y2: "5" }) });