"use client";
import { EntityType, World } from "@/types/World";
import React, { useState } from "react";
import dynamic from "next/dynamic";
;
let RayTracingPage = dynamic(()=>import("./RayTracingCanvas"));
let initialMovements = [0,0,0,0,0]
export default async function Home() {
const [world, setWorld] = useState<World>({
lights: [
{
x: -30,
y: -10,
z: 20,
},
],
camera: {
point: {
x: 0,
y: 1.8,
z: 10,
},
fov: 45,
direction: {
x: 0,
y: 3,
z: 0,
},
},
entities: [
{
type: EntityType.Sphere,
point: {
x: 0,
y: 3.5,
z: -3,
},
color: { // 0=> purple
r: 155,
g: 50,
b: 155,
a: 255
},
specular: 0.2,
lambert: 0.7,
ambient: 0.1, p0:0,
radius: 1,
speed: 0.1
},
{
type: EntityType.Sphere,
point: {
x: -4,
y: 3.5,
z: -1,
},
color: { // 1 => red
r: 155,
g: 25,
b: 40,
a:255
},
specular: 0.1,
lambert: 0.9,
ambient: 0.0,
radius: 0.2, p0:0,
speed: 0.2
},
{
type: EntityType.Sphere,
point: { // 2 => green
x: -7,
y: 3.5,
z: -10,
},
color: {
r: 34,
g: 255,
b: 34,
a: 255
},
specular: 0.2,
lambert: 0.7,
ambient: 0.1,
radius: 0.1, p0:0,
speed: 0.3
},
{
type: EntityType.Sphere,
point: {
x: -8,
y: 3.5,
z: -5,
},
color: { // 3 => dark blue
r: 34,
g: 13,
b: 134,
a: 255
},
specular: 0.2,
lambert: 0.7,
ambient: 0.1,
radius: 0.3, p0:0,
speed: 0.4
},
{
type: EntityType.Sphere,
point: {
x: -14,
y: 3.5,
z: -3,
},
color: { // 4 => yellow
r: 230,
g: 230,
b: 21,
a: 255
},
specular: 0.2,
lambert: 0.7,
ambient: 0.1,
radius: 0.5,
p0:0,
speed: 0.5
},
]
});
const [movements,setMovements] = useState<number[]>(initialMovements)
const motionUpdate:()=> World =()=>{
let newMovements:number[]=[]
for(let i = 0; i < movements.length; i++){
newMovements.push(movements[i] + world.entities[i].speed)
}
console.log(movements)
setMovements(newMovements);
world.entities[0].point.x = Math.sin(movements[0]);
world.entities[0].point.z = Math.cos(movements[0]);
world.entities[1].point.x = Math.sin(movements[1]) * 2;
world.entities[1].point.z = -4 + Math.cos(movements[1]) * 2;
world.entities[2].point.x = Math.sin(movements[2]) * 3;
world.entities[2].point.z = -3 + Math.cos(movements[2]) * 3;
world.entities[2].point.y = 3.5 + Math.sin(movements[2]) * 3;
world.entities[3].point.x = Math.sin(movements[3]) * 2;
world.entities[3].point.z = -3 + Math.cos(movements[3]) * 2;
world.entities[4].point.x = Math.sin(movements[4]) * 4;
world.entities[4].point.z = -3 + Math.cos(movements[4]) * 4;
world.entities[4].point.y = 3.5 + Math.cos(movements[4]) * 4;
return world
}
return (
<div>
<CanvasPage width={1280} height={720} AnimationCallback={motionUpdate}></CanvasPage>
</div>
)
}
我的React状态没有每次更新,动作被设置回默认值,任何想法为什么会发生这种情况
const motionUpdate:()=> World =useCallback(()=>{
setWorld(world=>{
const newWorld = { ...world };
setMovements((moves)=>{
let newMovements:number[]=[]
for(let i = 0; i < moves.length; i++){
newMovements.push(moves[i] + world.entities[i].speed)
}
return newMovements
});
newWorld.entities[0].point.x = Math.sin(movements[0]);
newWorld.entities[0].point.z = Math.cos(movements[0]);
newWorld.entities[1].point.x = Math.sin(movements[1]) * 2;
newWorld.entities[1].point.z = -4 + Math.cos(movements[1]) * 2;
newWorld.entities[2].point.x = Math.sin(movements[2]) * 3;
newWorld.entities[2].point.z = -3 + Math.cos(movements[2]) * 3;
newWorld.entities[2].point.y = 3.5 + Math.sin(movements[2]) * 3;
newWorld.entities[3].point.x = Math.sin(movements[3]) * 2;
newWorld.entities[3].point.z = -3 + Math.cos(movements[3]) * 2;
newWorld.entities[4].point.x = Math.sin(movements[4]) * 4;
newWorld.entities[4].point.z = -3 + Math.cos(movements[4]) * 4;
newWorld.entities[4].point.y = 3.5 + Math.cos(movements[4]) * 4;
return newWorld
})
return world
},[movements, world])
尝试用上面的函数更新我的代码,画布仍然没有更新,我假设这是因为太多的调用motionUpdate函数阻止状态更新,也许我需要使用reduce函数,什么是最好的解决方案?
1条答案
按热度按时间wxclj1h51#
请正确格式化您的代码,因为有一个孤独的分号在那里。此外,您直接改变了
world
状态,而不是调用setWorld
。在你的函数中,你可以做如下的事情:
还可以考虑将你的函数 Package 在一个
useCallback
中,否则它将在每次渲染时重新创建。注意
没有必要一遍又一遍地重复同一句话。