ควบคุมการลาก (Implementing Drag Controls)

ควบคุมการลาก three.js (Implementing Drag Controls)

drag คือการคลิกที่วัตถุค้างเอาไว้ แล้วลากไปวางยังพื้นที่ ที่ต้องการ โดยการลากนั้นวัตถุจะเคลื่อนที่ตามมาส์ไปด้วย จนกว่าเราจะปล่อยมือจากการคลิกเมาส์ วัตถูก็จะมาอยู่ที่ตำแหน่งใหม่ ซึ่งการ drag จะช่วยให้เราสามารถย้ายวัตถุได้อย่างอิสระตามต้องการ

ข้อกำหนดเบื้องต้น


ข้อกำหนดสำหรับบทความนี้คือ คุณควรได้ทำตามบทความ  จัดระเบียบโค้ดด้วย .JSX มาก่อน

สร้างไฟล์ Draggable.jsx


สร้างไฟล์ Draggable.jsx ภายในโฟลเดอร์ components เขียนโค้ดดังนี้

เราจำเป็นต้องนำเข้าการควบคุมการลาก DragControls จากแหล่งนี้ลงที่นี่ 3 ตัวอย่างเช่น jsm การควบคุมสแลช (slash controls) , การควบคุมการลากสแลช (slash drag controls) แล้วล้างข้อมูลการลากนี้ ให้เราทำส่วนประกอบ dragonball ให้ถูกต้อง

import {
    DragControls
} from 'three/examples/jsm/controls/DragControls';


และเช่นเดียวกับการควบคุมวงโคจรจะต้องสร้างฟังก์ชันควบคุมการลาก Draggable แล้วมานำเข้าส่วนขยายจาก react-three-fiber แล้วขยาย extend การควบคุม ตกลง ตอนนี้คอนสตรัคเตอร์ของการควบคุมการลากใช้อ็อบเจ็กต์ ซึ่งเป็นอาร์เรย์ของอ็อบเจกต์ dragonball 3D กล้องและองค์ประกอบ dom วัตถุวัตถุในวินาที

นำเข้า import { useThree, extend } from ‘react-three-fiber’; แล้วดึงกล้องและ const { camera, gl } นั้นจะมีองค์ประกอบ DOM แล้วเราก็แค่ส่งออกส่วนประกอบนี้ export default Draggable;

import { useThree, extend } from 'react-three-fiber';

const Draggable = props => {
      const { camera, gl } = useThree(); 

      return(

      )
{

export default Draggable;

โค้ด

import {
    DragControls
} from 'three/examples/jsm/controls/DragControls';
import { useRef, useEffect, useState } from 'react';
import { useThree, extend } from 'react-three-fiber';
extend({ DragControls });

const Draggable = props => {
    const groupRef = useRef();
    const [children, setChildren] = useState([])
    const { camera, gl } = useThree();
    useEffect(() => {
        setChildren(groupRef.current.children)
    }, [])
    return (
        <group ref={groupRef}>
            <dragControls
                args={[children, camera, gl.domElement]}
            />
            {props.children}
        </group>
    )
}

export default Draggable;



เพิ่มโค้ดนำเข้า Draggable ที่ไฟล์ App.js

import Draggable from './components/Draggable';

เพิ่มโค้ด < Draggable> </Draggable> ครอบ Suspense

หยุดการทำงาน <Orbit />

{/* <Orbit /> */}

โค้ด ไฟล์ App.js

import './App.css';
import {
  Canvas, useFrame
} from 'react-three-fiber';
import { Suspense } from 'react';
import Orbit from './components/Orbit';
import Box from './components/Box';
import Background from './components/Background';
import Floor from './components/Floor';
import Bulb from './components/Bulb';
import Draggable from './components/Draggable';
import ColorPicker from './components/ColorPicker';

function App() {


  return (
    <div style={{ height: '100vh', width: '100vw' }}>
      < ColorPicker />
      <Canvas
        shadowMap
        style={{ background: 'black' }}
        camera={{ position: [7, 7, 7] }}
      >
        <ambientLight intensity={0.2} />
        <Bulb position={[0, 3, 0]} />
        {/* <Orbit /> */}
        <axesHelper args={[5]} />
        < Draggable>
          <Suspense fallback={null}>
            <Box position={[-4, 1, 0]} />
          </Suspense>
          <Suspense fallback={null}>
            <Box position={[4, 1, 0]} />
          </Suspense>
        </Draggable>
        <Suspense fallback={null}>
          <Background />
        </Suspense>
        <Floor position={[0, -0.5, 0]} />
      </Canvas>
    </div>
  );
}

export default App;


ทดสอบ ย้ายวัตถุได้อย่างอิสระตามต้องการ

addEventListener

addEventListener() วิธีการช่วยให้คุณเพิ่มฟังเหตุการณ์บนวัตถุ DOM HTML ใด ๆ เช่นองค์ประกอบ HTML, เอกสาร HTML วัตถุหน้าต่างหรือวัตถุอื่น ๆ ที่สนับสนุนการจัดกิจกรรม


ที่ไฟล์ Draggable.jsx เพิ่มโค้ด const controlsRef = useRef();

const controlsRef = useRef();

ทำการเพิ่ม event listenter (ตัวฟังเหตุการณ์) โดยคำสั่ง addEventListener() ซึ่งในที่นี่เราฟังเหตุการณ์คลิกเพียงอย่างเดียวจึงใส่ค่า ‘hoveron’ ลงไป

        controlsRef.current.addEventListener('hoveron',
            e => console.log('you hovered')
        )

เพิ่มโค้ด ref={controlsRef}

ref={controlsRef}

ที่ไฟล์ App.js เปิดการทำงาน <Orbit />

hover on even เมื่อเมาส์เลื่อนไปมา กล่องหรือวัตถุจะมีขนาดใหญ่ขึ้น

ไฟล์ Draggable.jsx เพิ่ม scene

    useEffect(() => {
        setChildren(groupRef.current.children)     
    }, [])

    useEffect(() => {
        controlsRef.current.addEventListener(
            'hoveron',
            e => scene.orbitControls.enabled = false
        )      
    }, [children])

ทดสอบ เมื่อเมาส์เลื่อนไปมา กล่องหรือวัตถุจะมีขนาดใหญ่ขึ้น และ ย้ายวัตถุได้อย่างอิสระตามต้องการ

ผลลัพธ์การทำงาน


โค้ดไฟล์ Draggable.jsx 

import {
    DragControls
} from 'three/examples/jsm/controls/DragControls';
import { useRef, useEffect, useState } from 'react';
import { useThree, extend } from 'react-three-fiber';
extend({ DragControls });

const Draggable = props => {
    const groupRef = useRef();
    const controlsRef = useRef();
    const [children, setChildren] = useState([])
    const { camera, gl, scene } = useThree();

    useEffect(() => {
        setChildren(groupRef.current.children)     
    }, [])

    useEffect(() => {
        controlsRef.current.addEventListener(
            'hoveron',
            e => scene.orbitControls.enabled = false
        )      
    }, [children])


    return (
        <group ref={groupRef}>
            <dragControls
                ref={controlsRef}
                args={[children, camera, gl.domElement]}
            />
            {props.children}
        </group>
    )
}

export default Draggable;


ดูผ่านเว็บไซต์ได้ที่

Leave a Reply

Your email address will not be published.