Skip to content

Commit c154ebe

Browse files
李志豪zhiqingchen
李志豪
authored andcommitted
fix: v2 image bugfix
1 parent ce3b461 commit c154ebe

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

src/skia/graphic.tsx

+17-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import SkiaPathRebuilder from './SkiaPathRebuilder';
2424
import { ReactElement } from 'react';
2525
import mapStyleToAttrs from 'zrender/lib/svg/mapStyleToAttrs';
2626
import {
27+
Skia,
2728
Path as SkiaPath,
2829
Text as SkiaText,
2930
matchFont,
@@ -313,17 +314,32 @@ export function brushSVGImage(
313314
y={y}
314315
width={dw}
315316
height={dh}
317+
{...attrs}
316318
>
317319
{effects}
318320
</SkiaImage>
319321
);
320322
}
321323
type CustomImageProps = SkiaProps<ImageProps> & {
322324
href: string;
325+
height?: number;
326+
width?: number;
323327
children?: ReactElement[];
324328
};
325329
function SkiaImage({ href, children, ...attrs }: CustomImageProps) {
326-
const skiaImage = useImage(href);
330+
let skiaImage = useImage(href);
331+
// Base64 image
332+
if (href.indexOf(';base64') > -1) {
333+
const base64Data = href.split(',')[1] || '';
334+
const binaryData = Skia.Data.fromBase64(base64Data);
335+
skiaImage = Skia.Image.MakeImageFromEncoded(binaryData);
336+
}
337+
const imageInfo = skiaImage?.getImageInfo();
338+
if (imageInfo && !attrs.width) {
339+
const { height: oriHeight, width: oriWidth } = imageInfo;
340+
attrs.width = attrs.height ? (attrs.height / oriHeight) * oriWidth : 0;
341+
}
342+
// attrs.fit = 'fill'; // Here you can set 'Image' fit mode
327343
return (
328344
<Image {...attrs} image={skiaImage}>
329345
{children}

src/svg/svgChart.tsx

+38-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import React, {
3333
useCallback,
3434
} from 'react';
3535

36-
import { Platform, View } from 'react-native';
36+
import { Platform, View, Image as RNImage } from 'react-native';
3737

3838
import {
3939
setPlatformAPI,
@@ -80,6 +80,32 @@ const tagMap = {
8080
mask: Mask,
8181
};
8282

83+
const imageSizeMap: any = {};
84+
85+
interface ImageSize {
86+
width: number;
87+
height: number;
88+
}
89+
90+
// 使用 async/await 获取图片尺寸
91+
const getImageSize = async (uri: string): Promise<ImageSize> => {
92+
return new Promise((resolve, reject) => {
93+
RNImage.getSize(
94+
uri,
95+
(width, height) => resolve({ width, height }),
96+
(error) => reject(error)
97+
);
98+
});
99+
};
100+
101+
async function imageInit(url: string) {
102+
const { width, height } = await getImageSize(url);
103+
imageSizeMap[url] = {
104+
width,
105+
height,
106+
};
107+
}
108+
83109
function toCamelCase(str: string) {
84110
var reg = /-(\w)/g;
85111
return str.replace(reg, function (_: any, $1: string) {
@@ -170,6 +196,17 @@ function SvgEle(props: SVGVEleProps) {
170196
</Tag>
171197
);
172198
}
199+
if (tag === 'image' && !attrs.width) {
200+
if (imageSizeMap[attrs.href]) {
201+
const { width, height } = imageSizeMap[attrs.href];
202+
attrs.width = (attrs.height / height) * width;
203+
if (attrs.height === 0) {
204+
attrs.opacity = 0;
205+
}
206+
} else {
207+
imageInit(attrs.href);
208+
}
209+
}
173210
return (
174211
<Tag key={node.key} {...attrs}>
175212
{children?.map((child) => <SvgEle key={child.key} node={child} />)}

0 commit comments

Comments
 (0)