【问题标题】:React - Canvas rendering, seperate draw logic & input logicReact - 画布渲染,单独的绘制逻辑和输入逻辑
【发布时间】:2021-02-21 07:58:24
【问题描述】:

对不起,如果在我搜索之前有人问过这个问题并且找不到任何东西。

我目前正在创建一个反应应用程序,需要将细节渲染到画布上。该程序本身将是一个地图创建程序。目前我正在使用画布上下文绘制到画布上,尽管我最终想将其更改为 konva 或 ocanvas。

我目前的问题是我正在努力寻找一种分离所有内容的好方法,因为画布需要处理大量鼠标事件、渲染数据、“工具”选择和一些数据操作。理想情况下,我想将此代码分离到一个单独的单元中,这样所有代码都不在一个地方。 IE:渲染逻辑、输入逻辑等……我该怎么做呢?请记住,地图可能需要传递到子单元中。

以下是我目前拥有的代码的 sn-p,我删除了一些细粒度的细节,但保留了我所有的鼠标代码和值:

import React, {
  useState,
  useEffect,
  Fragment
} from "react";
import {
  useCanvas
} from './canvashooks/CanvasHooks.js';

const Canvas = ({map}) => {

  //far to many variables, is there a better way of doing this?
  const [offX, setOffX] = useState(0);
  const [offY, setOffY] = useState(0);
  const [scale, setScale] = useState(1.0);
  const [mouseDown, setMouseDown] = useState(false);
  const [mouseUp, setMouseUp] = useState(false);
  const [initialX, setInitialX] = useState(0);
  const [initialY, setInitialY] = useState(0);
  const [offXStart, setOffXStart] = useState(0);
  const [offYStart, setOffYStart] = useState(0);


  const canvasRef = React.useRef(null);

  const draw = ctx => {
    console.log(map)
    ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight)

    //draw the buildings:
    if (map.Buildings === undefined) {
      return;
    }
    //draw data from the map
  }
  useEffect(() => {

    const canvas = canvasRef.current
    const context = canvas.getContext('2d')
    draw(context)
  }, [draw])

  const handleCanvasClick = (event) => {

  }

  const handleCanvasMouseDown = (event) => {
    let initialX = event.pageX;
    let initialY = event.pageY;
    setMouseDown(true);
    setInitialX(initialX);
    setInitialY(initialY);
    setOffXStart(offX);
    setOffYStart(offY);
  }

  const handleCanvasMouseUp = (event) => {
    console.log('Canvas Mouse Up');
    setMouseDown(false);
  }

  const handleCanvasDrag = (event) => {
    if (!mouseDown) {
      return;
    }
    let diffX = event.pageX - initialX;
    let diffY = event.pageY - initialY;

    let offX = offXStart + diffX;
    let offY = offXStart + diffY;
    setOffX(offX);
    setOffY(offY);
  }

  const handleCanvasMouseWheel = (event) => {
    if (event.deltaY < 0) {
      setScale(scale + 0.1)
    }

    if (event.deltaY > 0) {
      setScale(scale - 0.1)
    }
  }



  return ( 
    <div class = "box canvasContainer" >
    <canvas id = "renderCanvas"ref = {canvasRef} width = "1000" height = "1000" 
    onWheel = {handleCanvasMouseWheel} 
    onMouseMove = {handleCanvasDrag}
    onMouseUp = {handleCanvasMouseUp}
    onMouseDown = {handleCanvasMouseDown} 
    onClick = {handleCanvasClick}> Your browser doesnt support the canvas < /canvas>
    </div>
  );
};

export default Canvas;

【问题讨论】:

    标签: javascript reactjs html5-canvas


    【解决方案1】:

    经过一番思考和思考,我想出了以下解决方案:

    在画布类中创建并初始化“工具”列表,该初始化的一部分是提供回调函数列表以更新状态 IE:渲染比例和偏移量。画布内的事件函数调用所选工具内的事件。

    这个方法非常可扩展,因为任何函数都可以添加到回调中,这意味着可以对工具进行编码以做任何事情。我还在最后调用的工具中添加了一个渲染函数,可以根据工具将自定义元素渲染到屏幕上。

    【讨论】:

      猜你喜欢
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 2013-04-28
      • 2021-03-18
      相关资源
      最近更新 更多