"use client";
import { useState, ReactNode } from "react";
import * as THREE from "three";
import { PivotControls, Html } from "@react-three/drei";
interface PivotControlsWrapperProps {
children?: ReactNode;
}
const PivotControlsWrapper: React.FC<PivotControlsWrapperProps> = ({
children,
}) => {
// PivotControlsの位置と回転を管理するstate
const [markerPosition, setMarkerPosition] = useState<
[number, number, number]
>([0, 0, 0]);
const [markerRotation, setMarkerRotation] = useState<
[number, number, number]
>([0, 0, 0]);
const [markerScale, setMarkerScale] = useState<[number, number, number]>([
1, 1, 1,
]);
// コピー成功時のフィードバック用state
const [copySuccess, setCopySuccess] = useState(false);
// 位置、回転、スケールの情報をクリップボードにコピーする関数
const copyTransformToClipboard = () => {
const transformText = `position={[${markerPosition[0].toFixed(2)}, ${markerPosition[1].toFixed(2)}, ${markerPosition[2].toFixed(2)}]}\nscale={[${markerScale[0].toFixed(2)}, ${markerScale[1].toFixed(2)}, ${markerScale[2].toFixed(2)}]}\nrotation={[${markerRotation[0].toFixed(2)}, ${markerRotation[1].toFixed(2)}, ${markerRotation[2].toFixed(2)}]}`;
navigator.clipboard
.writeText(transformText)
.then(() => {
// コピー成功時のフィードバック
setCopySuccess(true);
// 2秒後にフィードバックを非表示
setTimeout(() => setCopySuccess(false), 2000);
})
.catch((err) => {
console.error("クリップボードへのコピーに失敗しました:", err);
});
};
return (
<PivotControls
autoTransform
scale={100}
lineWidth={2}
fixed
onDrag={(matrix) => {
// matrixから位置、回転、スケールを抽出
const position = new THREE.Vector3();
const quaternion = new THREE.Quaternion();
const scale = new THREE.Vector3();
matrix.decompose(position, quaternion, scale);
// quaternionからオイラー角に変換
const euler = new THREE.Euler().setFromQuaternion(quaternion);
// stateを更新
setMarkerPosition([position.x, position.y, position.z]);
setMarkerRotation([euler.x, euler.y, euler.z]);
setMarkerScale([scale.x, scale.y, scale.z]);
}}
>
<group>
{/* ここに設定したいオブジェクトを位置0、回転0、大きさ1で置く */}
{children}
<Html
position={[1.2, 0, 0]}
style={{
color: "white",
backgroundColor: "rgba(0,0,0,0.7)",
padding: "10px",
borderRadius: "5px",
width: "200px",
// pointerEvents: "none", // マウスイベントを通過させる
}}
>
<div style={{ fontSize: "12px", fontFamily: "monospace" }}>
<div>位置:</div>
<div>X: {markerPosition[0].toFixed(3)}</div>
<div>Y: {markerPosition[1].toFixed(3)}</div>
<div>Z: {markerPosition[2].toFixed(3)}</div>
<div style={{ marginTop: "5px" }}>回転 (rad):</div>
<div>X: {markerRotation[0].toFixed(3)}</div>
<div>Y: {markerRotation[1].toFixed(3)}</div>
<div>Z: {markerRotation[2].toFixed(3)}</div>
<div style={{ marginTop: "5px" }}>スケール:</div>
<div>X: {markerScale[0].toFixed(3)}</div>
<div>Y: {markerScale[1].toFixed(3)}</div>
<div>Z: {markerScale[2].toFixed(3)}</div>
<div style={{ marginTop: "10px" }}>
<button
onClick={copyTransformToClipboard}
style={{
backgroundColor: copySuccess ? "#4CAF50" : "#007BFF",
color: "white",
border: "none",
padding: "5px 10px",
borderRadius: "4px",
cursor: "pointer",
fontSize: "12px",
width: "100%",
transition: "background-color 0.3s",
}}
>
{copySuccess ? "コピー完了!" : "位置・回転・スケールをコピー"}
</button>
</div>
</div>
</Html>
</group>
</PivotControls>
);
};
export default PivotControlsWrapper;