【问题标题】:Why is HTML5 drawImage not drawing images on canvas?为什么 HTML5 drawImage 不在画布上绘制图像?
【发布时间】:2021-03-02 00:49:16
【问题描述】:

我尝试添加一个 eventListener 来仅在图像加载后才绘制图像。 我也尝试在设置图像 src 之前和之后放置事件侦听器,但似乎仍然没有任何效果。

我似乎无法弄清楚究竟是什么原因造成的。谁能解释一下。

import React from 'react';
import {useEffect, useState} from 'react';

function Main() {
    //initiate state
    const [ plane, setPlane ] = useState( new Image() );
    const [ star, setStar ] = useState( new Image() );
    const [ bird, setBird ] = useState( new Image() );
    const [ parachute, setParachute ] = useState( new Image() );
    const [ cloud, setCloud ] = useState( new Image() );
    
    //draw the game animation
    let draw = () => {
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d'); //context

        //set background color
        context.fillStyle = '#74b9ff';
        //context.fillRect(0, 0, canvas.width, canvas.height);

        //load images
        plane.src = 'images/plane.png';
        plane.onload = drawImage( context);
        star.src = 'images/star.png';
        bird.src = 'images/bird.png';
        parachute.src = 'images/parachute.png';
        //cloud.src = 'images/cloud.png';
        // setPlane( prevState => { return {...prevState, src: 'images/plane.png' }  } );
        // setStar( prevState => { return {...prevState, src: 'images/star.png' }  } );
        // setBird( prevState => { return {...prevState, src: 'images/bird.png' }  } );
        // setParachute( prevState => { return {...prevState, src: 'images/parachute.png' }  } );
        // setCloud( prevState => { return {...prevState, src: 'images/cloud.png' }  } );
        
        

    }

    let drawImage = ( context ) => {
        context.drawImage(plane, 0, 0, 50, 50);
    }

    useEffect( () => draw(), [] );

    return (
        <div className="container">
            <canvas width='400px' height='400px' id='canvas'></canvas>
        </div>
    );
}

export default Main;

【问题讨论】:

    标签: reactjs html5-canvas drawimage


    【解决方案1】:

    这可能并不明显,但您的问题是由以下行引起的:

    plane.onload = drawImage( context);
    

    如果这样写,它根本不会像你想的那样做。 onload 事件可以被分配一个回调函数——顾名思义——一旦完成加载就会触发一个函数。如果您附加括号(),它实际上会立即执行函数。

    这意味着它会在加载完成之前尝试绘制图像。

    您需要做的是仅通过函数名称传递对函数的引用。

    plane.onload = drawImage;
    

    你的问题是你想传递一个参数。这是做不到的——至少不能这样。

    但是,您可以做的是使上下文成为 Image 对象本身的属性。

    类似:

    let draw = () => {
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d'); //context
    
        context.fillStyle = '#74b9ff';
    
        plane.context=context;
        plane.onload = drawImage;        
        plane.src = 'images/plane.png';
    }
    
    let drawImage = ( e ) => {
      e.target.context.drawImage(plane, 0, 0, 50, 50);
    }
    

    【讨论】:

    • 我刚才其实正要回答这个问题。但是你的解释很好。我通过写plane.onload = () =&gt; context.drawImage(plane, 0, 0, 50, 50); 解决了这个问题。我猜箭头函数避开了你刚才解释的问题。非常感谢您帮助我理解!
    猜你喜欢
    • 2013-03-28
    • 2015-11-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 2020-04-14
    • 2014-08-15
    相关资源
    最近更新 更多