exodeui-react-native 1.0.10 → 1.1.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/engine.ts +60 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exodeui-react-native",
3
- "version": "1.0.10",
3
+ "version": "1.1.0",
4
4
  "description": "React Native runtime for ExodeUI animations",
5
5
  "main": "index.js",
6
6
  "files": [
package/src/engine.ts CHANGED
@@ -1670,12 +1670,47 @@ export class ExodeUIEngine {
1670
1670
  canvas.drawText(text, x, y, paint, font);
1671
1671
  }
1672
1672
 
1673
+ private getOrDecodeImage(src: string): any {
1674
+ if (!src) return null;
1675
+ if (this.imageCache.has(src)) return this.imageCache.get(src)!;
1676
+
1677
+ if (src.startsWith('data:image')) {
1678
+ try {
1679
+ const base64Str = src.includes(',') ? src.split(',')[1] : src;
1680
+ const data = Skia.Data.fromBase64(base64Str);
1681
+ const img = Skia.Image.MakeImageFromEncoded(data);
1682
+ if (img) {
1683
+ this.imageCache.set(src, img);
1684
+ return img;
1685
+ }
1686
+ } catch (e) {
1687
+ console.error('[ExodeUIEngine] Failed to decode base64 image:', e);
1688
+ }
1689
+ }
1690
+ return null;
1691
+ }
1692
+
1673
1693
  private renderImage(canvas: any, obj: any, w: number, h: number) {
1674
- // Image support requires Skia.Image.MakeFromExternalSource or similar
1675
- // Placeholder for now
1676
- const paint = Skia.Paint();
1677
- paint.setColor(Skia.Color('#374151'));
1678
- canvas.drawRect({ x: -w/2, y: -h/2, width: w, height: h }, paint);
1694
+ const state = this.objectStates.get(obj.id);
1695
+ const geom = state?.geometry || obj.geometry;
1696
+ const src = obj.src || geom.src || '';
1697
+
1698
+ const img = this.getOrDecodeImage(src);
1699
+ if (img) {
1700
+ const paint = Skia.Paint();
1701
+ paint.setAlphaf(state?.opacity ?? 1);
1702
+ canvas.drawImageRect(
1703
+ img,
1704
+ { x: 0, y: 0, width: img.width(), height: img.height() },
1705
+ { x: -w/2, y: -h/2, width: w, height: h },
1706
+ paint
1707
+ );
1708
+ } else {
1709
+ // Fallback placeholder
1710
+ const paint = Skia.Paint();
1711
+ paint.setColor(Skia.Color('#374151'));
1712
+ canvas.drawRect({ x: -w/2, y: -h/2, width: w, height: h }, paint);
1713
+ }
1679
1714
  }
1680
1715
 
1681
1716
  private renderButton(canvas: any, obj: any, w: number, h: number) {
@@ -2248,8 +2283,26 @@ export class ExodeUIEngine {
2248
2283
 
2249
2284
  if (style.fill) {
2250
2285
  const paint = Skia.Paint();
2251
- paint.setColor(Skia.Color(style.fill.color || '#000000'));
2252
- paint.setAlphaf((state.opacity ?? 1) * (style.fill.opacity ?? 1));
2286
+
2287
+ let hasImageFill = false;
2288
+ if ((style.fill.type === 'Image' || style.fill.type === 'Pattern' || style.fill.url) && style.fill.url) {
2289
+ const img = this.getOrDecodeImage(style.fill.url);
2290
+ if (img) {
2291
+ const matrix = Skia.Matrix();
2292
+ matrix.translate(-w/2, -h/2);
2293
+ matrix.scale(w / img.width(), h / img.height());
2294
+ paint.setShader(img.makeShaderOptions(0, 0, 0, 0, matrix));
2295
+ hasImageFill = true;
2296
+ }
2297
+ }
2298
+
2299
+ if (!hasImageFill) {
2300
+ const fillCol = style.fill.color;
2301
+ const fillColStr = typeof fillCol === 'string' ? fillCol.replace(/\s+/g, '') : '#000000';
2302
+ try { paint.setColor(Skia.Color(fillColStr)); } catch { paint.setColor(Skia.Color('#000000')); }
2303
+ }
2304
+
2305
+ paint.setAlphaf(Math.max(0, Math.min(1, (state.opacity ?? 1) * (style.fill.opacity ?? 1))));
2253
2306
  paint.setStyle(PaintStyle.Fill);
2254
2307
 
2255
2308
  if (style.shadow && style.shadow.opacity > 0) {