1. 程式人生 > >react-native-Art動畫基礎

react-native-Art動畫基礎

一:基礎:
ART:暴露了七個元件:
● Surface - 一個矩形可渲染的區域,是其他元素的容器!
● Group - 可容納多個形狀、文字和其他的分組
● Shape - 形狀定義,可填充
● Text - 文字形狀定義
props
● Surface
○ width : 渲染區域的寬
○ height : 定義渲染區域的高
● Shape
○ d : 定義繪製路徑
○ stroke : 描邊顏色
○ strokeWidth : 描邊寬度
○ strokeDash : 定義虛線
○ fill : 填充顏色
● Text
○ funt : 字型樣式,定義字型、大小、是否加粗 如: bold 35px Heiti SC
● Path
○ moveTo(x,y) : 移動到座標(x,y)
○ lineTo(x,y) : 連線到(x,y)
○ arc() : 繪製弧線
○ close() : 封閉空間

二:例項
● 繪製直線:

import  React,{Component} from 'react';
import  {
 ART,
 View,
 StyleSheet,
} from 'react-native';

var {
  Surface,
  Group,
  Shape,
  Path
} = ART;

export default class  Note extends Component{
    render(){
         const path = Path()
            .moveTo(1,1)//移動起始點
            .lineTo(300
,1);//繪製結束後的座標點 return( <View style={styles.container}> <Surface width={300} height={2}> <Shape d={path} stroke="#000000" strokeWidth={1} /> </Surface> </View> ) } } var styles = StyleSheet.create({ container: { paddingTop: 20
, } });
  注意Surface的寬高,就是檢視能繪製的寬高

● 繪製虛線:

export default class  Note extends Component{
    render(){
         const path = Path()
            .moveTo(1,1)//移動起始點
            .lineTo(300,1);//繪製結束後的座標點
        return(
           <View style={styles.container}>
                <Surface width={300} height={2}>
                    <Shape d={path} stroke="#000000" strokeWidth={2} strokeDash={[10,50]}/>
                </Surface>
            </View>
        )
    }

}
注意:strokeDash={[10,50]}表示:先繪製10畫素的實線然後繪製50畫素的虛線!

● 繪製矩形:

export default class  Note extends Component{
    render(){
         const path = new Path()
            .moveTo(1,1)
            .lineTo(1,99)
            .lineTo(99,99)
            .lineTo(99,1)
            .close();
        return(
           <View style={styles.container}>
                <Surface width={100} height={100}>
                  <Shape d={path} stroke="#000000" fill="#892265" strokeWidth={1} />
                </Surface>
            </View>
        )
    }

}

注意:close的意思是建立一個密閉的路徑,首先通過linrTo繪製三條邊,然後使用close連結第四條邊。使用fill設定裡面的填充色。

● 繪製圓形:

export default class  Note extends Component{
    render(){
         const path = new Path()
            .moveTo(50,1)
            .arc(0,99,25)
            .arc(0,-99,25)
            .close();

        return(
           <View style={styles.container}>
                <Surface width={100} height={100}>
                 <Shape d={path} stroke="#000000" strokeWidth={1}/>
                </Surface>
            </View>
        )
    }

}
  注意:acr(x,y,radius)終點座標距離起始點的相對距離

● 繪製字型:

export default class  Note extends Component{
    render(){
        const   path=new Path()
        .moveTo(40,40)
        .lineTo(99,10);

        return(
           <View style={styles.container}>
                <Surface width={100} height={100}>
                   <Text strokeWidth={1} stroke="#000" font="bold 35px Heiti SC" path={path} >Swipe</Text>
                </Surface>
            </View>
        )
    }

}

注意:font的使用

● 繪製扇形:

const {Surface} = ART;
import Wedge from './Wedge'

export default class  Note extends Component{
    render(){
        const  path=new Path()
        .moveTo(40,40)
        .lineTo(99,10);

        return(
           <View style={styles.container}>
                 <Surface width={100} height={100}>
                    <Wedge
                     outerRadius={50}
                     startAngle={0}
                     endAngle={60}
                     originX={50}
                     originY={50}
                     fill="blue"/>

                </Surface>
            </View>
        )
    }

}
   注意:使用了一個React.art封裝的一個元件Wedge;

● 圖層疊加:

const {Surface, Shape,Text, Path,Group} = ART;
export default class  Note extends Component{
    render(){

        const pathRect = new Path()
            .moveTo(1,1)
            .lineTo(1,99)
            .lineTo(99,99)
            .lineTo(99,1)
            .close();

        const pathCircle = new Path()
            .moveTo(50,1)
            .arc(0,99,25)
            .arc(0,-99,25)
            .close();

        const pathText = new Path()
            .moveTo(40,5)
            .lineTo(40,99);


        return(
            <View style={styles.container}>
                <Surface width={100} height={100}>
                    <Group>
                        <Shape d={pathRect} stroke="#000000" fill="#000000" strokeWidth={1}/>
                        <Shape d={pathCircle} stroke="#FFFFFF" fill="#FFFFFF" strokeWidth={1}/>
                        <Text strokeWidth={1} strokeDash={[2,1,2,1]} stroke="#000" font="bold 30px Heiti SC" path={pathText} >Swipe</Text>
                    </Group>
                </Surface>
            </View>
        )
    }

}

注意:圖層疊加,上一層的會覆蓋下一層的,類似於安卓的幀佈局!

三:高階例子:
效果圖:

這裡寫圖片描述

import React ,{
    Component
}from 'react';
import {
  ART as Art,
  StyleSheet,
  View,
  Dimensions,
  TouchableWithoutFeedback,
  Animated
} from 'react-native';

var HEART_SVG = "M130.4-0.8c25.4 0 46 20.6 46 46.1 0 13.1-5.5 24.9-14.2 33.3L88 153.6 12.5 77.3c-7.9-8.3-12.8-19.6-12.8-31.9 0-25.5 20.6-46.1 46-46.2 19.1 0 35.5 11.7 42.4 28.4C94.9 11 111.3-0.8 130.4-0.8"
var HEART_COLOR = 'rgb(226,38,77,1)';
var GRAY_HEART_COLOR = "rgb(204,204,204,1)";

var FILL_COLORS = [ 
  'rgba(221,70,136,1)',
  'rgba(212,106,191,1)',
  'rgba(204,142,245,1)',
  'rgba(204,142,245,1)',
  'rgba(204,142,245,1)',
  'rgba(0,0,0,0)'
];

var PARTICLE_COLORS = [
  'rgb(158, 202, 250)',
  'rgb(161, 235, 206)',
  'rgb(208, 148, 246)',
  'rgb(244, 141, 166)',
  'rgb(234, 171, 104)',
  'rgb(170, 163, 186)'
]

 getXYParticle=(total, i, radius)=> {
  var angle = ( (2*Math.PI) / total ) * i;

  var x = Math.round((radius*2) * Math.cos(angle - (Math.PI/2)));
  var y = Math.round((radius*2) * Math.sin(angle - (Math.PI/2)));
  return {
    x: x,
    y: y,
  }
}

 getRandomInt=(min, max)=> {
  return Math.floor(Math.random() * (max - min)) + min;
}

 shuffleArray=(array)=> {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}


var {
  Surface,
  Group,
  Shape,
  Path
} = Art;

//使用Animated.createAnimatedComponent對其他元件建立對話
//建立一個灰色的新型圖片
var AnimatedShape = Animated.createAnimatedComponent(Shape);

var {
  width: deviceWidth,
  height: deviceHeight
} = Dimensions.get('window');

export default  class Key extends  Component{
  constructor(props) {
    super(props);

    this.state = {
       animation: new Animated.Value(0) 
    };
  }

  explode=()=> {
    Animated.timing(this.state.animation, {
      duration: 1500,
      toValue: 28
    }).start(() => {
      this.state.animation.setValue(0);
      this.forceUpdate();
    });
  }

  getSmallExplosions=(radius, offset)=> {
    return [0,1,2,3,4,5,6].map((v, i, t) => {

      var scaleOut = this.state.animation.interpolate({
        inputRange: [0, 5.99, 6, 13.99, 14, 21],
        outputRange: [0, 0, 1, 1, 1, 0],
        extrapolate: 'clamp'
      });

      var moveUp = this.state.animation.interpolate({
        inputRange: [0, 5.99, 14],
        outputRange: [0, 0, -15],
        extrapolate: 'clamp'
      });

      var moveDown = this.state.animation.interpolate({
        inputRange: [0, 5.99, 14],
        outputRange: [0, 0, 15],
        extrapolate: 'clamp'
      });

      var color_top_particle = this.state.animation.interpolate({
        inputRange: [6, 8, 10, 12, 17, 21],
        outputRange: shuffleArray(PARTICLE_COLORS)
      })

      var color_bottom_particle = this.state.animation.interpolate({
        inputRange: [6, 8, 10, 12, 17, 21],
        outputRange: shuffleArray(PARTICLE_COLORS)
      })

      var position = getXYParticle(7, i, radius)

      return (
        <Group 
          x={position.x + offset.x } 
          y={position.y + offset.y} 
          rotation={getRandomInt(0, 40) * i}
        >
          <AnimatedCircle 
            x={moveUp}
            y={moveUp}
            radius={15} 
            scale={scaleOut} 
            fill={color_top_particle} 
          />
          <AnimatedCircle 
            x={moveDown}
            y={moveDown}
            radius={8} 
            scale={scaleOut} 
            fill={color_bottom_particle} 
          />
        </Group>
      )
    }, this)
  }
  render() {
    var heart_scale = this.state.animation.interpolate({
      inputRange: [0, .01, 6, 10, 12, 18, 28],
      outputRange: [1, 0, .1, 1, 1.2, 1, 1],
      extrapolate: 'clamp'
    });

    var heart_fill = this.state.animation.interpolate({
      inputRange: [0, 2],
      outputRange: [GRAY_HEART_COLOR, HEART_COLOR],
      extrapolate: 'clamp'
    })

    var heart_x = heart_scale.interpolate({
      inputRange: [0, 1],
      outputRange: [90, 0],
    })

    var heart_y = heart_scale.interpolate({
      inputRange: [0, 1],
      outputRange: [75, 0],
    })

    var circle_scale = this.state.animation.interpolate({
      inputRange: [0, 1, 4],
      outputRange: [0, .3, 1],
      extrapolate: 'clamp'
    });

    var circle_stroke_width = this.state.animation.interpolate({
      inputRange: [0, 5.99, 6, 7, 10],
      outputRange: [0, 0, 15, 8, 0],
      extrapolate: 'clamp'
    });

    var circle_fill_colors = this.state.animation.interpolate({
      inputRange: [1, 2, 3, 4, 4.99, 5],
      outputRange: FILL_COLORS,
      extrapolate: 'clamp'
    })

    var circle_opacity = this.state.animation.interpolate({
      inputRange: [1,9.99, 10],
      outputRange: [1, 1, 0],
      extrapolate: 'clamp'
    })


    return (
      <View style={styles.container}>
        <TouchableWithoutFeedback onPress={this.explode} style={styles.container}> 
          <View style={{transform: [{scale: .8}]}}>
            <Surface width={deviceWidth} height={deviceHeight}>
              <Group x={75} y={200}>
             //是一個心形的影象
                <AnimatedShape
                  d={HEART_SVG}
                  x={heart_x}
                  y={heart_y}
                  scale={heart_scale}
                  fill={heart_fill}
                />
                <AnimatedCircle
                  x={89}
                  y={75}
                  radius={150}
                  scale={circle_scale}
                  strokeWidth={circle_stroke_width}
                  stroke={FILL_COLORS[2]}
                  fill={circle_fill_colors}
                  opacity={circle_opacity}
                />

                {this.getSmallExplosions(75, {x:89, y:75})}
              </Group>
            </Surface>
          </View>
        </TouchableWithoutFeedback>
      </View>
    );
  }
};

class  AnimatedCircle  extends  Component{
  render(){
     var radius = this.props.radius;
    var path = Path().moveTo(0, -radius)
        .arc(0, radius * 2, radius)
        .arc(0, radius * -2, radius)
        .close();
    return  React.createElement(AnimatedShape, React.__spread({},  this.props, {d: path}));
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
  }
});

相關推薦

react-native-Art動畫基礎

一:基礎: ART:暴露了七個元件: ● Surface - 一個矩形可渲染的區域,是其他元素的容器! ● Group - 可容納多個形狀、文字和其他的分組 ● Shape - 形狀定義,可填充 ● Text - 文字形狀定義 pro

react-native-ART-繪圖

Android預設就包含ART庫,IOS需要單獨新增依賴庫。(新增依賴的方法百度一下哦) 這裡主要是我自己做的筆記,把別人的程式碼都跑了一遍而已 基礎元件 ART暴露的元件有7個,這篇用到的有五個。先介紹即將用到的四個元件,之後在介紹另外三個。  Surface -

React-Native ART 繪圖簡析

剛建立的React Native 微信公眾號,歡迎微信掃描關注訂閱號,每天定期會分享react native 技術文章,移動技術乾貨,精彩文章技術推送。同時可以掃描我的微信加入react-native技術交流微信群。歡迎各位大牛,React Native技術愛好者加入交流

react-native-art畫二次貝塞爾曲線實現

1、關於react-native ART庫的使用,目前網上能搜到的少之又少,簡書上的一篇react-native-art 繪圖入門,從基本上講解了一下react-native-art的使用方法,但是隻是簡單的橫豎曲線的繪製,但專案中有一個需求就是繪製網速的速率曲線, (專案

React Native Animated動畫

在React Native中,我們可以通過兩種方式實現一個動畫效果: LayoutAnimation Animated 關於LayoutAnimation,我之前寫過一篇學習部落格(React Native LayoutAnimation動畫)。此主要用

react-native-art path程式碼解析

React-Native-ART程式碼解析 一、探尋原始碼 1.如何使用 安卓自己整合,不需要額外操作,iOS需要pod新增ART庫,如下: pod 'React', :path => '../rn-source', :subspecs =

React Native LayoutAnimation動畫

在React Native中,LayoutAnimation用於在頁面佈局發生改變時,新增動畫效果。 LayoutAnimation使用簡單,要實現動畫效果只需要在setState()前新增LayoutAnimation動畫方法: //新增一張圖片

React-Native之手勢基礎

   好的東西都要分享,尊重原版原連結。        React-Native是一款由Facebook開發並開源的框架,主要賣點是使用JavaScript編寫原生的移動應用。從2015年3月份開源到現在,已經差不多有半年。目前,React-Native正在以幾乎每週一

react native props state 網絡請求 native組件等一些基礎知識

tex ntc 引擎 dict events 容量 通過 one should > js 的6種類型 number string Boolean object function undefined >給對象添加一個屬性 let a ={} Object.as

使用WebStorm開發React-native基礎

ttr regexp 渲染 hang reg 路徑 tostring png text 配置問題: (1)找不到SDK路徑,或者沒有SDK對應的版本:SDK必須是android-23才可以(更新SDK) 解決方法:環境變量,必須設置Android_HOME

react native基礎

初始化 dcom 更新 con one stat The 銷毀 變化 react native 的兩個核心的屬性控制改變組件:props和state。props是在父組件中進行設置,只要設置完成那麽在組件的生命周期就定死了,不會發生改變。針對數據變化修改的情況,我們需要使用

React Native 入門基礎知識總結

入門 部署 社區 另一個 變化 started EDA set rop 中秋在家閑得無事,想著做點啥,後來想想,為啥不學學 react native。在學習 React Native 時, 需要對前端(HTML,CSS,JavaScript)知識有所了解。對於JS,可以看看

React Native基礎元件

轉載請註明出處:小樓一夜聽春雨的專欄http://blog.csdn.net/win816723459/article/details/54134171 本節主要介紹以下元件 View 容器元件(同Html中的div標籤) Text 文字元件(同Html中的p標籤)

React-Native Navigator 過渡動畫卡頓的解決方案

在RN0.44版本之前,路由導航跳轉幾乎是使用的是Navigator元件,在0.44版本以後就不推薦使用了,官方推薦的是react-navigation,當然還是可以在廢棄的庫中找到: import { Navigator } from 'react-native-deprecated-custom-comp

美團React Native基礎元件庫beeshell詳解

近年來,伴隨著大前端概念的提出和興起,移動端和前端的邊界變得越來越模糊,湧現了一大批移動跨平臺開發框架和模式。從早期的PhoneGap、inoc等Hybird技術,到現在耳熟能詳的React Native、Weex和Flutter等技術,無不體現著移動端開發的前

react native 動畫元件Animated

Animate.js import React, { Component } from 'react' import { AppRegistry, StyleSheet, Text, View, Animated, //使用Animated元件 Easin

React Native動畫總結

ops rom nsf 依賴 不能 top oval chm translate   最近在使用react native進行App混合開發,相對於H5的開發,RN所提供的樣式表較少,RN中不能使用類似於css3中的動畫,因此,RN提供了Animated的API   1.寫一

React Native 基礎

雖然React Native出來已經很久了,但是還是想分享一下。技術這東西更新的太快,覺得有用就學,不能猶豫,不然什麼都不會。 一,環境配置 1,這裡講的是window+android配置,如果想了解其他配置請去官網檢視(http://reactnative.cn/) 2,本人

React Native SVG Animated 繪製動畫

轉自:React Native SVG描邊動畫 stroke屬性 stroke 定義描邊顏色 stroke="#0078ff" strokeWidth 定義描邊的寬度 strokeWidth="3" 建立虛線時候用到的屬性: strokeDasharra

React Native基礎&入門教程:初步使用Flexbox佈局

在本篇裡,讓我們一起來了解一下,什麼是Flexbox佈局,以及如何使用。 一、長度的單位 在開始任何佈局之前,讓我們來首先需要知道,在寫React Native元件樣式時,長度的不帶單位的,它表示“與裝置畫素密度無關的邏輯畫素點”。 這個怎麼理解呢? 我們知道,螢幕上一個發光的最小點,對應著一