首页 > 解决方案 > 在 React 中清除画布以接收雾效果的位置

问题描述

我正在尝试在 React 中接收雾效果。主要思想是我有两个组件:第一个组件处理更新云的坐标及其速度,第二个组件负责一个云。我在移动云时遇到问题,如果我不清除画布,我可以看到每朵云的轨迹,如果我应用 canvas.clear 我什么也看不到。你有什么提示,我应该在哪里放置 clear canvas.clear 或者你有其他想法吗?

第一个组件:

    import React from 'react';
    import styled from 'styled-components';
    import FogPiece from './Fog-Piece.jsx';

    const CanvasContext = React.createContext();

    const FogDiv = styled.div`
    position: absolute;
    width:100vw;
    height:100vh;
    `

    class Fog extends React.Component{
      constructor(props){
        super(props);
        this.canvas = React.createRef();
        this.state = {
          ctx: null,
          parameters:[],
          screenWidth : 0,
          screenHeight: 0,
        }
      }

      componentDidMount = () => {
        Promise.all(this.newCoordinates()).then((paramArray) =>{
          this.setState({
            ctx: this.canvas.current.getContext('2d'),
            screenWidth: this.canvas.current.parentNode.getBoundingClientRect().width,
            screenHeight: this.canvas.current.parentNode.getBoundingClientRect().height,
            parameters: paramArray
          });
          window.requestAnimationFrame(this.update)
        })
      }

      newCoordinates = () => {
        return(Array.from(Array(this.props.density).keys()).map(elem =>{
          return new Promise (resolve => {
            const params = {
              x: this.random(0,this.state.screenWidth), 
              y: this.random(0,this.state.screenHeight),
              velocityX: this.random(-this.props.maxVelocity, this.props.maxVelocity),
              velocityY: this.random(-this.props.maxVelocity, this.props.maxVelocity)
            }
            resolve(params)
          })
        }))
      }

      updateCoordinates = () => {
        return(this.state.parameters.map(elem =>{
          return new Promise (resolve => {
            elem = this.ifCross(elem.x, elem.y, elem.velocityX, elem.velocityY);
            const params = {
              x: elem.x + elem.velocityX, 
              y: elem.y + elem.velocityY,
              velocityX: elem.velocityX,
              velocityY: elem.velocityY
            }
            resolve(params)
          })
        }))
      }

      random = (min,max) => {
        return Math.random()*(max - min) + min
      }

      ifCross = (x,y, velocityX, velocityY) => {
        if (x > this.state.screenWidth){
          x = this.state.screenWidth
          velocityX = - velocityX
        }

        if (x < 0){
          x = 0
          velocityX = - velocityX
        }

        if (y > this.state.screenHeight){
          y = this.state.screenHeight
          velocityY = - velocityY
        }

        if (y < 0){
          y = 0
          velocityY = - velocityY
        }

        return {x:x, y:y, velocityX:velocityX, velocityY:velocityY }
      }

      update = () => {
        Promise.all(this.updateCoordinates()).then((paramArray) =>{
          //here is the problem
          // this.state.ctx.clearRect(0,0,this.state.screenWidth, this.state.screenHeight)
          this.setState({
            parameters: paramArray,
          });
          window.requestAnimationFrame(this.update)
        })
      }

      render(){
        return(
          <FogDiv>
            <canvas width={this.state.screenWidth} height={this.state.screenHeight} ref = {this.canvas} >
              {this.state.ctx && (
                <CanvasContext.Provider value = {this.state.ctx}>
                  {this.state.parameters.map(param =>(
                    <FogPiece
                    x = {param.x}
                    y = {param.y}
                    />  
                  ))}
                </CanvasContext.Provider>
              )}
            </canvas>
          </FogDiv>
        )
      }
    }


    export default Fog;
    export {
      CanvasContext
    }

第二个:

    import React from 'react';
    import styled from 'styled-components';
    import {CanvasContext} from './Fog.jsx';

    class FogPiece extends React.Component{
      constructor(props){
        super(props);
        this.state = {
          image:'https://media.istockphoto.com/vectors/sample-red-square-grunge-textured-isolated-stamp-vector-id471401412',
        }
      }

      random(min,max){
        return Math.random()*(max - min) + min
      }

      render(){
        return(
          <CanvasContext.Consumer>
            {ctx => {
              console.log("x", "y", this.props)
              const img = new Image();
              img.src = this.state.image;
              img.onload = () => {
                ctx.drawImage(img,
                  this.props.x,
                  this.props.y,
                  40,
                  40)
              }
            }}
          </CanvasContext.Consumer>
        )
      }
    }

    export default FogPiece;

标签: javascriptreactjs

解决方案


推荐阅读