canvu-react 0.3.32 → 0.3.33
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/index.cjs +167 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +167 -39
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +167 -39
- package/dist/native.cjs.map +1 -1
- package/dist/native.js +167 -39
- package/dist/native.js.map +1 -1
- package/dist/react.cjs +168 -40
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +168 -40
- package/dist/react.js.map +1 -1
- package/dist/realtime.cjs +1 -1
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +1 -1
- package/dist/realtime.js.map +1 -1
- package/dist/tldraw.cjs +167 -39
- package/dist/tldraw.cjs.map +1 -1
- package/dist/tldraw.js +167 -39
- package/dist/tldraw.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1043,24 +1043,153 @@ function svgNumber(value) {
|
|
|
1043
1043
|
const rounded = Math.round(value * 100) / 100;
|
|
1044
1044
|
return Number.isInteger(rounded) ? String(rounded) : String(rounded);
|
|
1045
1045
|
}
|
|
1046
|
-
function
|
|
1047
|
-
|
|
1048
|
-
return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
|
|
1049
|
-
}
|
|
1050
|
-
function architecturalCloudScallopCount(rx, ry, amplitude) {
|
|
1051
|
-
const perimeter = approximateEllipsePerimeter(rx, ry);
|
|
1052
|
-
const targetScallopLength = Math.max(10, amplitude * 2);
|
|
1046
|
+
function architecturalCloudScallopCount(perimeter, amplitude) {
|
|
1047
|
+
const targetScallopLength = Math.max(18, amplitude * 2.45);
|
|
1053
1048
|
let count = Math.max(12, Math.round(perimeter / targetScallopLength));
|
|
1054
1049
|
if (count % 2 === 1) count += 1;
|
|
1055
1050
|
return count;
|
|
1056
1051
|
}
|
|
1057
|
-
function
|
|
1058
|
-
const
|
|
1059
|
-
const
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1052
|
+
function roundedRectMetrics(width, height, inset, radius) {
|
|
1053
|
+
const left = inset;
|
|
1054
|
+
const top = inset;
|
|
1055
|
+
const right = width - inset;
|
|
1056
|
+
const bottom = height - inset;
|
|
1057
|
+
const rectWidth = Math.max(0, right - left);
|
|
1058
|
+
const rectHeight = Math.max(0, bottom - top);
|
|
1059
|
+
const normalizedRadius = Math.max(
|
|
1060
|
+
0,
|
|
1061
|
+
Math.min(radius, rectWidth / 2, rectHeight / 2)
|
|
1062
|
+
);
|
|
1063
|
+
const centerX = width / 2;
|
|
1064
|
+
const topHalfLength = Math.max(0, right - normalizedRadius - centerX);
|
|
1065
|
+
const horizontalLength = Math.max(0, rectWidth - normalizedRadius * 2);
|
|
1066
|
+
const verticalLength = Math.max(0, rectHeight - normalizedRadius * 2);
|
|
1067
|
+
const arcLength = normalizedRadius * (Math.PI / 2);
|
|
1068
|
+
return {
|
|
1069
|
+
left,
|
|
1070
|
+
top,
|
|
1071
|
+
right,
|
|
1072
|
+
bottom,
|
|
1073
|
+
radius: normalizedRadius,
|
|
1074
|
+
centerX,
|
|
1075
|
+
topHalfLength,
|
|
1076
|
+
horizontalLength,
|
|
1077
|
+
verticalLength,
|
|
1078
|
+
arcLength,
|
|
1079
|
+
perimeter: horizontalLength * 2 + verticalLength * 2 + Math.PI * 2 * normalizedRadius
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
function pointOnLine(startX, startY, endX, endY, t) {
|
|
1083
|
+
return [startX + (endX - startX) * t, startY + (endY - startY) * t];
|
|
1084
|
+
}
|
|
1085
|
+
function pointOnArc(centerX, centerY, radius, startAngle, endAngle, t) {
|
|
1086
|
+
const theta = startAngle + (endAngle - startAngle) * t;
|
|
1087
|
+
return [centerX + Math.cos(theta) * radius, centerY + Math.sin(theta) * radius];
|
|
1088
|
+
}
|
|
1089
|
+
function pointOnRoundedRectPath(metrics, distance) {
|
|
1090
|
+
if (metrics.perimeter <= 0) return [metrics.centerX, metrics.top];
|
|
1091
|
+
let remaining = (distance % metrics.perimeter + metrics.perimeter) % metrics.perimeter;
|
|
1092
|
+
const consume = (length) => {
|
|
1093
|
+
if (length <= 1e-9) return null;
|
|
1094
|
+
if (remaining <= length) return remaining / length;
|
|
1095
|
+
remaining -= length;
|
|
1096
|
+
return null;
|
|
1097
|
+
};
|
|
1098
|
+
let t = consume(metrics.topHalfLength);
|
|
1099
|
+
if (t != null) {
|
|
1100
|
+
return pointOnLine(
|
|
1101
|
+
metrics.centerX,
|
|
1102
|
+
metrics.top,
|
|
1103
|
+
metrics.right - metrics.radius,
|
|
1104
|
+
metrics.top,
|
|
1105
|
+
t
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
t = consume(metrics.arcLength);
|
|
1109
|
+
if (t != null) {
|
|
1110
|
+
return pointOnArc(
|
|
1111
|
+
metrics.right - metrics.radius,
|
|
1112
|
+
metrics.top + metrics.radius,
|
|
1113
|
+
metrics.radius,
|
|
1114
|
+
-Math.PI / 2,
|
|
1115
|
+
0,
|
|
1116
|
+
t
|
|
1117
|
+
);
|
|
1118
|
+
}
|
|
1119
|
+
t = consume(metrics.verticalLength);
|
|
1120
|
+
if (t != null) {
|
|
1121
|
+
return pointOnLine(
|
|
1122
|
+
metrics.right,
|
|
1123
|
+
metrics.top + metrics.radius,
|
|
1124
|
+
metrics.right,
|
|
1125
|
+
metrics.bottom - metrics.radius,
|
|
1126
|
+
t
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
t = consume(metrics.arcLength);
|
|
1130
|
+
if (t != null) {
|
|
1131
|
+
return pointOnArc(
|
|
1132
|
+
metrics.right - metrics.radius,
|
|
1133
|
+
metrics.bottom - metrics.radius,
|
|
1134
|
+
metrics.radius,
|
|
1135
|
+
0,
|
|
1136
|
+
Math.PI / 2,
|
|
1137
|
+
t
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
t = consume(metrics.horizontalLength);
|
|
1141
|
+
if (t != null) {
|
|
1142
|
+
return pointOnLine(
|
|
1143
|
+
metrics.right - metrics.radius,
|
|
1144
|
+
metrics.bottom,
|
|
1145
|
+
metrics.left + metrics.radius,
|
|
1146
|
+
metrics.bottom,
|
|
1147
|
+
t
|
|
1148
|
+
);
|
|
1149
|
+
}
|
|
1150
|
+
t = consume(metrics.arcLength);
|
|
1151
|
+
if (t != null) {
|
|
1152
|
+
return pointOnArc(
|
|
1153
|
+
metrics.left + metrics.radius,
|
|
1154
|
+
metrics.bottom - metrics.radius,
|
|
1155
|
+
metrics.radius,
|
|
1156
|
+
Math.PI / 2,
|
|
1157
|
+
Math.PI,
|
|
1158
|
+
t
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
t = consume(metrics.verticalLength);
|
|
1162
|
+
if (t != null) {
|
|
1163
|
+
return pointOnLine(
|
|
1164
|
+
metrics.left,
|
|
1165
|
+
metrics.bottom - metrics.radius,
|
|
1166
|
+
metrics.left,
|
|
1167
|
+
metrics.top + metrics.radius,
|
|
1168
|
+
t
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
t = consume(metrics.arcLength);
|
|
1172
|
+
if (t != null) {
|
|
1173
|
+
return pointOnArc(
|
|
1174
|
+
metrics.left + metrics.radius,
|
|
1175
|
+
metrics.top + metrics.radius,
|
|
1176
|
+
metrics.radius,
|
|
1177
|
+
Math.PI,
|
|
1178
|
+
Math.PI * 1.5,
|
|
1179
|
+
t
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
t = consume(metrics.topHalfLength);
|
|
1183
|
+
if (t != null) {
|
|
1184
|
+
return pointOnLine(
|
|
1185
|
+
metrics.left + metrics.radius,
|
|
1186
|
+
metrics.top,
|
|
1187
|
+
metrics.centerX,
|
|
1188
|
+
metrics.top,
|
|
1189
|
+
t
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
return [metrics.centerX, metrics.top];
|
|
1064
1193
|
}
|
|
1065
1194
|
function buildRectSvg(width, height, style = DEFAULT_STROKE_STYLE) {
|
|
1066
1195
|
return `<rect width="${width}" height="${height}" fill="none" stroke="${style.stroke}" stroke-width="${style.strokeWidth}" rx="4"${strokeOpacityAttr(style)} />`;
|
|
@@ -1075,35 +1204,34 @@ function buildArchitecturalCloudPathD(width, height, strokeWidth = DEFAULT_STROK
|
|
|
1075
1204
|
const h = Math.max(0, height);
|
|
1076
1205
|
if (w <= 0 || h <= 0) return "";
|
|
1077
1206
|
const inset = Math.max(0.5, strokeWidth / 2);
|
|
1078
|
-
const
|
|
1079
|
-
const
|
|
1080
|
-
if (
|
|
1081
|
-
const baseExponent = 3.6;
|
|
1207
|
+
const outerWidth = Math.max(0, w - inset * 2);
|
|
1208
|
+
const outerHeight = Math.max(0, h - inset * 2);
|
|
1209
|
+
if (outerWidth <= 0 || outerHeight <= 0) return "";
|
|
1082
1210
|
const amplitude = Math.min(
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
Math.max(
|
|
1211
|
+
outerWidth * 0.12,
|
|
1212
|
+
outerHeight * 0.12,
|
|
1213
|
+
Math.max(5, Math.min(14, Math.min(w, h) * 0.07))
|
|
1086
1214
|
);
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
const
|
|
1093
|
-
const
|
|
1094
|
-
|
|
1095
|
-
|
|
1215
|
+
const radius = Math.min(
|
|
1216
|
+
outerWidth / 2,
|
|
1217
|
+
outerHeight / 2,
|
|
1218
|
+
Math.max(amplitude * 2.5, outerHeight * 0.43)
|
|
1219
|
+
);
|
|
1220
|
+
const outer = roundedRectMetrics(w, h, inset, radius);
|
|
1221
|
+
const inner = roundedRectMetrics(
|
|
1222
|
+
w,
|
|
1223
|
+
h,
|
|
1224
|
+
inset + amplitude,
|
|
1225
|
+
Math.max(0, radius - amplitude)
|
|
1226
|
+
);
|
|
1227
|
+
const scallopCount = architecturalCloudScallopCount(outer.perimeter, amplitude);
|
|
1228
|
+
const [startX, startY] = pointOnRoundedRectPath(inner, 0);
|
|
1096
1229
|
const segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];
|
|
1097
1230
|
for (let index = 0; index < scallopCount; index += 1) {
|
|
1098
|
-
const
|
|
1099
|
-
const
|
|
1100
|
-
const
|
|
1101
|
-
const [
|
|
1102
|
-
segmentMid,
|
|
1103
|
-
outerRx,
|
|
1104
|
-
outerRy
|
|
1105
|
-
);
|
|
1106
|
-
const [endX, endY] = pointOnArchitecturalCloud(segmentEnd, innerRx, innerRy);
|
|
1231
|
+
const controlDistance = (index + 0.5) / scallopCount * outer.perimeter;
|
|
1232
|
+
const endDistance = (index + 1) / scallopCount * inner.perimeter;
|
|
1233
|
+
const [controlX, controlY] = pointOnRoundedRectPath(outer, controlDistance);
|
|
1234
|
+
const [endX, endY] = pointOnRoundedRectPath(inner, endDistance);
|
|
1107
1235
|
segments.push(
|
|
1108
1236
|
`Q${svgNumber(controlX)} ${svgNumber(controlY)} ${svgNumber(endX)} ${svgNumber(endY)}`
|
|
1109
1237
|
);
|