Javascript 在Reactjs中以多步骤形式切换页面时,如何保留修改过的画布?
我是一个初学者,最近开始学习React,这是我第一次尝试使用Canvas 我的目标是有一个多步骤的形式,其中一个步骤包括画布。画布的用途是允许用户在图像上标记点 为了做到这一点,我已经改编并引用了这个例子供自己使用 对于我的代码,它的工作原理是在画布挂载时首先绘制背景图像(useffect()),然后用户单击他想要放置点的位置。onClick函数获取整个页面的坐标,并将其存储在本地状态(坐标)。onClick函数还获取画布的坐标,并将其存储在父状态(parentCoordinates)中,该状态从父状态传递到画布。最后,它在相对于页面的坐标上绘制一个点 拥有父状态(parentCoordinates)和本地状态(coordinate)的原因是,我希望捕获父状态中画布的坐标,以便进行后端处理,而本地坐标用于视觉目的,以便点显示在画布上 我现在面临的主要问题是,一旦标记了位置,如果用户单击下一节旁边的位置并单击“返回”返回画布,则以前标记的位置都将消失。但是父状态数组(parentCoordinates)仍然包含这些坐标 在第一个useffect中(仅在画布装载时运行),我尝试使用forEach方法迭代父状态中存储的坐标(parentCoordinates)。在该方法中,我对每个坐标进行了一些修正,使其值现在相对于整个页面,然后在生成的坐标上绘制点。返回画布时,控制台在forEach方法中记录应该绘制点的正确坐标,但画布上没有点 背景图像位于点上方是否有问题?还是我处理和使用美国的方式有问题 下面是Canvas组件的代码Javascript 在Reactjs中以多步骤形式切换页面时,如何保留修改过的画布?,javascript,reactjs,canvas,Javascript,Reactjs,Canvas,我是一个初学者,最近开始学习React,这是我第一次尝试使用Canvas 我的目标是有一个多步骤的形式,其中一个步骤包括画布。画布的用途是允许用户在图像上标记点 为了做到这一点,我已经改编并引用了这个例子供自己使用 对于我的代码,它的工作原理是在画布挂载时首先绘制背景图像(useffect()),然后用户单击他想要放置点的位置。onClick函数获取整个页面的坐标,并将其存储在本地状态(坐标)。onClick函数还获取画布的坐标,并将其存储在父状态(parentCoordinates)中,该状态
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