51 votes

Comment puis-je utiliser Fabric.js avec React?

J'ai une demande à l'aide d'fortement HTML5 canvas via Fabric.js. L'application est écrite en haut de Angulaire 1.x, et j'ai l'intention de migrer à Réagir. Mon application permet d'écrire du texte et le dessin des lignes, des rectangles et des ellipses. Il est également possible de déplacer, agrandir, réduire, sélectionner, couper, copier, et coller un ou plusieurs de ces objets. Il est également possible de zoom et de panoramique de la toile à l'aide de divers raccourcis. En bref, mon application utilise Fabric.js à sa pleine mesure.

Je ne pouvais pas trouver beaucoup d'informations sur la façon d'utiliser Fabric.js avec Réagir, donc mon souci est que 1. est-il possible, sans modifications majeures, et 2. est-il normal ou devrais-je plutôt utiliser un autre vaste toile de bibliothèque qui a un meilleur support pour Réagir?

Le seul exemple de Réagir+Fabric.js j'ai pu trouver, a été réagir-nokia, qui, cependant, est beaucoup plus simple que mon application. Mes principales préoccupations sont l'événement de transformation et de manipulation du DOM de Fabric.js et de leur effet sur les Réagissent.

Il semble y avoir également une toile de bibliothèque pour Réagir, appelé réagir la toile, mais il semble manquer d'un grand nombre de fonctionnalités par rapport à Fabric.js.

Que dois-je prendre en compte (au sujet de manipulation du DOM, le traitement des événements, etc.) lors de l'utilisation de Fabric.js dans une Réagir application?

58voto

STHayden Points 169

Nous avons eu ce même problème dans notre app de la façon de les utiliser Fabric.js à l'intérieur de réagir. Ma recommandation est de traiter un tissu, comme un incontrôlée de la composante. Ont tissu instance que l'ensemble de votre application peut parler et faire un tissu appels et puis quand tout changement d'utilisation .toObject() appel pour mettre l'ensemble du tissu de l'état dans votre Redux magasin. Ensuite Réagir votre application peut lire le tissu de l'état de votre Redux état comme vous le feriez dans le fonctionnement normal de Réagir app.

Je ne peux pas obtenir un exemple de travail dans le StackOverflow de l'éditeur de code, mais ici est un JSFiddle exemple qui implémente le modèle que je recommande.

23voto

rm- Points 4069

J'ai utilisé Tissu pour une preuve de concept de projet et l'idée générale est la même que pour, disons, D3. Gardez à l'esprit que le Tissu fonctionne sur des éléments du DOM, tandis que Réagir affiche les données dans le DOM, et généralement, ce dernier est reporté. Il y a deux choses qui vont vous aider à vous assurer que votre code fonctionne:

Attendre jusqu'à ce que le composant est monté

Pour ce faire, placez votre Tissu d'instanciation en componentDidMount:

import React, { Component } from 'react';
import { fabric } from 'react-fabricjs';
import styles from './MyComponent.css';

class MyComponent extends Component {
  componentWillMount() {
    // dispatch some actions if you use Redux
  }

  componentDidMount() {
    const canvas = new fabric.Canvas('c');

    // do some stuff with it
  }

  render() {
    return (
      <div className={styles.myComponent}>
        <canvas id="c" />
      </div>
    )
  }
}

Placer le Tissu constructeur en componentDidMount assure de ne pas échouer parce que pour le moment cette méthode est exécutée, le DOM est prêt. (mais les accessoires ne sont parfois pas, juste au cas où si vous utilisez Redux)

Utiliser les références afin de calculer la largeur et la hauteur

Refs sont les références à la réalité des éléments du DOM. Vous pouvez le faire avec refs ce que vous pouvez faire avec des éléments du DOM en utilisant des API DOM: sélectionner les enfants, trouver un parent, d'attribuer des propriétés de style, calculer innerHeight et innerWidth. Ce dernier est précisément ce dont vous avez besoin:

componentDidMount() {
  const canvas = new fabric.Canvas('c', {
    width: this.refs.canvas.clientWidth,
    height: this.refs.canvas.clientHeight
  });

  // do some stuff with it
}

N'oubliez pas de définir refs de la propriété de l' this. Pour ce faire, vous aurez besoin d'un constructeur. Le tout serait ressembler à

import React, { Component } from 'react';
import { fabric } from 'react-fabricjs';
import styles from './MyComponent.css';

class MyComponent extends Component {
  constructor() {
    super()
    this.refs = {
      canvas: {}
    };
  }

  componentWillMount() {
    // dispatch some actions if you use Redux
  }

  componentDidMount() {
    const canvas = new fabric.Canvas('c', {
      width: this.refs.canvas.clientWidth,
      height: this.refs.canvas.clientHeight
    });

    // do some stuff with it
  }

  render() {
    return (
      <div className={styles.myComponent}>
        <canvas
          id="c"
          ref={node => {
            this.refs.canvas = node;
          } />
      </div>
    )
  }
}

Tissu de mélange avec l'état des composants ou des accessoires

Vous pouvez faire votre Tissu instance de réagir à tout composant d'accessoires ou de mises à jour d'état. Pour le faire fonctionner, il suffit de mettre à jour votre Tissu instance (qui, comme vous avez pu le voir, vous pouvez stocker dans le cadre de la composante propres propriétés) sur componentDidUpdate. Tout simplement en s'appuyant sur render des appels de fonction ne sera pas vraiment utile, car aucun des éléments qui sont rendus devait jamais changer sur de nouvelles disciplines ou de nouvelles de l'état. Quelque chose comme ceci:

import React, { Component } from 'react';
import { fabric } from 'react-fabricjs';
import styles from './MyComponent.css';

class MyComponent extends Component {
  constructor() {
    this.refs = {
      canvas: {}
    };
  }

  componentWillMount() {
    // dispatch some actions if you use Redux
  }

  componentDidMount() {
    const canvas = new fabric.Canvas('c', {
      width: this.refs.canvas.clientWidth,
      height: this.refs.canvas.clientHeight
    });

    this.fabric = canvas;

    // do some initial stuff with it
  }

  componentDidUpdate() {
    const {
      images = []
    } = this.props;
    const {
      fabric
    } = this;

    // do some stuff as new props or state have been received aka component did update
    images.map((image, index) => {
      fabric.Image.fromURL(image.url, {
        top: 0,
        left: index * 100 // place a new image left to right, every 100px
      });
    });
  }

  render() {
    return (
      <div className={styles.myComponent}>
        <canvas
          id="c"
          ref={node => {
            this.refs.canvas = node;
          } />
      </div>
    )
  }
}

Il suffit de remplacer le rendu d'image avec le code dont vous avez besoin et qui dépend de la nouvelle composante de l'état ou les accessoires. N'oubliez pas de nettoyer la toile avant de rendre de nouveaux objets, trop!

1voto

Radomír Laučík Points 192

Il est également réagir-fabricjs package qui permet d'utiliser le tissu des objets réagir composants. En fait, Rishat la réponse comprend ce paquet, mais je ne comprends pas comment c'est censé fonctionner comme il n'y a pas de 'tissu' objet dans la réaction fabricjs (il a sans doute le sens de " tissu-webpack package). Un exemple simple 'Bonjour le monde' composante:

import React from 'react';
import {Canvas, Text} from 'react-fabricjs';

const HelloFabric = React.createClass({
  render: function() {
    return (
      <Canvas
        width="900"
        height="900">
          <Text
            text="Hello World!"
            left={300}
            top={300}
            fill="#000000"
            fontFamily="Arial"
          />
      </Canvas>
    );
  }
});

export default HelloFabric;

Même si vous ne souhaitez pas utiliser ce package, explorer c'est le code peut vous aider à comprendre comment mettre en œuvre Fabric.js dans Réagissent par vous-même.

-2voto

Marc L. Points 655

Oups!

Si vous attendiez des réponses à propos de Microsoft Fabric, vous êtes au mauvais endroit. Vous devriez être à la recherche de .

(La réponse originale est sans importance et légèrement gênante, supprimée.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X