每天推薦一個 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