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!