跳到主要内容

SVG 图像

绘制 SVG (参见 SVG 支持)。

如果根尺寸是绝对单位,则 width/height 属性不起作用,因为初始视口是固定的。

名称类型描述
svgSVGSVG 图像。
width?number目标图像的宽度。当根 SVG 宽度以相对单位指定时,用于解析初始视口。
height?number目标图像的高度。当根 SVG 高度以相对单位指定时,用于解析初始视口。
x?numbersvg 容器的可选显示 x 坐标。
y?numbersvg 容器的可选显示 y 坐标。
信息

ImageSVG 组件不遵循与其他组件相同的绘制规则。 请参阅应用效果

示例

tsx
import {
Canvas,
ImageSVG,
useSVG
} from "@shopify/react-native-skia";
 
const ImageSVGDemo = () => {
// Alternatively, you can pass an SVG URL directly
// for instance: const svg = useSVG("https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg");
const svg = useSVG(require("../../assets/tiger.svg"));
return (
<Canvas style={{ flex: 1 }}>
{ svg && (
<ImageSVG
svg={svg}
width={256}
height={256}
/>)
}
</Canvas>
);
};
tsx
import {
Canvas,
ImageSVG,
useSVG
} from "@shopify/react-native-skia";
 
const ImageSVGDemo = () => {
// Alternatively, you can pass an SVG URL directly
// for instance: const svg = useSVG("https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg");
const svg = useSVG(require("../../assets/tiger.svg"));
return (
<Canvas style={{ flex: 1 }}>
{ svg && (
<ImageSVG
svg={svg}
width={256}
height={256}
/>)
}
</Canvas>
);
};

您还可以使用内联字符串作为 SVG (使用 Skia.SVG.MakeFromString)

tsx
import React from "react";
import { Canvas, ImageSVG, Skia } from "@shopify/react-native-skia";
 
const svg = Skia.SVG.MakeFromString(
`<svg viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'>
<circle cx='31' cy='325' r='120px' fill='#c02aaa'/>
</svg>`
)!;
 
export const SVG = () => {
return (
<Canvas style={{ flex: 1 }}>
<ImageSVG
svg={svg}
x={0}
y={0}
width={290}
height={500}
/>
</Canvas>
);
};
tsx
import React from "react";
import { Canvas, ImageSVG, Skia } from "@shopify/react-native-skia";
 
const svg = Skia.SVG.MakeFromString(
`<svg viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'>
<circle cx='31' cy='325' r='120px' fill='#c02aaa'/>
</svg>`
)!;
 
export const SVG = () => {
return (
<Canvas style={{ flex: 1 }}>
<ImageSVG
svg={svg}
x={0}
y={0}
width={290}
height={500}
/>
</Canvas>
);
};

缩放 SVG

如上所述,如果根尺寸是绝对单位,则 width/height 属性不起作用,因为初始视口是固定的。但是您可以访问这些值并使用 fitbox 函数。

示例

在下面的示例中,我们将 SVG 缩放到画布的宽度和高度。

tsx
import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, Group } from "@shopify/react-native-skia";
 
const svg = Skia.SVG.MakeFromString(
`<svg viewBox='0 0 20 20' width="20" height="20" xmlns='http://www.w3.org/2000/svg'>
<circle cx='10' cy='10' r='10' fill='#00ffff'/>
</svg>`
)!;
 
const width = 256;
const height = 256;
const src = rect(0, 0, svg.width(), svg.height());
const dst = rect(0, 0, width, height);
 
export const SVG = () => {
return (
<Canvas style={{ flex: 1 }}>
<Group transform={fitbox("contain", src, dst)}>
<ImageSVG svg={svg} x={0} y={0} width={20} height={20} />
</Group>
</Canvas>
);
};
tsx
import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, Group } from "@shopify/react-native-skia";
 
const svg = Skia.SVG.MakeFromString(
`<svg viewBox='0 0 20 20' width="20" height="20" xmlns='http://www.w3.org/2000/svg'>
<circle cx='10' cy='10' r='10' fill='#00ffff'/>
</svg>`
)!;
 
const width = 256;
const height = 256;
const src = rect(0, 0, svg.width(), svg.height());
const dst = rect(0, 0, width, height);
 
export const SVG = () => {
return (
<Canvas style={{ flex: 1 }}>
<Group transform={fitbox("contain", src, dst)}>
<ImageSVG svg={svg} x={0} y={0} width={20} height={20} />
</Group>
</Canvas>
);
};

应用效果

ImageSVG 组件不遵循与其他组件相同的绘制规则。这是因为在后台,我们使用 Skia 中的 SVG 模块。但是您可以使用 layer 属性来应用效果。

不透明度示例

在下面的示例中,我们通过 ColorMatrix 组件应用不透明度效果。

tsx
import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, useSVG, Group, Paint, OpacityMatrix, ColorMatrix } from "@shopify/react-native-skia";
 
const width = 256;
const height = 256;
 
export const SVG = () => {
const tiger = useSVG(require("./tiger.svg"));
if (!tiger) {
return null;
}
const src = rect(0, 0, tiger.width(), tiger.height());
const dst = rect(0, 0, width, height);
return (
<Canvas style={{ flex: 1 }}>
<Group
transform={fitbox("contain", src, dst)}
layer={<Paint><ColorMatrix matrix={OpacityMatrix(0.5)} /></Paint>}
>
<ImageSVG svg={tiger} x={0} y={0} width={800} height={800} />
</Group>
</Canvas>
);
};
tsx
import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, useSVG, Group, Paint, OpacityMatrix, ColorMatrix } from "@shopify/react-native-skia";
 
const width = 256;
const height = 256;
 
export const SVG = () => {
const tiger = useSVG(require("./tiger.svg"));
if (!tiger) {
return null;
}
const src = rect(0, 0, tiger.width(), tiger.height());
const dst = rect(0, 0, width, height);
return (
<Canvas style={{ flex: 1 }}>
<Group
transform={fitbox("contain", src, dst)}
layer={<Paint><ColorMatrix matrix={OpacityMatrix(0.5)} /></Paint>}
>
<ImageSVG svg={tiger} x={0} y={0} width={800} height={800} />
</Group>
</Canvas>
);
};

模糊示例

在下面的示例中,我们将模糊图像滤镜应用于 SVG。

tsx
import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, useSVG, Group, Paint, Blur } from "@shopify/react-native-skia";
 
const width = 256;
const height = 256;
 
export const SVG = () => {
const tiger = useSVG(require("./tiger.svg"));
if (!tiger) {
return null;
}
const src = rect(0, 0, tiger.width(), tiger.height());
const dst = rect(0, 0, width, height);
return (
<Canvas style={{ flex: 1 }}>
<Group transform={fitbox("contain", src, dst)} layer={<Paint><Blur blur={10} /></Paint>}>
<ImageSVG svg={tiger} x={0} y={0} width={800} height={800} />
</Group>
</Canvas>
);
};
tsx
import React from "react";
import { Canvas, ImageSVG, Skia, rect, fitbox, useSVG, Group, Paint, Blur } from "@shopify/react-native-skia";
 
const width = 256;
const height = 256;
 
export const SVG = () => {
const tiger = useSVG(require("./tiger.svg"));
if (!tiger) {
return null;
}
const src = rect(0, 0, tiger.width(), tiger.height());
const dst = rect(0, 0, width, height);
return (
<Canvas style={{ flex: 1 }}>
<Group transform={fitbox("contain", src, dst)} layer={<Paint><Blur blur={10} /></Paint>}>
<ImageSVG svg={tiger} x={0} y={0} width={800} height={800} />
</Group>
</Canvas>
);
};

结果

SVG 支持

来自 Skia 的 SVG 模块将 SVG 显示为图像。我们期望大多数 SVG 文件都能开箱即用地正确渲染,特别是如果它们来自 Figma 或 Illustrator。但是,请在使用时注意以下一些怪癖。文本元素当前不会渲染,任何外部 XML 元素(如 XLink 或 CSS)也不会渲染。如果您的 SVG 渲染不正确,并且您已考虑以下所有项目,请提交一个问题

文本

目前不支持文本渲染

CSS 样式

不支持 SVG 中包含的 CSS 样式。 如果可能,像 SVGO 这样的工具可以帮助将 CSS 样式属性转换为 SVG 属性。 您可以在 这里 在线使用它。 例如,它可以将包含转换的 CSS 样式属性规范化为正确的 transform 属性。

RGBA 颜色

不支持 RGBA 颜色语法。 相反,您应该使用 fill-opacitystroke-opacity 属性。 请考虑以下示例。

xml
<circle
r="10"
cx="10"
cy="10"
fill="rgba(100, 200, 300, 0.5)"
stroke="rgba(100, 200, 300, 0.8)"
/>
xml
<circle
r="10"
cx="10"
cy="10"
fill="rgba(100, 200, 300, 0.5)"
stroke="rgba(100, 200, 300, 0.8)"
/>

需要重写为

xml
<circle
r="10"
cx="10"
cy="10"
fill="rgb(100, 200, 300)"
fill-opacity="0.5"
stroke="rgb(100, 200, 300)"
stroke-opacity="0.8"
/>
xml
<circle
r="10"
cx="10"
cy="10"
fill="rgb(100, 200, 300)"
fill-opacity="0.5"
stroke="rgb(100, 200, 300)"
stroke-opacity="0.8"
/>

opacity 属性也适用于 fillstroke 属性。

不支持的元素

以下是不支持的元素的列表。 通常,可以重写这些 SVG 以不使用这些元素。

  • <altGlyph> (已弃用)
  • <animate>
  • <cursor> (已弃用)
  • <feComponentTransfer>
  • <feConvolveMatrix>
  • <feTile>
  • <feDropShadow>
  • <font> (已弃用)
  • <foreignObject>
  • <glyph> (已弃用)
  • <script>
  • <view>

字体系列

当使用 Skia 渲染 SVG 时,您的应用程序中可用的所有字体也可用于您的 SVG。 但是,您设置 font-family 属性的方式与在 Web 上一样灵活。

jsx
// ✅ This is really all that is supported:
<text font-family="MyFont" />
// ❌ This won't work. If MyFont is available, this syntax will be accepted.
// but it will never fallback to monospace
<text font-family="MyFont, monospace" />
// ❌ The single quote syntax won't work either.
<text font-family="'MyFont'" />
jsx
// ✅ This is really all that is supported:
<text font-family="MyFont" />
// ❌ This won't work. If MyFont is available, this syntax will be accepted.
// but it will never fallback to monospace
<text font-family="MyFont, monospace" />
// ❌ The single quote syntax won't work either.
<text font-family="'MyFont'" />

内联 SVG

某些 SVG 通过 <image><feImage> 元素包含内联 SVG。 这不受支持。

渐变模板

在渐变中不支持已弃用的 xlink:href 属性。 您可以使用 href 属性代替。 但是,我们发现它似乎没有得到充分的支持。 我们建议避免使用它。

回退

一些有问题的 SVG 在浏览器中可以很好地显示,因为它们对错误非常容忍。 我们发现 Skia SVG 模块的容错性要差得多。