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:
Родитель
2c04da063b
Коммит
eb3e67a257
|
@ -23,7 +23,7 @@ export default class LinearGradient extends Shape {
|
|||
y1={y1}
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
{...extractGradient(props)}
|
||||
{...extractGradient(props, this)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export default class RadialGradient extends Shape {
|
|||
ry={ry || r}
|
||||
cx={cx}
|
||||
cy={cy}
|
||||
{...extractGradient(props)}
|
||||
{...extractGradient(props, this)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,12 @@ export default class Stop extends Component {
|
|||
stopColor: "#000",
|
||||
stopOpacity: 1,
|
||||
};
|
||||
setNativeProps = () => {
|
||||
const { parent } = this.props;
|
||||
if (parent) {
|
||||
parent.forceUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return null;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
[self.svgView defineClipPath:self clipPathName:self.name];
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node parseReference];
|
||||
|
|
|
@ -197,6 +197,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
if (self.name) {
|
||||
typeof(self) __weak weakSelf = self;
|
||||
[self.svgView defineTemplate:weakSelf templateName:self.name];
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
NSArray<RNSVGLength *> *points = @[self.x1, self.y1, self.x2, self.y2];
|
||||
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
|
||||
[painter setUnits:self.gradientUnits];
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
[self.svgView defineMask:self maskName:self.name];
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
NSArray<RNSVGLength *> *points = @[self.x, self.y, self.patternwidth, self.patternheight];
|
||||
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
|
||||
[painter setUnits:self.patternUnits];
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
NSArray<RNSVGLength *> *points = @[self.fx, self.fy, self.rx, self.ry, self.cx, self.cy];
|
||||
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
|
||||
[painter setUnits:self.gradientUnits];
|
||||
|
|
|
@ -531,6 +531,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
|
|||
|
||||
- (void)parseReference
|
||||
{
|
||||
self.dirty = false;
|
||||
if (self.name) {
|
||||
typeof(self) __weak weakSelf = self;
|
||||
[self.svgView defineTemplate:weakSelf templateName:self.name];
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче