reactjs - 为什么 HTML5 drawImage 不在画布上绘制图像?
问题描述
我尝试添加一个 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;
解决方案
这可能并不明显,但您的问题是由以下行引起的:
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);
}
推荐阅读
- optaplanner - Optaplanner 中的学校时间表(TO DO 评论)
- php - 使用php从数据库中获取多个json
- apache-superset - 如何为 Apache Superset 添加两个 TIme 列过滤器?
- .net - 为我的 Web 应用程序迁移到 Azure Linux 使内存使用量从 50mb 跃升至 300mb - 这正常吗?
- javascript - 如何在另一个元素中使用 parseFromString 脚本输出
- java - 如何在 android studio 应用程序中翻译单词?
- javascript - 如何在更改屏幕时自动滚动到顶部
- solidity - 类型错误:成员在 unit256 中未找到或可见
- networking - 使用带有完整路径的 fs.unlinkSync 删除项目中的文件,它适用于本地服务器,但在部署到 azure web 应用程序后会出现错误(5xx)
- python - 当我安装 tensorflow 时出现以下错误 ImportError: cannot import name '_set_madvise_hugepage' from 'numpy.core._multiarray_umath'