@jiujue/react-canvas-fiber 2.0.4 → 2.0.6

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.d.cts CHANGED
@@ -86,6 +86,7 @@ type ViewProps = {
86
86
  children?: ReactNode;
87
87
  style?: YogaStyle;
88
88
  background?: string;
89
+ border?: string;
89
90
  borderRadius?: number;
90
91
  scrollX?: boolean;
91
92
  scrollY?: boolean;
@@ -157,6 +158,7 @@ type ImageProps = {
157
158
  style?: YogaStyle;
158
159
  src: string;
159
160
  objectFit?: 'cover' | 'contain' | 'fill';
161
+ borderRadius?: number;
160
162
  pointerEvents?: PointerEventsMode;
161
163
  onPointerDownCapture?: CanvasPointerEventHandler;
162
164
  onPointerDown?: CanvasPointerEventHandler;
package/dist/index.d.ts CHANGED
@@ -86,6 +86,7 @@ type ViewProps = {
86
86
  children?: ReactNode;
87
87
  style?: YogaStyle;
88
88
  background?: string;
89
+ border?: string;
89
90
  borderRadius?: number;
90
91
  scrollX?: boolean;
91
92
  scrollY?: boolean;
@@ -157,6 +158,7 @@ type ImageProps = {
157
158
  style?: YogaStyle;
158
159
  src: string;
159
160
  objectFit?: 'cover' | 'contain' | 'fill';
161
+ borderRadius?: number;
160
162
  pointerEvents?: PointerEventsMode;
161
163
  onPointerDownCapture?: CanvasPointerEventHandler;
162
164
  onPointerDown?: CanvasPointerEventHandler;
package/dist/index.js CHANGED
@@ -88,14 +88,56 @@ function drawRoundedRect(ctx, x, y, w, h, r) {
88
88
  function rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
89
89
  return ax < bx + bw && ax + aw > bx && ay < by + bh && ay + ah > by;
90
90
  }
91
+ function resolveBorder(value) {
92
+ if (typeof value !== "string") return null;
93
+ const raw = value.trim();
94
+ if (!raw) return null;
95
+ const normalized = raw.replace(/\s+/g, " ");
96
+ const match = normalized.match(/^([0-9]*\.?[0-9]+)(px)?\s+(?:solid\s+)?(.+)$/i);
97
+ if (match) {
98
+ const width = Number(match[1]);
99
+ const color = match[3]?.trim();
100
+ if (Number.isFinite(width) && width > 0 && color) return { width, color };
101
+ return null;
102
+ }
103
+ const withoutSolid = normalized.replace(/\bsolid\b/gi, " ").replace(/\s+/g, " ").trim();
104
+ const match2 = withoutSolid.match(/^([0-9]*\.?[0-9]+)(px)?\s+(.+)$/i);
105
+ if (match2) {
106
+ const width = Number(match2[1]);
107
+ const color = match2[3]?.trim();
108
+ if (Number.isFinite(width) && width > 0 && color) return { width, color };
109
+ return null;
110
+ }
111
+ if (/^[0-9]/.test(withoutSolid)) return null;
112
+ if (!withoutSolid) return null;
113
+ return { width: 1, color: withoutSolid };
114
+ }
115
+ function drawBorder(ctx, x, y, w, h, radius, border) {
116
+ if (!Number.isFinite(border.width) || border.width <= 0) return;
117
+ const inset = border.width / 2;
118
+ const bw = w - border.width;
119
+ const bh = h - border.width;
120
+ if (bw <= 0 || bh <= 0) return;
121
+ ctx.save();
122
+ ctx.strokeStyle = border.color;
123
+ ctx.lineWidth = border.width;
124
+ drawRoundedRect(ctx, x + inset, y + inset, bw, bh, Math.max(0, radius - inset));
125
+ ctx.stroke();
126
+ ctx.restore();
127
+ }
91
128
  function drawNode(state, node, offsetX, offsetY) {
92
129
  const { ctx } = state;
93
130
  const x = offsetX + node.layout.x;
94
131
  const y = offsetY + node.layout.y;
95
132
  const w = node.layout.width;
96
133
  const h = node.layout.height;
134
+ let viewBorder = null;
135
+ let viewRadius = 0;
136
+ let viewIsScroll = false;
97
137
  if (node.type === "View") {
98
138
  const background = node.props.background;
139
+ viewBorder = resolveBorder(node.props.border);
140
+ viewRadius = node.props.borderRadius ?? 0;
99
141
  const scrollX = !!node.props?.scrollX;
100
142
  const scrollY = !!node.props?.scrollY;
101
143
  const scrollLeft = scrollX ? node.scrollLeft ?? 0 : 0;
@@ -111,14 +153,14 @@ function drawNode(state, node, offsetX, offsetY) {
111
153
  const maxScrollLeft = Math.max(0, contentWidth - w);
112
154
  const maxScrollTop = Math.max(0, contentHeight - h);
113
155
  if (background) {
114
- const radius = node.props.borderRadius ?? 0;
115
156
  ctx.save();
116
157
  ctx.fillStyle = background;
117
- drawRoundedRect(ctx, x, y, w, h, radius);
158
+ drawRoundedRect(ctx, x, y, w, h, viewRadius);
118
159
  ctx.fill();
119
160
  ctx.restore();
120
161
  }
121
162
  if (scrollX || scrollY) {
163
+ viewIsScroll = true;
122
164
  ctx.save();
123
165
  ctx.beginPath();
124
166
  ctx.rect(x, y, w, h);
@@ -195,6 +237,7 @@ function drawNode(state, node, offsetX, offsetY) {
195
237
  ctx.fill();
196
238
  ctx.restore();
197
239
  }
240
+ if (viewBorder) drawBorder(ctx, x, y, w, h, viewRadius, viewBorder);
198
241
  return;
199
242
  }
200
243
  }
@@ -234,6 +277,7 @@ function drawNode(state, node, offsetX, offsetY) {
234
277
  const { imageInstance } = node;
235
278
  if (imageInstance && imageInstance.complete && imageInstance.naturalWidth > 0) {
236
279
  const objectFit = node.props.objectFit || "contain";
280
+ const radius = node.props.borderRadius ?? 0;
237
281
  const srcW = imageInstance.naturalWidth;
238
282
  const srcH = imageInstance.naturalHeight;
239
283
  let dstX = x;
@@ -261,7 +305,7 @@ function drawNode(state, node, offsetX, offsetY) {
261
305
  }
262
306
  ctx.save();
263
307
  ctx.beginPath();
264
- drawRoundedRect(ctx, x, y, w, h, 0);
308
+ drawRoundedRect(ctx, x, y, w, h, radius);
265
309
  ctx.clip();
266
310
  ctx.drawImage(imageInstance, srcX, srcY, finalSrcW, finalSrcH, dstX, dstY, dstW, dstH);
267
311
  ctx.restore();
@@ -270,6 +314,9 @@ function drawNode(state, node, offsetX, offsetY) {
270
314
  for (const child of node.children) {
271
315
  drawNode(state, child, x, y);
272
316
  }
317
+ if (node.type === "View" && !viewIsScroll && viewBorder) {
318
+ drawBorder(ctx, x, y, w, h, viewRadius, viewBorder);
319
+ }
273
320
  }
274
321
  function drawTree(root, ctx, dpr, clearColor, defaults) {
275
322
  const w = ctx.canvas.width;