如何在 React Three Fiber / ThreeJs 上交换元素
how to swap elements on React Three Fiber / ThreeJs
我有这个 Card 组件,单击它会激活并展开该块。想点击一个然后另一个他们交换位置。
类似于:
// Initial Board
1,1,1,1,
2,2,2,2,
3,3,3,3,
4,4,4,4,
并且不允许在线相同的号码。行、列或主对角线。
完成订购块,如:
// win condition for Board
1, 2, 3, 4,
4, 3, 2, 1,
2, 1, 4, 3,
3, 4, 1, 2,
// the Card component
const Card = ({locale, args, color, speed}) => {
const mesh = useRef(null)
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
// expand state of the mesh. change size on click event
const [expand, setExpand] = useState(false);
const props = useSpring({
scale: expand ? [1.4, 1.4, 1.4]: [1,1,1],
})
return (
<a.mesh
onClick={() => setExpand(!expand)}
scale={props.scale}
castShadow
position={locale}
ref={mesh}>
<boxBufferGeometry attach='geometry' args={args} />
<MeshWobbleMaterial attach='material' color={color} speed={speed} factor={0.6} />
</a.mesh>
)
}
// its rendering inside Canvas from react-three-fiber
<Card locale={[-2, 1, -2]} color={'navy'} speed={6} />
<Card locale={[0, 1, -2]} color={'navy'} speed={6} />
<Card locale={[2, 1, -2]} color={'navy'} speed={6} />
<Card locale={[4, 1, -2]} color={'navy'} speed={6} />
<Card locale={[-2, 3, -2]} color={'teal'} speed={3} />
<Card locale={[0, 3, -2]} color={'teal'} speed={3} />
<Card locale={[2, 3, -2]} color={'teal'} speed={3} />
<Card locale={[4, 3, -2]} color={'teal'} speed={3} />
<Card locale={[-2, 5, -2]} color={'blue'} speed={9} />
<Card locale={[0, 5, -2]} color={'blue'} speed={9} />
<Card locale={[2, 5, -2]} color={'blue'} speed={9} />
<Card locale={[4, 5, -2]} color={'blue'} speed={9} />
<Card locale={[-2, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[0, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[2, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[4, -1, -2]} color={'aqua'} speed={2} />
github link 在这里:https://github.com/iagokrt/board-game-threejs
我正在为董事会想出一个愚蠢的逻辑。
这个问题比Whosebug的标准答案复杂得多,所以我只回答了一部分。动画部分对我来说是最有趣的,所以我解决了那个问题。
如果您想交换棋盘上的立方体,您必须根据它们的 x,y 位置设置动画。所以我将 x,y 坐标添加到 useSpring,它将使用语言环境 属性。您必须在要在网格位置 属性.
中使用它们的位置添加插值函数
const Card = ({ locale, args, color, speed }) => {
const mesh = useRef(null);
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
// expand state of the mesh. change size on click event
const [expand, setExpand] = useState(false);
const props = useSpring({
scale: expand ? [1.4, 1.4, 1.4] : [1, 1, 1],
xy: [locale[0], locale[1]]
});
return (
<a.mesh
onClick={() => setExpand(!expand)}
scale={props.scale}
castShadow
position={props.xy.interpolate((x, y) => [x, y, locale[2]])}
ref={mesh}
>
<boxBufferGeometry attach="geometry" args={args} />
<MeshWobbleMaterial
attach="material"
color={color}
speed={speed}
factor={0.6}
/>
</a.mesh>
);
};
这样,如果您更改 Card 组件的语言环境 属性,那么它将为新位置设置动画。
我创建了一个小例子。我在计时器中更改了区域设置,您可以看到它与动画交换。
https://codesandbox.io/s/react-tree-fiber-board-5mbns?file=/src/App.js
我有这个 Card 组件,单击它会激活并展开该块。想点击一个然后另一个他们交换位置。 类似于:
// Initial Board
1,1,1,1,
2,2,2,2,
3,3,3,3,
4,4,4,4,
并且不允许在线相同的号码。行、列或主对角线。 完成订购块,如:
// win condition for Board
1, 2, 3, 4,
4, 3, 2, 1,
2, 1, 4, 3,
3, 4, 1, 2,
// the Card component
const Card = ({locale, args, color, speed}) => {
const mesh = useRef(null)
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
// expand state of the mesh. change size on click event
const [expand, setExpand] = useState(false);
const props = useSpring({
scale: expand ? [1.4, 1.4, 1.4]: [1,1,1],
})
return (
<a.mesh
onClick={() => setExpand(!expand)}
scale={props.scale}
castShadow
position={locale}
ref={mesh}>
<boxBufferGeometry attach='geometry' args={args} />
<MeshWobbleMaterial attach='material' color={color} speed={speed} factor={0.6} />
</a.mesh>
)
}
// its rendering inside Canvas from react-three-fiber
<Card locale={[-2, 1, -2]} color={'navy'} speed={6} />
<Card locale={[0, 1, -2]} color={'navy'} speed={6} />
<Card locale={[2, 1, -2]} color={'navy'} speed={6} />
<Card locale={[4, 1, -2]} color={'navy'} speed={6} />
<Card locale={[-2, 3, -2]} color={'teal'} speed={3} />
<Card locale={[0, 3, -2]} color={'teal'} speed={3} />
<Card locale={[2, 3, -2]} color={'teal'} speed={3} />
<Card locale={[4, 3, -2]} color={'teal'} speed={3} />
<Card locale={[-2, 5, -2]} color={'blue'} speed={9} />
<Card locale={[0, 5, -2]} color={'blue'} speed={9} />
<Card locale={[2, 5, -2]} color={'blue'} speed={9} />
<Card locale={[4, 5, -2]} color={'blue'} speed={9} />
<Card locale={[-2, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[0, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[2, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[4, -1, -2]} color={'aqua'} speed={2} />
github link 在这里:https://github.com/iagokrt/board-game-threejs 我正在为董事会想出一个愚蠢的逻辑。
这个问题比Whosebug的标准答案复杂得多,所以我只回答了一部分。动画部分对我来说是最有趣的,所以我解决了那个问题。
如果您想交换棋盘上的立方体,您必须根据它们的 x,y 位置设置动画。所以我将 x,y 坐标添加到 useSpring,它将使用语言环境 属性。您必须在要在网格位置 属性.
中使用它们的位置添加插值函数const Card = ({ locale, args, color, speed }) => {
const mesh = useRef(null);
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
// expand state of the mesh. change size on click event
const [expand, setExpand] = useState(false);
const props = useSpring({
scale: expand ? [1.4, 1.4, 1.4] : [1, 1, 1],
xy: [locale[0], locale[1]]
});
return (
<a.mesh
onClick={() => setExpand(!expand)}
scale={props.scale}
castShadow
position={props.xy.interpolate((x, y) => [x, y, locale[2]])}
ref={mesh}
>
<boxBufferGeometry attach="geometry" args={args} />
<MeshWobbleMaterial
attach="material"
color={color}
speed={speed}
factor={0.6}
/>
</a.mesh>
);
};
这样,如果您更改 Card 组件的语言环境 属性,那么它将为新位置设置动画。
我创建了一个小例子。我在计时器中更改了区域设置,您可以看到它与动画交换。
https://codesandbox.io/s/react-tree-fiber-board-5mbns?file=/src/App.js