Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Reactjs中以多步骤形式切换页面时,如何保留修改过的画布?_Javascript_Reactjs_Canvas - Fatal编程技术网

Javascript 在Reactjs中以多步骤形式切换页面时,如何保留修改过的画布?

Javascript 在Reactjs中以多步骤形式切换页面时,如何保留修改过的画布?,javascript,reactjs,canvas,Javascript,Reactjs,Canvas,我是一个初学者,最近开始学习React,这是我第一次尝试使用Canvas 我的目标是有一个多步骤的形式,其中一个步骤包括画布。画布的用途是允许用户在图像上标记点 为了做到这一点,我已经改编并引用了这个例子供自己使用 对于我的代码,它的工作原理是在画布挂载时首先绘制背景图像(useffect()),然后用户单击他想要放置点的位置。onClick函数获取整个页面的坐标,并将其存储在本地状态(坐标)。onClick函数还获取画布的坐标,并将其存储在父状态(parentCoordinates)中,该状态

我是一个初学者,最近开始学习React,这是我第一次尝试使用Canvas

我的目标是有一个多步骤的形式,其中一个步骤包括画布。画布的用途是允许用户在图像上标记点

为了做到这一点,我已经改编并引用了这个例子供自己使用

对于我的代码,它的工作原理是在画布挂载时首先绘制背景图像(useffect()),然后用户单击他想要放置点的位置。onClick函数获取整个页面的坐标,并将其存储在本地状态(坐标)。onClick函数还获取画布的坐标,并将其存储在父状态(parentCoordinates)中,该状态从父状态传递到画布。最后,它在相对于页面的坐标上绘制一个点

拥有父状态(parentCoordinates)和本地状态(coordinate)的原因是,我希望捕获父状态中画布的坐标,以便进行后端处理,而本地坐标用于视觉目的,以便点显示在画布上

我现在面临的主要问题是,一旦标记了位置,如果用户单击下一节旁边的位置并单击“返回”返回画布,则以前标记的位置都将消失。但是父状态数组(parentCoordinates)仍然包含这些坐标

在第一个useffect中(仅在画布装载时运行),我尝试使用forEach方法迭代父状态中存储的坐标(parentCoordinates)。在该方法中,我对每个坐标进行了一些修正,使其值现在相对于整个页面,然后在生成的坐标上绘制点。返回画布时,控制台在forEach方法中记录应该绘制点的正确坐标,但画布上没有点

背景图像位于点上方是否有问题?还是我处理和使用美国的方式有问题

下面是Canvas组件的代码

import React, { useEffect, useState, useRef } from 'react'
import picture from '../../picture.png'

function Canvas(props) {

    const { parentCoordinates, setParentCoordinates, handleCanvasBack, handleCanvasNext } = props;

    const canvas = document.getElementById('canvas')

    const canvasRef = useRef(null);

    const [coordinates, setCoordinates] = useState([]);

    useEffect(() => {
        const canvasObj = canvasRef.current;
        const ctx = canvasObj.getContext('2d');
        console.log('canvas is mounting')
        let drawing = new Image();
        drawing.src = picture
        drawing.onload = function () {
            ctx.drawImage(picture, 0, 0, 1050, 490);
        };
        painCoordinates.forEach((coordinate) => {
            var rect = document.getElementById('canvas').getBoundingClientRect()
            coordinate.x = coordinate.x + rect.left
            console.log(coordinate.x)
            coordinate.y = coordinate.y + rect.top
            console.log(coordinate.y)
            draw(ctx, coordinate)
        });
    }, []);

    function draw(ctx, location) {
        console.log("Cross drawn on the coordinate: ", location)
        var rect = document.getElementById('canvas').getBoundingClientRect()
        ctx.save();
        ctx.beginPath();
        ctx.arc(location.x - rect.left, location.y - rect.top, 2, 0, 2 * Math.PI, true);
        ctx.fillStyle = "#FF0000";
        ctx.fill();
        ctx.restore();
    };

    const handleCanvasClick = (event) => {

        // on each click get current mouse location wrt to whole page
        const localCoord = { x: event.clientX, y: event.clientY };

        // get current mouse location wrt to canvas
        var rect = document.getElementById('canvas').getBoundingClientRect()
        const parentCoord = { x: event.clientX - rect.left, y: event.clientY - rect.top }

        // add the newest mouse location (page) to an array in local state 
        setCoordinates(coordinates => [...coordinates, localCoord])

        // add the newest mouse location (Canvas) to an array in parent state 
        setParentCoordinates(parentCoordinates => [...parentCoordinates, parentCoord])

        console.log("Local Coord State is now", coordinates)
        console.log("Parent Coord State is now", parentCoordinates)

        const canvasObj = canvasRef.current;
        const ctx = canvasObj.getContext('2d');
        draw(ctx, localCoord)

    };

    return (
        <div>
            <canvas
                id='canvas'
                ref={canvasRef}
                style={{ border: '1px solid black' }}
                width='630'
                height='450'
                onClick={handleCanvasClick} />
            <div>
                <Button onClick={() => { handleCanvasBack(parentCoordinates) }}>Back</Button>
                <Button variant='contained' color='primary' onClick={() => handleCanvasNext(parentCoordinates)}>Next</Button>
            </div>
        </div >

    )
}

export default Canvas

//To handle stepping and navigation of multi-page form and storage of states across the pages

import React, { useState } from 'react'
import Page1 from './page1'
import Canvas from './canvas'
import Page3 from './page3'

function Main(props) {

    const [parentCoordinates, setParentCoordinates] = useState([]);
    
    const steps = [
        'Page 1',
        'Canvas',
        'Page 3',
    ]

    const [activeStep, setActiveStep] = useState(0)

    const handleStep = (step) => () => {
        setActiveStep(step)
    }

    const handleNext = () => {
        setActiveStep(activeStep + 1);
    }


    const handleBack = () => {
        setActiveStep(activeStep - 1)
    }

    const handleCanvasNext = (parentCoordinates) => {
        console.log("Parent Coordinates array is", parentCoordinates)
        setActiveStep(activeStep + 1);
    }


    const handleCanvasBack = (parentCoordinates) => {
        console.log("Parent Coordinates array is", parentCoordinates)
        setActiveStep(activeStep - 1)
    }

 
    const renderStepContent = () => {
        switch (activeStep) {
            case 0:
                return <Page1
                          handleBack={handleBack} 
                          handleNext={handleNext} />;
            case 1:
                return <Canvas 
                          handleCanvasBack={handleCanvasBack} 
                          handleCanvasNext={handleCanvasNext} 
                          parentCoordinates={parentCoordinates} 
                          setParentCoordinates={setParentCoordinates} 
                         />;
            case 2:
                return <Page3 
                          handleBack={handleBack} 
                          handleNext={handleNext}/>
            default:
                return <div>Page Not Found</div>
        }
    }

    return (
       <div>
         {renderStepContent(activeStep)}
       </div>
    )
}

export default Main
import React,{useffect,useState,useRef}来自“React”
从“../../picture.png”导入图片
功能画布(道具){
const{parentCoordinates,setParentCoordinates,handleCanvasBack,handleCanvasNext}=props;
const canvas=document.getElementById('canvas')
const canvasRef=useRef(null);
const[coordinates,setCoordinates]=useState([]);
useffect(()=>{
const canvasObj=canvasRef.current;
const ctx=canvasObj.getContext('2d');
console.log('画布正在装载')
让绘图=新图像();
drawing.src=图片
drawing.onload=函数(){
ctx.drawImage(图片,0,0,1050,490);
};
painCoordinates.forEach((坐标)=>{
var rect=document.getElementById('canvas').getBoundingClientRect()
坐标x=坐标x+矩形左
console.log(coordinate.x)
coordinate.y=coordinate.y+rect.top
console.log(坐标y)
绘制(ctx,坐标)
});
}, []);
功能图(ctx,位置){
console.log(“在坐标:,位置上交叉绘制”)
var rect=document.getElementById('canvas').getBoundingClientRect()
ctx.save();
ctx.beginPath();
弧(location.x-rect.left,location.y-rect.top,2,0,2*Math.PI,true);
ctx.fillStyle=“#FF0000”;
ctx.fill();
ctx.restore();
};
常量handleCanvasClick=(事件)=>{
//每次单击时,将当前鼠标位置写入整个页面
const localCoord={x:event.clientX,y:event.clientY};
//获取当前鼠标位置wrt到画布
var rect=document.getElementById('canvas').getBoundingClientRect()
const parentCoord={x:event.clientX-rect.left,y:event.clientY-rect.top}
//将最新的鼠标位置(页面)添加到本地状态的数组中
setCoordinates(坐标=>[…坐标,本地坐标])
//将最新的鼠标位置(画布)添加到父状态的数组中
setParentCoordinates(parentCoordinates=>[…parentCoordinates,parentCoord])
log(“本地坐标状态现在为”,坐标)
log(“父坐标状态现在为”,父坐标)
const canvasObj=canvasRef.current;
const ctx=canvasObj.getContext('2d');
绘图(ctx、localCoord)
};
返回(
{handleCanvasBack(parentCoordinates)}}>Back
handleCanvasNext(父坐标)}>Next
)
}
导出默认画布
下面是父组件的代码

import React, { useEffect, useState, useRef } from 'react'
import picture from '../../picture.png'

function Canvas(props) {

    const { parentCoordinates, setParentCoordinates, handleCanvasBack, handleCanvasNext } = props;

    const canvas = document.getElementById('canvas')

    const canvasRef = useRef(null);

    const [coordinates, setCoordinates] = useState([]);

    useEffect(() => {
        const canvasObj = canvasRef.current;
        const ctx = canvasObj.getContext('2d');
        console.log('canvas is mounting')
        let drawing = new Image();
        drawing.src = picture
        drawing.onload = function () {
            ctx.drawImage(picture, 0, 0, 1050, 490);
        };
        painCoordinates.forEach((coordinate) => {
            var rect = document.getElementById('canvas').getBoundingClientRect()
            coordinate.x = coordinate.x + rect.left
            console.log(coordinate.x)
            coordinate.y = coordinate.y + rect.top
            console.log(coordinate.y)
            draw(ctx, coordinate)
        });
    }, []);

    function draw(ctx, location) {
        console.log("Cross drawn on the coordinate: ", location)
        var rect = document.getElementById('canvas').getBoundingClientRect()
        ctx.save();
        ctx.beginPath();
        ctx.arc(location.x - rect.left, location.y - rect.top, 2, 0, 2 * Math.PI, true);
        ctx.fillStyle = "#FF0000";
        ctx.fill();
        ctx.restore();
    };

    const handleCanvasClick = (event) => {

        // on each click get current mouse location wrt to whole page
        const localCoord = { x: event.clientX, y: event.clientY };

        // get current mouse location wrt to canvas
        var rect = document.getElementById('canvas').getBoundingClientRect()
        const parentCoord = { x: event.clientX - rect.left, y: event.clientY - rect.top }

        // add the newest mouse location (page) to an array in local state 
        setCoordinates(coordinates => [...coordinates, localCoord])

        // add the newest mouse location (Canvas) to an array in parent state 
        setParentCoordinates(parentCoordinates => [...parentCoordinates, parentCoord])

        console.log("Local Coord State is now", coordinates)
        console.log("Parent Coord State is now", parentCoordinates)

        const canvasObj = canvasRef.current;
        const ctx = canvasObj.getContext('2d');
        draw(ctx, localCoord)

    };

    return (
        <div>
            <canvas
                id='canvas'
                ref={canvasRef}
                style={{ border: '1px solid black' }}
                width='630'
                height='450'
                onClick={handleCanvasClick} />
            <div>
                <Button onClick={() => { handleCanvasBack(parentCoordinates) }}>Back</Button>
                <Button variant='contained' color='primary' onClick={() => handleCanvasNext(parentCoordinates)}>Next</Button>
            </div>
        </div >

    )
}

export default Canvas

//To handle stepping and navigation of multi-page form and storage of states across the pages

import React, { useState } from 'react'
import Page1 from './page1'
import Canvas from './canvas'
import Page3 from './page3'

function Main(props) {

    const [parentCoordinates, setParentCoordinates] = useState([]);
    
    const steps = [
        'Page 1',
        'Canvas',
        'Page 3',
    ]

    const [activeStep, setActiveStep] = useState(0)

    const handleStep = (step) => () => {
        setActiveStep(step)
    }

    const handleNext = () => {
        setActiveStep(activeStep + 1);
    }


    const handleBack = () => {
        setActiveStep(activeStep - 1)
    }

    const handleCanvasNext = (parentCoordinates) => {
        console.log("Parent Coordinates array is", parentCoordinates)
        setActiveStep(activeStep + 1);
    }


    const handleCanvasBack = (parentCoordinates) => {
        console.log("Parent Coordinates array is", parentCoordinates)
        setActiveStep(activeStep - 1)
    }

 
    const renderStepContent = () => {
        switch (activeStep) {
            case 0:
                return <Page1
                          handleBack={handleBack} 
                          handleNext={handleNext} />;
            case 1:
                return <Canvas 
                          handleCanvasBack={handleCanvasBack} 
                          handleCanvasNext={handleCanvasNext} 
                          parentCoordinates={parentCoordinates} 
                          setParentCoordinates={setParentCoordinates} 
                         />;
            case 2:
                return <Page3 
                          handleBack={handleBack} 
                          handleNext={handleNext}/>
            default:
                return <div>Page Not Found</div>
        }
    }

    return (
       <div>
         {renderStepContent(activeStep)}
       </div>
    )
}

export default Main
//处理多页表单的步进和导航以及跨页状态存储
从“React”导入React,{useState}
从“./Page1”导入第1页
从“/Canvas”导入画布
从“./Page3”导入第3页
主功能(道具){
const[parentCoordinates,setParentCoordinates]=useState([]);
常数步长=[
“第1页”,
“画布”,
“第3页”,
]
常量[activeStep,setActiveStep]=useState(0)
常量handleStep=(步长)=>()=>{
设置活动步骤(步骤)
}
常量handleNext=()=>{
setActiveStep(activeStep+1);
}
常量把手=()=>{
setActiveStep(activeStep-1)
}
常量handleCanvasNext=(父坐标)=>{
log(“父坐标数组为”,父坐标)
setActiveStep(activeStep+1);
}
常量handleCanvasBack=(父坐标)=>{
log(“父坐标数组为”,parentCoordin