组
Group 组件是 React Native Skia 中的一个基本构造。Group 组件可以彼此深度嵌套。它可以对其子组件应用以下操作
名称 | 类型 | 描述 |
---|---|---|
transform? | Transform2d | 与 React Native 中的 API 相同,但有两个区别:变换的默认原点位于左上角(React Native 视图使用中心),并且所有旋转都以弧度为单位。 |
origin? | Point | 设置变换的原点。此属性不会被其子元素继承。 |
clip? | RectOrRRectOrPath | 用于裁剪子元素的矩形、圆角矩形或路径。 |
invertClip? | boolean | 反转裁剪区域:裁剪区域外的部分将显示,而内部的部分将隐藏。 |
layer? | RefObject<Paint> | 将子元素绘制为位图,并应用由 paint 提供的效果。 |
以下三个组件不受组属性的影响。要对这些组件应用绘制效果,您需要使用 图层效果。在每个组件参考中,我们还会记录如何在其上应用绘制效果。
绘制属性
其子元素将继承应用于组的所有绘制属性。这些属性可以是像 color
或 style
这样的属性,也可以是像 <Shader />
或 <ImageFilter />
这样的子元素(请参阅绘制)。
tsx
import {Canvas ,Circle ,Group } from "@shopify/react-native-skia";export constPaintDemo = () => {constr = 128;return (<Canvas style ={{flex : 1 }}><Circle cx ={r }cy ={r }r ={r }color ="#51AFED" />{/* The paint is inherited by the following sibling and descendants. */}<Group color ="lightblue"style ="stroke"strokeWidth ={10}><Circle cx ={r }cy ={r }r ={r / 2} /><Circle cx ={r }cy ={r }r ={r / 3}color ="white" /></Group ></Canvas >);};
tsx
import {Canvas ,Circle ,Group } from "@shopify/react-native-skia";export constPaintDemo = () => {constr = 128;return (<Canvas style ={{flex : 1 }}><Circle cx ={r }cy ={r }r ={r }color ="#51AFED" />{/* The paint is inherited by the following sibling and descendants. */}<Group color ="lightblue"style ="stroke"strokeWidth ={10}><Circle cx ={r }cy ={r }r ={r / 2} /><Circle cx ={r }cy ={r }r ={r / 3}color ="white" /></Group ></Canvas >);};
变换
transform
属性与其在 React Native 中的同名属性 相同,但有一个显著的区别:在 React Native 中,变换的原点是对象的中心,而在 Skia 中,它是对象的左上角位置。
origin
属性是用于设置变换原点的辅助工具。此属性不会被其子元素继承。所有旋转都以弧度为单位。
简单变换
tsx
import {Canvas ,Fill ,Group ,RoundedRect } from "@shopify/react-native-skia";constSimpleTransform = () => {return (<Canvas style ={{flex : 1 }}><Fill color ="#e8f4f8" /><Group color ="lightblue"transform ={[{skewX :Math .PI / 6 }]}><RoundedRect x ={64}y ={64}width ={128}height ={128}r ={10} /></Group ></Canvas >);};
tsx
import {Canvas ,Fill ,Group ,RoundedRect } from "@shopify/react-native-skia";constSimpleTransform = () => {return (<Canvas style ={{flex : 1 }}><Fill color ="#e8f4f8" /><Group color ="lightblue"transform ={[{skewX :Math .PI / 6 }]}><RoundedRect x ={64}y ={64}width ={128}height ={128}r ={10} /></Group ></Canvas >);};
原点变换
tsx
import {Canvas ,Fill ,Group ,RoundedRect } from "@shopify/react-native-skia";constSimpleTransform = () => {return (<Canvas style ={{flex : 1 }}><Fill color ="#e8f4f8" /><Group color ="lightblue"origin ={{x : 128,y : 128 }}transform ={[{skewX :Math .PI / 6 }]}><RoundedRect x ={64}y ={64}width ={128}height ={128}r ={10} /></Group ></Canvas >);};
tsx
import {Canvas ,Fill ,Group ,RoundedRect } from "@shopify/react-native-skia";constSimpleTransform = () => {return (<Canvas style ={{flex : 1 }}><Fill color ="#e8f4f8" /><Group color ="lightblue"origin ={{x : 128,y : 128 }}transform ={[{skewX :Math .PI / 6 }]}><RoundedRect x ={64}y ={64}width ={128}height ={128}r ={10} /></Group ></Canvas >);};
裁剪操作
clip
提供一个裁剪区域,用于设置应该显示子元素的哪一部分。区域内的部分会显示,而区域外的部分会隐藏。当使用 invertClip
时,裁剪区域外的所有内容都会显示,而裁剪区域内的部分会隐藏。
裁剪矩形
tsx
import {Canvas ,Group ,Image ,useImage ,rect ,Fill ,} from "@shopify/react-native-skia";constsize = 256;constpadding = 32;constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));constrct =rect (padding ,padding ,size -padding * 2,size -padding * 2);return (<Canvas style ={{flex : 1 }}><Fill color ="lightblue" /><Group clip ={rct }><Image image ={image }x ={0}y ={0}width ={size }height ={size }fit ="cover"/></Group ></Canvas >);};
tsx
import {Canvas ,Group ,Image ,useImage ,rect ,Fill ,} from "@shopify/react-native-skia";constsize = 256;constpadding = 32;constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));constrct =rect (padding ,padding ,size -padding * 2,size -padding * 2);return (<Canvas style ={{flex : 1 }}><Fill color ="lightblue" /><Group clip ={rct }><Image image ={image }x ={0}y ={0}width ={size }height ={size }fit ="cover"/></Group ></Canvas >);};

裁剪圆角矩形
tsx
import {Canvas ,Group ,Image ,useImage ,rrect ,rect ,} from "@shopify/react-native-skia";constsize = 256;constpadding = 32;constr = 8;constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));constroundedRect =rrect (rect (padding ,padding ,size -padding * 2,size -padding * 2),r ,r );return (<Canvas style ={{flex : 1 }}><Group clip ={roundedRect }><Image image ={image }x ={0}y ={0}width ={size }height ={size }fit ="cover"/></Group ></Canvas >);};
tsx
import {Canvas ,Group ,Image ,useImage ,rrect ,rect ,} from "@shopify/react-native-skia";constsize = 256;constpadding = 32;constr = 8;constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));constroundedRect =rrect (rect (padding ,padding ,size -padding * 2,size -padding * 2),r ,r );return (<Canvas style ={{flex : 1 }}><Group clip ={roundedRect }><Image image ={image }x ={0}y ={0}width ={size }height ={size }fit ="cover"/></Group ></Canvas >);};

裁剪路径
tsx
import {Canvas ,Group ,Image ,useImage ,Skia ,} from "@shopify/react-native-skia";constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));conststar =Skia .Path .MakeFromSVGString ("M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 L 128 0 Z")!;return (<Canvas style ={{flex : 1 }}><Group clip ={star }><Image image ={image }x ={0}y ={0}width ={256}height ={256}fit ="cover" /></Group ></Canvas >);};
tsx
import {Canvas ,Group ,Image ,useImage ,Skia ,} from "@shopify/react-native-skia";constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));conststar =Skia .Path .MakeFromSVGString ("M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 L 128 0 Z")!;return (<Canvas style ={{flex : 1 }}><Group clip ={star }><Image image ={image }x ={0}y ={0}width ={256}height ={256}fit ="cover" /></Group ></Canvas >);};

反转裁剪
tsx
import {Canvas ,Group ,Image ,useImage ,Skia ,} from "@shopify/react-native-skia";constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));conststar =Skia .Path .MakeFromSVGString ("M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 L 128 0 Z")!;return (<Canvas style ={{flex : 1 }}><Group clip ={star }invertClip ><Image image ={image }x ={0}y ={0}width ={256}height ={256}fit ="cover" /></Group ></Canvas >);};
tsx
import {Canvas ,Group ,Image ,useImage ,Skia ,} from "@shopify/react-native-skia";constClip = () => {constimage =useImage (require ("./assets/oslo.jpg"));conststar =Skia .Path .MakeFromSVGString ("M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 L 128 0 Z")!;return (<Canvas style ={{flex : 1 }}><Group clip ={star }invertClip ><Image image ={image }x ={0}y ={0}width ={256}height ={256}fit ="cover" /></Group ></Canvas >);};

图层效果
使用 layer
属性将创建一个子元素的位图绘制。您可以使用它来应用效果。这对于构建需要应用于一组元素而不是特定一个元素的效果特别有用。
tsx
import {Canvas ,Group ,Circle ,Blur ,Paint ,ColorMatrix ,} from "@shopify/react-native-skia";constClip = () => {return (<Canvas style ={{flex : 1 }}><Group color ="lightblue"layer ={<Paint ><Blur blur ={20} /><ColorMatrix matrix ={[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,]}/></Paint >}><Circle cx ={0}cy ={128}r ={128 * 0.95} /><Circle cx ={256}cy ={128}r ={128 * 0.95} /></Group ></Canvas >);};
tsx
import {Canvas ,Group ,Circle ,Blur ,Paint ,ColorMatrix ,} from "@shopify/react-native-skia";constClip = () => {return (<Canvas style ={{flex : 1 }}><Group color ="lightblue"layer ={<Paint ><Blur blur ={20} /><ColorMatrix matrix ={[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, -7,]}/></Paint >}><Circle cx ={0}cy ={128}r ={128 * 0.95} /><Circle cx ={256}cy ={128}r ={128 * 0.95} /></Group ></Canvas >);};

Fitbox
FitBox
组件基于 Group
组件,允许您自动缩放绘图以适应目标矩形。
名称 | 类型 | 描述 |
---|---|---|
src | SKRect | 缩放前绘图的边界矩形 |
dst | SKRect | 缩放后绘图的边界矩形 |
fit? | Fit | 使图像适应矩形的方法。值可以是 contain 、fill 、cover 、fitHeight 、fitWidth 、scaleDown 、none (默认值为 contain ) |
示例
考虑以下 SVG 导出。其边界源矩形为 0, 0, 664, 308
xml
<svg width="664" height="308" viewBox="0 0 664 308" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M 170.1 215.5 C 165 222.3..." fill="black"/></svg>
xml
<svg width="664" height="308" viewBox="0 0 664 308" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M 170.1 215.5 C 165 222.3..." fill="black"/></svg>
我们希望将该路径自动缩放到大小为 256 x 256
的画布上
tsx
import {Canvas ,FitBox ,Path ,rect } from "@shopify/react-native-skia";constHello = () => {return (<Canvas style ={{width : 256,height : 256 }}><FitBox src ={rect (0, 0, 664, 308)}dst ={rect (0, 0, 256, 256)}><Path path ="M 170.1 215.5 C 165 222.3..."strokeCap ="round"strokeJoin ="round"style ="stroke"strokeWidth ={30}/></FitBox ></Canvas >);};
tsx
import {Canvas ,FitBox ,Path ,rect } from "@shopify/react-native-skia";constHello = () => {return (<Canvas style ={{width : 256,height : 256 }}><FitBox src ={rect (0, 0, 664, 308)}dst ={rect (0, 0, 256, 256)}><Path path ="M 170.1 215.5 C 165 222.3..."strokeCap ="round"strokeJoin ="round"style ="stroke"strokeWidth ={30}/></FitBox ></Canvas >);};
