@jiujue/react-canvas-fiber 2.1.1 → 2.1.2
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/README.md +4 -0
- package/README.zh.md +4 -0
- package/dist/index.cjs +149 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -86,6 +86,10 @@ type ViewProps = {
|
|
|
86
86
|
children?: ReactNode;
|
|
87
87
|
style?: YogaStyle;
|
|
88
88
|
background?: string;
|
|
89
|
+
backgroundImage?: string;
|
|
90
|
+
backgroundPosition?: string;
|
|
91
|
+
backgroundSize?: string;
|
|
92
|
+
backgroundRepeat?: string;
|
|
89
93
|
border?: string;
|
|
90
94
|
borderRadius?: number;
|
|
91
95
|
scrollX?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,10 @@ type ViewProps = {
|
|
|
86
86
|
children?: ReactNode;
|
|
87
87
|
style?: YogaStyle;
|
|
88
88
|
background?: string;
|
|
89
|
+
backgroundImage?: string;
|
|
90
|
+
backgroundPosition?: string;
|
|
91
|
+
backgroundSize?: string;
|
|
92
|
+
backgroundRepeat?: string;
|
|
89
93
|
border?: string;
|
|
90
94
|
borderRadius?: number;
|
|
91
95
|
scrollX?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,8 @@ function createNode(type, props) {
|
|
|
42
42
|
};
|
|
43
43
|
if (type === "Image") {
|
|
44
44
|
node.imageInstance = null;
|
|
45
|
+
} else if (type === "View") {
|
|
46
|
+
node.backgroundImageInstance = null;
|
|
45
47
|
}
|
|
46
48
|
return node;
|
|
47
49
|
}
|
|
@@ -125,6 +127,105 @@ function drawBorder(ctx, x, y, w, h, radius, border) {
|
|
|
125
127
|
ctx.stroke();
|
|
126
128
|
ctx.restore();
|
|
127
129
|
}
|
|
130
|
+
function resolveBgRepeat(repeat) {
|
|
131
|
+
if (!repeat) return "repeat";
|
|
132
|
+
if (repeat === "no-repeat" || repeat === "repeat-x" || repeat === "repeat-y" || repeat === "repeat")
|
|
133
|
+
return repeat;
|
|
134
|
+
return "repeat";
|
|
135
|
+
}
|
|
136
|
+
function parseBgSize(size, w, h, imgW, imgH) {
|
|
137
|
+
if (!size || size === "auto") return { width: imgW, height: imgH };
|
|
138
|
+
if (size === "cover") {
|
|
139
|
+
const scale = Math.max(w / imgW, h / imgH);
|
|
140
|
+
return { width: imgW * scale, height: imgH * scale };
|
|
141
|
+
}
|
|
142
|
+
if (size === "contain") {
|
|
143
|
+
const scale = Math.min(w / imgW, h / imgH);
|
|
144
|
+
return { width: imgW * scale, height: imgH * scale };
|
|
145
|
+
}
|
|
146
|
+
const parts = size.trim().split(/\s+/);
|
|
147
|
+
let rw = imgW;
|
|
148
|
+
let rh = imgH;
|
|
149
|
+
if (parts[0]) {
|
|
150
|
+
if (parts[0].endsWith("%")) {
|
|
151
|
+
rw = w * parseFloat(parts[0]) / 100;
|
|
152
|
+
} else if (parts[0] !== "auto") {
|
|
153
|
+
rw = parseFloat(parts[0]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (parts[1]) {
|
|
157
|
+
if (parts[1].endsWith("%")) {
|
|
158
|
+
rh = h * parseFloat(parts[1]) / 100;
|
|
159
|
+
} else if (parts[1] !== "auto") {
|
|
160
|
+
rh = parseFloat(parts[1]);
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
if (parts[0] !== "auto") {
|
|
164
|
+
rh = imgH * (rw / imgW);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { width: rw, height: rh };
|
|
168
|
+
}
|
|
169
|
+
function parseBgPos(pos, w, h, targetW, targetH) {
|
|
170
|
+
const parts = (pos || "").trim().split(/\s+/);
|
|
171
|
+
if (parts.length === 0 || parts.length === 1 && !parts[0]) {
|
|
172
|
+
return { x: 0, y: 0 };
|
|
173
|
+
}
|
|
174
|
+
const xStr = parts[0];
|
|
175
|
+
let yStr = parts[1];
|
|
176
|
+
if (parts.length === 1) {
|
|
177
|
+
yStr = "center";
|
|
178
|
+
}
|
|
179
|
+
function resolve(val, containerDim, imgDim) {
|
|
180
|
+
if (val === "left" || val === "top") return 0;
|
|
181
|
+
if (val === "right" || val === "bottom") return containerDim - imgDim;
|
|
182
|
+
if (val === "center") return (containerDim - imgDim) / 2;
|
|
183
|
+
if (val.endsWith("%")) {
|
|
184
|
+
return (containerDim - imgDim) * parseFloat(val) / 100;
|
|
185
|
+
}
|
|
186
|
+
if (val.endsWith("px")) {
|
|
187
|
+
return parseFloat(val);
|
|
188
|
+
}
|
|
189
|
+
return parseFloat(val) || 0;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
x: resolve(xStr, w, targetW),
|
|
193
|
+
y: resolve(yStr, h, targetH)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function drawBackgroundImage(ctx, node, x, y, w, h, radius) {
|
|
197
|
+
const img = node.backgroundImageInstance;
|
|
198
|
+
if (!img || !img.complete || img.naturalWidth === 0 || img.naturalHeight === 0) return;
|
|
199
|
+
const props = node.props;
|
|
200
|
+
const bgSize = props.backgroundSize;
|
|
201
|
+
const bgPos = props.backgroundPosition;
|
|
202
|
+
const bgRepeat = resolveBgRepeat(props.backgroundRepeat);
|
|
203
|
+
const imgW = img.naturalWidth;
|
|
204
|
+
const imgH = img.naturalHeight;
|
|
205
|
+
const { width: targetW, height: targetH } = parseBgSize(bgSize, w, h, imgW, imgH);
|
|
206
|
+
const { x: posX, y: posY } = parseBgPos(bgPos, w, h, targetW, targetH);
|
|
207
|
+
ctx.save();
|
|
208
|
+
drawRoundedRect(ctx, x, y, w, h, radius);
|
|
209
|
+
ctx.clip();
|
|
210
|
+
if (bgRepeat === "no-repeat") {
|
|
211
|
+
ctx.drawImage(img, x + posX, y + posY, targetW, targetH);
|
|
212
|
+
} else {
|
|
213
|
+
const pattern = ctx.createPattern(img, bgRepeat);
|
|
214
|
+
if (pattern) {
|
|
215
|
+
const matrix = new DOMMatrix();
|
|
216
|
+
const scaleX = targetW / imgW;
|
|
217
|
+
const scaleY = targetH / imgH;
|
|
218
|
+
matrix.translateSelf(x + posX, y + posY);
|
|
219
|
+
matrix.scaleSelf(scaleX, scaleY);
|
|
220
|
+
pattern.setTransform(matrix);
|
|
221
|
+
ctx.fillStyle = pattern;
|
|
222
|
+
ctx.beginPath();
|
|
223
|
+
ctx.rect(x, y, w, h);
|
|
224
|
+
ctx.fill();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
ctx.restore();
|
|
228
|
+
}
|
|
128
229
|
function drawNode(state, node, offsetX, offsetY) {
|
|
129
230
|
const { ctx } = state;
|
|
130
231
|
const x = offsetX + node.layout.x;
|
|
@@ -159,6 +260,10 @@ function drawNode(state, node, offsetX, offsetY) {
|
|
|
159
260
|
ctx.fill();
|
|
160
261
|
ctx.restore();
|
|
161
262
|
}
|
|
263
|
+
const viewNode = node;
|
|
264
|
+
if (viewNode.backgroundImageInstance) {
|
|
265
|
+
drawBackgroundImage(ctx, viewNode, x, y, w, h, viewRadius);
|
|
266
|
+
}
|
|
162
267
|
if (scrollX || scrollY) {
|
|
163
268
|
viewIsScroll = true;
|
|
164
269
|
ctx.save();
|
|
@@ -639,6 +744,18 @@ var hostConfig = {
|
|
|
639
744
|
if (!img.complete) {
|
|
640
745
|
img.onload = () => rootContainer.invalidate();
|
|
641
746
|
}
|
|
747
|
+
} else if (type === "View" && props.backgroundImage) {
|
|
748
|
+
const viewNode = node;
|
|
749
|
+
const img = new Image();
|
|
750
|
+
img.crossOrigin = "anonymous";
|
|
751
|
+
img.src = props.backgroundImage;
|
|
752
|
+
if (img.dataset) {
|
|
753
|
+
img.dataset.src = props.backgroundImage;
|
|
754
|
+
}
|
|
755
|
+
viewNode.backgroundImageInstance = img;
|
|
756
|
+
if (!img.complete) {
|
|
757
|
+
img.onload = () => rootContainer.invalidate();
|
|
758
|
+
}
|
|
642
759
|
}
|
|
643
760
|
return node;
|
|
644
761
|
},
|
|
@@ -723,6 +840,38 @@ var hostConfig = {
|
|
|
723
840
|
}
|
|
724
841
|
}
|
|
725
842
|
}
|
|
843
|
+
} else if (instance.type === "View") {
|
|
844
|
+
const viewNode = instance;
|
|
845
|
+
const newBg = instance.props.backgroundImage;
|
|
846
|
+
const currentBg = viewNode.backgroundImageInstance?.dataset?.src;
|
|
847
|
+
if (newBg !== currentBg) {
|
|
848
|
+
if (!newBg) {
|
|
849
|
+
viewNode.backgroundImageInstance = null;
|
|
850
|
+
} else {
|
|
851
|
+
const img = new Image();
|
|
852
|
+
img.crossOrigin = "anonymous";
|
|
853
|
+
img.src = newBg;
|
|
854
|
+
if (img.dataset) {
|
|
855
|
+
img.dataset.src = newBg;
|
|
856
|
+
}
|
|
857
|
+
viewNode.backgroundImageInstance = img;
|
|
858
|
+
const invalidate = () => {
|
|
859
|
+
let p = viewNode;
|
|
860
|
+
while (p) {
|
|
861
|
+
if (p.type === "Root") {
|
|
862
|
+
p.container?.invalidate();
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
p = p.parent;
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
if (!img.complete) {
|
|
869
|
+
img.onload = invalidate;
|
|
870
|
+
} else {
|
|
871
|
+
invalidate();
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
726
875
|
}
|
|
727
876
|
},
|
|
728
877
|
commitTextUpdate() {
|