import { Canvas } from '@react-three/fiber';
import { OrbitControls, GizmoHelper, GizmoViewport } from '@react-three/drei';
import BasicShapes from './Shapes/BasicShapes';
import useStore from './Context';
import exportGLB from './exportGLB';
import { useRef } from 'react';

function App() {
  const { shapes } = useStore();
const sceneRef = useRef(null);


  // Sahneyi dışa aktarma fonksiyonu tetiklemek için bir buton kullanabilirsiniz
  const handleExport = () => {
    if(sceneRef.current){
      exportGLB(sceneRef.current);
    }
  };

  return (
    <>
      <button onClick={handleExport} style={{ position: 'absolute', zIndex: 1, top: 10, left: 10 }}>
        Export GLB
      </button>
      <Canvas
      onCreated={({scene})=>{
        sceneRef.current = scene;
      }}
        style={{
          position: 'absolute',
          left: 0,
          right: 0,
          top: 0,
          bottom: 0,
        }}
        onPointerMissed={() => useStore.getState().setSelectedObject(null)}
      >
        <ambientLight />
        <pointLight position={[10, 10, 10]} />
        <OrbitControls key={4354364} />
        <BasicShapes />
        <GizmoHelper>
          <GizmoViewport />
        </GizmoHelper>
      </Canvas>
    </>
  );
}

export default App;
______


import { useEffect } from 'react';
import BasicShape from '../components/BasicShape';
import useStore from "../Context";
import { v4 as uuidv4 } from 'uuid'; // Benzersiz ID'ler için

const BasicShapes = () => {
  const { shapes, addShape } = useStore();

  useEffect(() => {
    // Başlangıçta sahneye bazı şekiller ekleyin
    if (shapes.length === 0) {
      addShape({ id: uuidv4(), type: 'box', position: [0, 0, 0], material: { color: 'orange' } });
      addShape({ id: uuidv4(), type: 'sphere', position: [2, 0, 0], material: { color: 'blue' } });
      // İstediğiniz kadar başlangıç şekli ekleyebilirsiniz
    }
  }, [shapes.length, addShape]);

  return (
    <>
      {shapes.map(shape => (
        <BasicShape
          key={shape.id}
          id={shape.id}
          type={shape.type}
          position={shape.position}
          material={shape.material}
        />
      ))}
    </>
  );
};

export default BasicShapes;
_______


import { Html, TransformControls } from "@react-three/drei";
import ShapeEditor from '../Shapes/ShapeEditor';
import useStore from "../Context";
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';

const BasicShape = ({ id, type, position, material }) => {
  const { selectedObject, setSelectedObject, updateShape,onEditing } = useStore();
  const isSelected = selectedObject?.id === id;
  
  const meshRef = useRef();

  const handleSelect = (e) => {
    e.stopPropagation();
    console.log(id,selectedObject?.id)
    if(isFinite(onEditing) && !onEditing){
    setSelectedObject({ id, type, position, material });
}
  };

  // Eğer gerektiğinde ek animasyon veya kontroller ekleyebilirsiniz
  useFrame(() => {
    // Örneğin, seçili objeyi döndür
    if (isSelected && meshRef.current) {
      meshRef.current.rotation.y += 0.01;
    }
  });

  return (
    <>
      <TransformControls object={meshRef.current} enabled={isSelected}>
        <mesh
          ref={meshRef}
          position={position}
          onClick={handleSelect}
        >
          <Html>
            {isSelected && <ShapeEditor shapeId={id} />}
          </Html>
          {type === 'box' && <boxGeometry args={[1, 1, 1]} />}
          {type === 'sphere' && <sphereGeometry args={[1, 32, 32]} />}
          {/* Diğer şekiller için geometry ekleyebilirsiniz */}
          <meshStandardMaterial color={material.color} />
        </mesh>
      </TransformControls>
    </>
  );
};

export default BasicShape;
_____

import { useState, useEffect } from 'react';
import { TextField, Button, MenuItem } from '@mui/material';
import useStore from "../Context";
import { Color } from 'three';

const ShapeEditor = ({ shapeId }) => {
  const { shapes, updateShape,setOnEditing,onEditing } = useStore();
  const shape = shapes??[].find(s => s?.id === shapeId);

  const [color, setColor] = useState(shape.material.color);
  const [type, setType] = useState(shape.type);

  useEffect(() => {
    if (shape) {
      const my_color = shape.material.color;
      setColor(new Color(my_color));
      setType(shape.type);
    }
  }, [shape]);
const startEdit  = ()=>{
  if(isFinite(onEditing) && !onEditing){
    setOnEditing(true)
  }
};
  const handleSave = () => {
    updateShape(shapeId, { material: { color }, type });
    setOnEditing(false)
  };

  return (
    <div onPointerEnter={()=>{startEdit()}} onPointerDown={()=>{startEdit()}} style={{ background: "white", padding: "10px", borderRadius: "5px", maxWidth: "200px" }}>
      <h3>Özellikler</h3>
      <TextField
        label="Renk"
        type="color"
        value={color}
        onChange={(e) => setColor(e.target.value)}
        fullWidth
        margin="normal"
      />
      <TextField
        select
        label="Şekil"
        value={type}
        onChange={(e) => setType(e.target.value)}
        fullWidth
        margin="normal"
      >
        <MenuItem value="box">Kutu</MenuItem>
        <MenuItem value="sphere">Küre</MenuItem>
        {/* Diğer şekiller için seçenek ekleyebilirsiniz */}
      </TextField>
      <Button variant="contained" color="primary" onClick={handleSave} fullWidth>
        Kaydet
      </Button>
    </div>
  );
};

export default ShapeEditor;

____

import { create } from "zustand";

// Zustand store
const useStore = create((set) => ({
  shapes: [], // Sahnedeki şekillerin dizisi
  onEditing: false,
  selectedObject: null, // Seçili obje
  setOnEditing: (value)=> set(value),
  setSelectedObject: (object) => set({ selectedObject: object }),
  addShape: (shape) => set((state) => ({ shapes: [...state.shapes, shape] })),
  updateShape: (id, newProps) => set((state) => ({
    shapes: state.shapes.map(shape => shape.id === id ? { ...shape, ...newProps } : shape)
  })),
  removeShape: (id) => set((state) => ({
    shapes: state.shapes.filter(shape => shape.id !== id)
  })),
}));

export default useStore;

_____

hata nedir?

düzelt ve anlat

ShapeEditor.jsx:10 Uncaught 
TypeError: Cannot read properties of undefined (reading 'color')
    at ShapeEditor (ShapeEditor.jsx:10:53)
    at renderWithHooks (chunk-NUMECXU6.js?v=c9f7d62c:11548:26)
    at mountIndeterminateComponent (chunk-NUMECXU6.js?v=c9f7d62c:14926:21)
    at beginWork (chunk-NUMECXU6.js?v=c9f7d62c:15914:22)
    at HTMLUnknownElement.callCallback2 (chunk-NUMECXU6.js?v=c9f7d62c:3674:22)
    at Object.invokeGuardedCallbackDev (chunk-NUMECXU6.js?v=c9f7d62c:3699:24)
    at invokeGuardedCallback (chunk-NUMECXU6.js?v=c9f7d62c:3733:39)
    at beginWork$1 (chunk-NUMECXU6.js?v=c9f7d62c:19765:15)
    at performUnitOfWork (chunk-NUMECXU6.js?v=c9f7d62c:19198:20)
    at workLoopSync (chunk-NUMECXU6.js?v=c9f7d62c:19137:13)
hook.js:608 The above error occurred in the <ShapeEditor> component:

    at ShapeEditor (http://localhost:5173/src/Shapes/ShapeEditor.jsx?t=1730868202957:22:24)
    at div

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error b