Maison > interface Web > js tutoriel > À propos de la méthode de dessin ART de React-Native

À propos de la méthode de dessin ART de React-Native

不言
Libérer: 2018-06-30 11:57:08
original
2228 Les gens l'ont consulté

Cet article présente principalement l'explication détaillée de la méthode de dessin ART de React-Native. Le contenu est assez bon, je vais le partager avec vous maintenant et le donner comme référence.

Contexte

Lors du processus de développement d'applications mobiles, dessiner des graphiques ou des animations bidimensionnelles de base est essentiel. Cependant, étant donné qu’Android et iOS disposent de leurs propres solutions API, l’adoption d’une solution technique plus généralement acceptée est plus propice à la compatibilité du code sur deux plates-formes.

art est un module CommonJS de style Node conçu pour être compatible avec plusieurs navigateurs. Sur cette base, Facebook a développé React-art, qui encapsule l'art afin qu'il puisse être utilisé par React.js, qui implémente la bibliothèque frontale SVG. Cependant, compte tenu de la syntaxe JSX de React.js, il prend déjà en charge l'insertion de balises SVG et ainsi de suite directement dans le dom (bien sûr, la bibliothèque React-Art n'est pas utilisée pour le moment. De plus, il existe un canevas HTML). , donc sur le front-end, React-Art n'est pas irremplaçable.

Cependant, côté mobile, compte tenu des besoins multiplateformes et de l'accumulation de technologies côté Web, React-Art est devenu une solution toute faite pour dessiner des graphiques. React-native a ajouté la prise en charge de React-Art sur les plates-formes iOS et Android dans les versions 0.10.0 et 0.18.0 respectivement.

Exemple de code

La différence entre React.js et React-Native réside uniquement dans l'acquisition ART décrite ci-dessous, et cet exemple peut ensuite être appliqué au côté Web en même temps et terminal mobile. L'exemple officiel fourni avec React-Art : Vector-Widget

Vector-Widget implémente en outre la réponse de rotation et d'accélération de rotation aux événements de clic de souris. L'accélération des clics est visible côté Web, mais elle n'est pas valide du côté mobile. La raison en est que React Native ne traite pas les attributs onMouseDown et onMouseUp dans le groupe. Cet article se concentre sur l'implémentation du SVG statique et ignore temporairement certains effets d'animation.

ART

ART est une bibliothèque très importante dans React Native, qui permet des dessins et des animations très sympas. Il convient de noter que lors de l'introduction d'ART dans React Native, Android inclut la bibliothèque ART par défaut et IOS doit ajouter les bibliothèques dépendantes séparément.

ios ajoute une bibliothèque dépendante

1 Utilisez xcode pour ouvrir le projet iOS dans React-native, sélectionnez le répertoire 'Bibliothèques'——> sélectionnez 'Ajouter des fichiers' au nom du projet' ——> 'node_modules/react-native/Libraries/ART/ART.xcodeproj' Ajouter

À propos de la méthode de dessin ART de React-Native

2. Sélectionnez le répertoire racine du projet — —> Cliquez sur 'Build Phases' ——> Cliquez sur 'Link Binary With Libraries' ——> Cliquez sur '+' en bas à gauche ——>

À propos de la méthode de dessin ART de React-Native

Composants de base

ART expose un total de 7 composants : Surface, Groupe, Forme, texte.

  • Surface - une zone de rendu rectangulaire qui est un conteneur pour d'autres éléments

  • Groupe - peut contenir plusieurs formes, textes et autres éléments Groupe

  • Forme - définition de forme, remplissable

  • Texte - définition de forme de texte

Propriétés

Surface

  • largeur : largeur de la zone de rendu

  • hauteur : définit la hauteur du rendu zone

Forme

  • d : Définir le chemin du dessin

  • trait : Couleur du trait

  • StrokeWidth : largeur du trait

  • StrokeDash : définir une ligne pointillée

  • fill : couleur de remplissage

Texte

  • funt : style de police, définir la police, la taille, s'il faut mettre en gras, tel que : gras 35px Heiti SC

Chemin

  • moveTo(x,y) : Déplacer vers les coordonnées (x,y)

  • lineTo( x,y ) : se connecter à (x, y)

  • arc() : dessiner un arc

  • close() : fermer l'espace

Exemple de code

Tracer une ligne droite

À propos de la méthode de dessin ART de React-Native

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

export default class Line extends React.Component{

  render(){

    const path = ART.Path();
    path.moveTo(1,1); //将起始点移动到(1,1) 默认(0,0)
    path.lineTo(300,1); //连线到目标点(300,1)

    return(
      <View style={this.props.style}>
        <ART.Surface width={300} height={2}>
          <ART.Shape d={path} stroke="#000000" strokeWidth={1} />
        </ART.Surface>
      </View>
    )
  }
}
Copier après la connexion

Dessiner une ligne pointillée

Comprendre les paramètres de StrokeDash,

[10,5] : signifie dessiner un 10- ligne continue de pixels et dessiner un blanc de 5 pixels, boucle comme ceci

[10,5,20,5] : signifie dessiner une ligne continue de 10 pixels, puis dessiner un blanc de 5 pixels, puis dessinez une ligne continue de 20 pixels et un blanc de 5 pixels

À propos de la méthode de dessin ART de React-Native

import React from &#39;react&#39;
import {
  View,
  ART
} from &#39;react-native&#39;

const {Surface, Shape, Path} = ART;

export default class DashLine extends React.Component{

  render(){

    const path = Path()
      .moveTo(1,1)
      .lineTo(300,1);

    return(
      <View style={this.props.style}>
        <Surface width={300} height={2}>
          <Shape d={path} stroke="#000000" strokeWidth={2} strokeDash={[10,5]}/>
        </Surface>
      </View>
    )
  }
}
Copier après la connexion

Dessinez un rectangle

Dessinez d'abord trois côtés via lineTo et utilisez le quatrième bord de lien étroit. fill fait le remplissage de couleur

À propos de la méthode de dessin ART de React-Native

import React from &#39;react&#39;
import {
  View,
  ART
} from &#39;react-native&#39;

const {Surface, Shape, Path} = ART;

export default class Rect extends React.Component{

  render(){

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

    return(
      <View style={this.props.style}>
        <Surface width={100} height={100}>
          <Shape d={path} stroke="#000000" fill="#892265" strokeWidth={1} />
        </Surface>
      </View>
    )
  }
}
Copier après la connexion

绘圆

了解arc(x,y,radius)的使用, 终点坐标距离起点坐标的相对距离。

À propos de la méthode de dessin ART de React-Native

import React from &#39;react&#39;
import {
  View,
  ART
} from &#39;react-native&#39;

const {Surface, Shape, Path} = ART;

export default class Circle extends React.Component{

  render(){

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


    return(
      <View style={this.props.style}>
        <Surface width={100} height={100}>
          <Shape d={path} stroke="#000000" strokeWidth={1}/>
        </Surface>
      </View>
    )
  }
}
Copier après la connexion

绘制文字

了解funt属性的使用,规则是“粗细 字号 字体”

注意: 字体应该是支持path属性的,应该是实现bug并没有不生效。 Android通过修改源码是可以解决的,IOS没看源码。

À propos de la méthode de dessin ART de React-Native

import React, {Component} from &#39;react&#39;;
import {
  AppRegistry,
  StyleSheet,
  ART,
  View
} from &#39;react-native&#39;;

const {Surface, Text, Path} = ART;

export default class ArtTextView extends Component {

  render() {

    return (
      <View style={styles.container}>
        <Surface width={100} height={100}>
          <Text strokeWidth={1} stroke="#000" font="bold 35px Heiti SC" path={new Path().moveTo(40,40).lineTo(99,10)} >React</Text>
        </Surface>

      </View>

    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: &#39;center&#39;,
    alignItems: &#39;center&#39;,
    backgroundColor: &#39;#F5FCFF&#39;,
  },

});
Copier après la connexion

绘制扇形

À propos de la méthode de dessin ART de React-Native

在这里需要使用arc做路径绘制。

Wedge.js

import React, { Component, PropTypes } from &#39;react&#39;;
import { ART } from &#39;react-native&#39;;
const { Shape, Path } = ART;

/**
 * Wedge is a React component for drawing circles, wedges and arcs. Like other
 * ReactART components, it must be used in a <Surface>.
 */
export default class Wedge extends Component<void, any, any> {

  static propTypes = {
    outerRadius: PropTypes.number.isRequired,
    startAngle: PropTypes.number.isRequired,
    endAngle: PropTypes.number.isRequired,
    originX: PropTypes.number.isRequired,
    originY: PropTypes.number.isRequired,
    innerRadius: PropTypes.number,
  };


  constructor(props : any) {
    super(props);
    (this:any).circleRadians = Math.PI * 2;
    (this:any).radiansPerDegree = Math.PI / 180;
    (this:any)._degreesToRadians = this._degreesToRadians.bind(this);
  }

  /**
   * _degreesToRadians(degrees)
   *
   * Helper function to convert degrees to radians
   *
   * @param {number} degrees
   * @return {number}
   */
  _degreesToRadians(degrees : number) : number {
    if (degrees !== 0 && degrees % 360 === 0) { // 360, 720, etc.
      return (this:any).circleRadians;
    }
    return degrees * (this:any).radiansPerDegree % (this:any).circleRadians;
  }

  /**
   * _createCirclePath(or, ir)
   *
   * Creates the ReactART Path for a complete circle.
   *
   * @param {number} or The outer radius of the circle
   * @param {number} ir The inner radius, greater than zero for a ring
   * @return {object}
   */
  _createCirclePath(or : number, ir : number) : Path {
    const path = new Path();

    path.move(0, or)
      .arc(or * 2, 0, or)
      .arc(-or * 2, 0, or);

    if (ir) {
      path.move(or - ir, 0)
        .counterArc(ir * 2, 0, ir)
        .counterArc(-ir * 2, 0, ir);
    }

    path.close();

    return path;
  }

  /**
   * _createArcPath(sa, ea, ca, or, ir)
   *
   * Creates the ReactART Path for an arc or wedge.
   *
   * @param {number} startAngle The starting degrees relative to 12 o&#39;clock
   * @param {number} endAngle The ending degrees relative to 12 o&#39;clock
   * @param {number} or The outer radius in pixels
   * @param {number} ir The inner radius in pixels, greater than zero for an arc
   * @return {object}
   */
  _createArcPath(originX : number, originY : number, startAngle : number, endAngle : number, or : number, ir : number) : Path {
    const path = new Path();

    // angles in radians
    const sa = this._degreesToRadians(startAngle);
    const ea = this._degreesToRadians(endAngle);

    // central arc angle in radians
    const ca = sa > ea ? (this:any).circleRadians - sa + ea : ea - sa;

    // cached sine and cosine values
    const ss = Math.sin(sa);
    const es = Math.sin(ea);
    const sc = Math.cos(sa);
    const ec = Math.cos(ea);

    // cached differences
    const ds = es - ss;
    const dc = ec - sc;
    const dr = ir - or;

    // if the angle is over pi radians (180 degrees)
    // we will need to let the drawing method know.
    const large = ca > Math.PI;

    // TODO (sema) Please improve theses comments to make the math
    // more understandable.
    //
    // Formula for a point on a circle at a specific angle with a center
    // at (0, 0):
    // x = radius * Math.sin(radians)
    // y = radius * Math.cos(radians)
    //
    // For our starting point, we offset the formula using the outer
    // radius because our origin is at (top, left).
    // In typical web layout fashion, we are drawing in quadrant IV
    // (a.k.a. Southeast) where x is positive and y is negative.
    //
    // The arguments for path.arc and path.counterArc used below are:
    // (endX, endY, radiusX, radiusY, largeAngle)

    path.move(or + or * ss, or - or * sc) // move to starting point
      .arc(or * ds, or * -dc, or, or, large) // outer arc
      .line(dr * es, dr * -ec);  // width of arc or wedge

    if (ir) {
      path.counterArc(ir * -ds, ir * dc, ir, ir, large); // inner arc
    }

    return path;
  }

  render() : any {
    // angles are provided in degrees
    const startAngle = this.props.startAngle;
    const endAngle = this.props.endAngle;
    // if (startAngle - endAngle === 0) {
    // return null;
    // }

    // radii are provided in pixels
    const innerRadius = this.props.innerRadius || 0;
    const outerRadius = this.props.outerRadius;

    const { originX, originY } = this.props;

    // sorted radii
    const ir = Math.min(innerRadius, outerRadius);
    const or = Math.max(innerRadius, outerRadius);

    let path;
    if (endAngle >= startAngle + 360) {
      path = this._createCirclePath(or, ir);
    } else {
      path = this._createArcPath(originX, originY, startAngle, endAngle, or, ir);
    }

    return <Shape {...this.props} d={path} />;
  }
}
Copier après la connexion

示例代码:

import React from &#39;react&#39;
import {
  View,
  ART
} from &#39;react-native&#39;

const {Surface} = ART;
import Wedge from &#39;./Wedge&#39;

export default class Fan extends React.Component{

  render(){

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

        </Surface>
      </View>
    )
  }
}
Copier après la connexion

综合示例

À propos de la méthode de dessin ART de React-Native

相关代码:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

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

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 = &#39;rgb(226,38,77,1)&#39;;
var GRAY_HEART_COLOR = "rgb(204,204,204,1)";

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

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

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(&#39;window&#39;);

export default class ArtAnimView 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: &#39;clamp&#39;
      });

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

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

      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: &#39;clamp&#39;
    });

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

    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: &#39;clamp&#39;
    });

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

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

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


    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);
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
  }
});
Copier après la connexion

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

node.js 利用流实现读写同步,边读边写的功能

angular2和nodejs实现图片上传的的的功能

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal