每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文,欢迎关注开源日报。交流QQ群:202790710;微博:https://weibo.com/openingsource;电报群 https://t.me/OpeningSourceOrg


今日推荐开源项目:《JScalibur WarriorJS》GitHub链接

推荐理由:事先说明,这个当然不是真的圣剑什么的。这个项目是一个游戏,你要给你的战士……用JavaScript写出一个冒险指南,然后让你的战士一路爬塔过关。虽然这是个游戏,但是可以训练你的JavaScript基础能力,推荐准备学习JavaScript的朋友来试试。

今日推荐英文原文:《Animated Graph in React Native》作者:Jiří Otáhal

原文链接:https://medium.com/react-native-motion/animated-graph-in-react-native-51354af2bdb0

推荐理由:一个动画可能不算太难,但是动画+图表呢?这篇文章就告诉你如何做出一个带有动画特效的图表

Animated Graph in React Native

Recently I was looking for a React Native graph library for my Pineapplee.io app. During the research, I realized it’s not easy to deal with graphs in React Native. And if you want to animate them? It looks almost impossible. The following gif is what I have done and will talk about in this “tutorial”!

Goal of this article

Without ART library

When I was doing my research about charts in React Native, I found out that almost everyone uses the ART library. Which is really cool and powerful drawing library. Look at this pie chart that has been done by ART library for the Pineapplee.io app.

ART library Pie Chart in pineapplee.io

But when you want to animate it? Well, you can. It is possible. But the animation is done by JS thread. I am always trying to find a way how to move everything to a native part, so our JS thread is not blocked by animation and can work on something else.

The column chart I am going to talk about (and you can see in the gif below) has been done by pure React Native. No ART library!

Let’s make it a bit complicated

I realized that I also need a negative value in the graph. Users of Pineapplee.io usually create a group for a trip and track their spendings. Obviously, there are only negative values — only spendings. The following gif shows how the animation looks like for both negative and positive values.

Layout

I decided to make every single column separately as a component. So I could add a “delay” effect. You can see that the animation starts randomly for every single column when the graph is changing a position of baseline. Let’s work with the 200 height. Value’s height could be 25 and label’s height 25 as well. That makes 150 for column.

Layout for a single column

If the graph’s height is 150 then the column’s height is 300. Every column has a positive part (A) and a negative part (B). Opposite side of these parts is always hidden. The A is hidden for the negative part and the B is hidden for the positive part. It means that if we move the positive part (A) underneath of baseline to the B space, the positive column will be completely hidden. That’s what we want when the value is negative.

Positive parts of columns (left side) and negative parts of the same columns (right parts)

You can see the negative value for the last column on the picture. The value is -5. Positive column is completely moved underneath of baseline (it’s hidden) and negative column is moved to proper Y position to represent -5 value. A maximum value for this graph is 10 (first column). It means that the -5 will be in the middle of a negative part (75 / 2).

We need to do a bit of math here because we need to interpolate actual value to Y position. But I am not going to talk about this here. I believe that you can figure everything out pretty easily.

Animated Column

I used my open source library called react-native-motion and component TranslateY. Which makes animations really easy to implement. Look at the code. Easy to understand. We use TranslateY component in the same way as we would use View component. The only thing we need to do is compute Y positions for positive column, negative column, baseline, and a value label.

 <View style={styles.container}>
          <TranslateY
            style={[styles.graphContainer]}
            value={graphLayerY}
            delay={delay}
          >
            // Positive column
            <TranslateY
              style={styles.positiveColumn}
              value={positiveY}
              delay={delay}
            />
            // Baseline
            // ...
            //
            // Negative column
            <TranslateY
              style={styles.negativeColumn}
              value={negativeY}
              delay={delay}
            />
          </TranslateY>
          <TranslateY
            style={styles.valueLayer}
            value={valueLayerY}
            delay={delay + valueDelay}
          >
            {this.renderValue()}
          </TranslateY>
</View>

Check the result in a real application. Pineapplee.io already implemented the column chart. As I said before, everything is done by UI thread (it’s pretty fast). There is an onPress event so you can change the months. When you select the category it will change the values of a graph and recomputes Y positions. Then the react-native-motion takes care of animation.

Animated Number

The number animation is a bit problem. Because we can’t move it to UI thread. It has to be done by JS thread. I’ve seen that developers usually have the effect done by setInterval. Of course, you can use it, but I wanted to do it safer.

So I use React Native’s Animated API even for the number animation. We can add a listener to animated value and when the value is changed we just re-render the number. It’s easy and you can take advantage of the Animated API. By using an Easing for example. And what’s the best? I put the component to the react-native-motion library which is open-sourced for you guys ?

You just have to write a couple of lines like this. Once the value is changed in your code it will take care of the rest.

Available in react-native-motion

Did you like it? Clap, Follow and Animate it! ?

Actually you don’t have to do anything of that. But it will help me a lot. It’s a big motivation for next articles like this.

About me ?

I am an author of Pineapplee.io (which I also use as a playground for my animations ?‍). And author of react-native-material-ui and react-native-motion libraries. Writing about them in this blog.


每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文,欢迎关注开源日报。交流QQ群:202790710;微博:https://weibo.com/openingsource;电报群 https://t.me/OpeningSourceOrg