mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-01 14:15:03 +00:00
Implement support for animating gradient stops, fixes #884
```jsx
import * as React from 'react';
import { View, StyleSheet, Animated } from 'react-native';
import { Svg, Defs, LinearGradient, Stop, Rect } from 'react-native-svg';
const AnimatedStop = Animated.createAnimatedComponent(Stop);
export default class App extends React.Component {
state = {
anim: new Animated.Value(0),
};
componentDidMount = () => {
Animated.timing(this.state.anim, {
duration: 3000,
toValue: 1,
}).start();
};
render() {
return (
<View style={styles.container}>
<Svg width="100%" height="100%">
<Defs>
<LinearGradient id="grad" x1="0" y1="50" x2="100" y2="50">
<Stop offset="0%" stopColor="#888" stopOpacity="1" />
<AnimatedStop
offset={this.state.anim}
stopColor="#888"
stopOpacity="0.1"
/>
<Stop offset="100%" stopColor="#888" stopOpacity="1" />
</LinearGradient>
</Defs>
<Rect
x="10"
y="20"
rx="16"
ry="16"
width="96"
height="32"
fill="url(#grad)"
/>
</Svg>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ecf0f1',
},
});
```
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Children } from "react";
|
||||
import React, { Children } from "react";
|
||||
import Color from "color";
|
||||
|
||||
import extractOpacity from "./extractOpacity";
|
||||
@@ -11,6 +11,12 @@ function percentToFloat(percent) {
|
||||
if (typeof percent === "number") {
|
||||
return percent;
|
||||
}
|
||||
if (
|
||||
typeof percent === "object" &&
|
||||
typeof percent.__getAnimatedValue === "function"
|
||||
) {
|
||||
return percent.__getAnimatedValue();
|
||||
}
|
||||
const matched = percent.match(percentReg);
|
||||
if (!matched) {
|
||||
console.warn(
|
||||
@@ -24,20 +30,27 @@ function percentToFloat(percent) {
|
||||
|
||||
const offsetComparator = (object, other) => object[0] - other[0];
|
||||
|
||||
export default function extractGradient(props) {
|
||||
export default function extractGradient(props, parent) {
|
||||
const { id, children, gradientTransform, transform, gradientUnits } = props;
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const stops = [];
|
||||
const childArray = Children.toArray(children);
|
||||
const childArray = React.Children.map(children, child =>
|
||||
React.cloneElement(child, {
|
||||
parent,
|
||||
}),
|
||||
);
|
||||
const l = childArray.length;
|
||||
for (let i = 0; i < l; i++) {
|
||||
const { props: { offset, stopColor, stopOpacity } } = childArray[i];
|
||||
const offsetNumber = percentToFloat(offset);
|
||||
if (stopColor && !isNaN(offsetNumber)) {
|
||||
const color = Color(stopColor).alpha(extractOpacity(stopOpacity)).rgb().array();
|
||||
const color = Color(stopColor)
|
||||
.alpha(extractOpacity(stopOpacity))
|
||||
.rgb()
|
||||
.array();
|
||||
const r = color[0] / 255;
|
||||
const g = color[1] / 255;
|
||||
const b = color[2] / 255;
|
||||
@@ -58,8 +71,11 @@ export default function extractGradient(props) {
|
||||
|
||||
return {
|
||||
name: id,
|
||||
children: childArray,
|
||||
gradient: colors.concat(offsets),
|
||||
gradientUnits: units[gradientUnits] || 0,
|
||||
gradientTransform: extractTransform(gradientTransform || transform || props),
|
||||
gradientTransform: extractTransform(
|
||||
gradientTransform || transform || props,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user