ger*_*m13 22 javascript reactjs
我正在尝试使用React渲染画布.画布内的图形也将由Reacts render方法处理.
当前代码确实使用我想要的图形渲染画布.但是我正在寻找一种方式来回报我的图形画布从内render方法.我想要这个的原因是因为我希望这个以"React Way"工作.
理想情况下,我希望我的代码是这样的:
return(
<div>
<canvas id='my_canvas_with_graphics_rendered_in_react'></canvas>
</div>
);
Run Code Online (Sandbox Code Playgroud)
首先,我想知道这是否可行.或者,如果我应该寻找替代方案.
也许我错过了React的观点,如果是这样的话请告诉我.我希望有一个解决方案,因为从我读过的内容看,React将自己称为Vin MVC.这就是为什么,如果可能的话,这将是我正在尝试做的完美解决方案.我不必担心画布内的渲染.我只是将数据提供给组件,React将重新呈现更改.
我在return声明中标明了我认为正确的代码应该去的地方.
该HTML代码:
<div id='wrapper'>
<canvas id='canvas'></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)
该jsx代码:
var MyCanvas = React.createClass({
render:function(){
var line = this.props.lines;
var ctx = this.props.canvas.getContext("2d");
ctx.strokeStyle = 'rgba(0,0,0,0.5)';
ctx.beginPath();
ctx.moveTo(line[0].x0, line[0].y0);
// .... more code .....
ctx.stroke();
return(
<div>
/* *********************************
??? RETURN MY RENDERED CANVAS
WITH GRAPHIC LINES. ????
This is where I want to return the canvas
********************************* */
</div>
);
}
});
var wrapper = document.getElementById('wrapper');
var canvas = document.getElementById('canvas');
var line1 = { x0: 0, y0: 10, x1: 20, y1: 30 };
var line2 = { x0: 40, y0: 50, x1: 60, y1: 70 };
var myCanvas = <MyCanvas canvas={ canvas } lines={ [line1, line2] } />;
React.render(myCanvas, wrapper);
Run Code Online (Sandbox Code Playgroud)
希望我清楚自己.
Ali*_*tor 18
你唯一的错误是你不熟悉反应参考.试试这个:
class ConnectionChart extends React.Component {
componentDidMount() {
let canvas = ReactDOM.findDOMNode(this.refs.myCanvas);
let ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(200,0,0)';
ctx.fillRect(10, 10, 55, 50);
}
render() {
return (
<div>
<canvas ref="myCanvas" />
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
你可能已经摆脱了ES6风格,但你明白了.因为你也可以用其他方法画画^^
And*_*ahl 13
canvas您render可以执行以下操作,而不是使用您的方法:
var MyCanvas = React.createClass({
componentDidMount: function () {
React.getDOMNode(this).appendChild(this.props.canvas);
},
render: function() {
return <div />;
}
});
Run Code Online (Sandbox Code Playgroud)
你只需渲染一个空,div然后等待React挂载它.安装后,将画布附加到React创建的实际DOM节点.
原因是该render方法只返回React然后转换为真实DOM节点的虚拟DOM节点.由于您有一个真正的DOM节点,因此无法将其转换为虚拟节点.另一个原因是您应该只从render该React控件返回节点.既然你是从Reacts控件之外管理画布,你应该使用真正的DOM apis来管理它.
关键是重写正确的React生命周期方法来进行绘制.render方法创建canvas DOM元素,你可以添加一个refs回调来设置对它的引用,但你必须等到组件被挂载才能在画布上绘制.
这是一个使用回调引用的示例,如React文档所推荐的那样.它设计用于在道具更改时基于道具和更新呈现静态(非动画)图形组件.它还订阅了窗口调整大小事件,以便可以通过CSS(例如width: 100%)动态调整大小. 此示例基于此Gist的代码.
export default class CanvasComponent extends React.Component {
constructor(props) {
super(props);
this._resizeHandler = () => {
/* Allows CSS to determine size of canvas */
this.canvas.width = this.canvas.clientWidth;
this.canvas.height = this.canvas.clientHeight;
this.clearAndDraw();
}
}
componentDidMount() {
window.addEventListener('resize', this._resizeHandler);
/* Allows CSS to determine size of canvas */
this.canvas.width = this.canvas.clientWidth;
this.canvas.height = this.canvas.clientHeight;
this.clearAndDraw();
}
componentWillUnmount() {
window.removeEventListener('resize', this._resizeHandler);
}
componentDidUpdate(prevProps, prevState) {
if (this.props.secondRect !== prevProps.secondRect) {
this.clearAndDraw();
}
}
clearAndDraw() {
const ctx = this.canvas.getContext('2d');
if (ctx) {
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.draw(ctx);
}
}
draw(ctx) {
ctx.fillStyle = 'rgb(200, 0, 0)';
ctx.fillRect(10, 10, 50, 50);
if (this.props.secondRect) {
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
ctx.fillRect(30, 30, 50, 50);
}
}
render() {
return (
<canvas ref={canvas => this.canvas = canvas} />
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以secondRect从父组件设置prop或从状态设置prop以在prop更新时查看组件更新.您可以扩展此构思以构建任何类型的数据驱动的画布渲染,例如图表或图形.
我想我会使用 更新这个答案,React.createRef()因为this.refs现在是遗留的。Refs 和 DOM
import React from "react";
import * as PropTypes from "prop-types";
class Canvas extends React.Component {
constructor() {
super()
this.canvas = React.createRef()
}
componentDidMount() {
const ctx = this.canvas.current.getContext('2d')
this.props.draw(ctx);
}
render() {
return <canvas ref={this.canvas} />;
}
}
Canvas.propTypes = {
draw: PropTypes.func.isRequired
};
export default Canvas
Run Code Online (Sandbox Code Playgroud)
您可以Canvas通过提供绘制上下文来使用它。
<Canvas
draw={ctx => {
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
}
}
/>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19138 次 |
| 最近记录: |