【问题标题】:How could we load a local image on a canvas?我们如何在画布上加载本地图像?
【发布时间】:2018-08-18 06:27:42
【问题描述】:

您好,感谢您抽出宝贵时间阅读此问题:

我正在尝试做一个练习来学习 React,因为我最近在 JS 中编写了一个代码来从本地加载一个文件,一个图像,一个画布,然后当用户点击它时会绘制圆圈;我尝试在 React 中做同样的事情。

这里是 JS 练习:https://codereview.stackexchange.com/questions/186526/read-an-image-file-into-a-canvas-and-display-click-coordinates

我在 Canvas 组件的 render() 中创建了一个画布,然后调用 make_base 函数获取上下文并将图像加载到其中。

代码如下:

import React from 'react';


class Canvas extends React.Component {
    //A canvas to display images with a title


    constructor(props) {
        super(props);

        this.state = {x: 0, y: 0, inside: ''};

        this.handleClick = this.handleClick.bind(this);
        this.make_base = this.make_base.bind(this);
    }

    _onMouseMove(e) {
        this.setState({x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY});
    }

    componentDidMount() {
        document.addEventListener('click', this.handleClick);
    }

    componentWillUnmount() {
        document.removeEventListener('click', this.handleClick);
    }

    handleClick(e) {
        e.stopPropagation();
        console.log('INSIDE');
        this.setState({inside: 'inside'});
    }

    make_base(image) {
        const context = this.refs.canvas.getContext('2d');
        let base_image = new Image();
        base_image.src = image;
        base_image.onload = function () {
            context.drawImage(base_image, 0, 0);
        }
    }


    render() {

        const {x, y, inside} = this.state;

        return (
            <div className="previewComponent">
                <div className="imgPreview">
                    {this.props.title}

                    <canvas ref="canvas" width={300} height={300}></canvas>
                    {this.make_base(this.props.image)}

                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
                         onClick={this.handleClick.bind(this)}/>

                    <h1>Mouse coordinates: {x} {y}</h1>
                    <h2>Inside?: {inside}</h2>
                </div>
            </div>
        )
    }
}

export {Canvas};

控制台告诉我们:

TypeError: Cannot read property 'getContext' of undefined
Canvas.make_base
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:36
  33 |    }
  34 | 
  35 |    make_base(image) {
> 36 |        const context = this.refs.canvas.getContext('2d');
  37 |        let base_image = new Image();
  38 |        base_image.src = image;
  39 |        base_image.onload = function () {
View compiled
Canvas.render
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:55
  52 |                    {this.props.title}
  53 | 
  54 |                    <canvas ref="canvas" width={300} height={300}></canvas>
> 55 |                    {this.make_base(this.props.image)}
  56 | 
  57 |                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
  58 |                         onClick={this.handleClick.bind(this)}/>

如果假设我们已经在 render() 方法中创建了画布,我不明白为什么 getContext() 会变得未定义。

另外我研究过:

How to access canvas context in React

https://blog.lavrton.com/using-react-with-html5-canvas-871d07d8d753

How to add image to canvas

编辑:

我已经尝试了建议的答案,控制台仍然告诉我们:

TypeError: Cannot read property 'getContext' of undefined
Canvas.make_base
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:36
  33 |    }
  34 | 
  35 |    make_base(image) {
> 36 |        const context = this.canvas.getContext('2d');
  37 |        let base_image = new Image();
  38 |        base_image.src = image;
  39 |        base_image.onload = function () {
View compiled
Canvas.render
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:55
  52 |                    {this.props.title}
  53 | 
  54 |                    <canvas ref={(canvas) => this.canvas = canvas} width={300} height={300}></canvas>
> 55 |                    {this.make_base(this.props.image)}
  56 | 
  57 |                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
  58 |                         onClick={this.handleClick.bind(this)}/>
View compiled

如果我们对正在编写上下文的行进行注释,我们会看到两个空画布:

可能不应该在渲染方法中创建画布,因为外部方法仍然无法访问它?

EDIT2:给定的答案效果很好:

但是我们想在鼠标点击时在光标所在的位置而不是按钮上绘制,所以问题是,我们如何获取坐标并将它们关联到画布中?

感谢您的帮助

【问题讨论】:

    标签: javascript image reactjs canvas render


    【解决方案1】:

    您使用的 refs 错误。

    您必须将 ref 设置为类变量,如 this.canvas

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.makeBase = this.makeBase.bind(this);
        this.recordMouse = this.recordMouse.bind(this);
      }
      recordMouse(event) {
        const ctx = this.canvas.getContext('2d');
        ctx.beginPath();
        ctx.fillRect(event.nativeEvent.offsetX,event.nativeEvent.offsetY,3,3);
        ctx.stroke();
      }
      makeBase() {
        const ctx = this.canvas.getContext('2d');
        ctx.beginPath();
        ctx.arc(95,50,40,0,2*Math.PI);
        ctx.stroke();
      }
      render() {
        return (
          <div>
            <canvas ref={(canvas)=>this.canvas=canvas} width="200" height="100" onMouseMove={this.recordMouse} />
            <button onClick={this.makeBase}>Make Base</button>
          </div>
        );
      }
    }
    ReactDOM.render(<App />, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>

    https://reactjs.org/docs/refs-and-the-dom.html

    【讨论】:

    • 感谢@Boy With Silver Wings 的帮助和快速回复。我已经尝试了您的代码,然后我阅读了文档。我不得不说它仍然被显示 TypeError: Cannot read property 'getContext' of undefined!
    • @Enoy 我已经添加了一个关于它应该如何工作的工作 sn-p
    • 感谢您的帮助。单击按钮时确实有效。但是,我们如何使用当前光标位置来做到这一点?用鼠标点击!?
    • 那将是一个完全不同的问题。正确的? @Enoy
    • 问题本身就是:如何在 React 中将本地图像加载到画布上?
    猜你喜欢
    • 2014-03-06
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2021-08-04
    • 1970-01-01
    • 2017-07-19
    相关资源
    最近更新 更多