|
|
@@ -7,6 +7,7 @@ import { ref, onMounted, onUnmounted, watch, computed } from "vue";
|
|
|
import * as THREE from "three";
|
|
|
import { STLLoader } from "three/addons/loaders/STLLoader.js";
|
|
|
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
|
|
|
+import { getHexColor } from "@/lib/colors";
|
|
|
|
|
|
interface Props {
|
|
|
file: File;
|
|
|
@@ -19,44 +20,19 @@ let animationId = 0;
|
|
|
let renderer: THREE.WebGLRenderer | null = null;
|
|
|
let mesh: THREE.Mesh | null = null;
|
|
|
|
|
|
-// Standard color map for common names
|
|
|
-const COLOR_MAP: Record<string, string> = {
|
|
|
- "white": "#ffffff",
|
|
|
- "black": "#1a1a1a",
|
|
|
- "grey": "#808080",
|
|
|
- "gray": "#808080",
|
|
|
- "red": "#ef4444",
|
|
|
- "blue": "#3b82f6",
|
|
|
- "green": "#22c55e",
|
|
|
- "yellow": "#eab308",
|
|
|
- "orange": "#f97316",
|
|
|
- "purple": "#a855f7",
|
|
|
- "pink": "#ec4899",
|
|
|
- "silver": "#c0c0c0",
|
|
|
- "gold": "#ffd700",
|
|
|
- "transparent": "#f3f4f6", // fallback for visual
|
|
|
- "natural": "#f5f5dc",
|
|
|
-};
|
|
|
-
|
|
|
-const getHexColor = (colorName?: string) => {
|
|
|
- if (!colorName) return "#808080";
|
|
|
- if (colorName.startsWith("#")) return colorName;
|
|
|
- return COLOR_MAP[colorName.toLowerCase()] || "#808080";
|
|
|
-};
|
|
|
-
|
|
|
const isLight = (hex: string) => {
|
|
|
const color = hex.startsWith("#") ? hex : getHexColor(hex);
|
|
|
- const rgb = parseInt(color.slice(1), 16);
|
|
|
+ const rgb = parseInt(color.slice(1, 7), 16);
|
|
|
const r = (rgb >> 16) & 0xff;
|
|
|
const g = (rgb >> 8) & 0xff;
|
|
|
const b = (rgb >> 0) & 0xff;
|
|
|
const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
|
- return luma > 150; // Threshold for "light"
|
|
|
+ return luma > 150;
|
|
|
};
|
|
|
|
|
|
const backgroundColor = computed(() => {
|
|
|
if (!props.color) return "transparent";
|
|
|
- return isLight(props.color) ? "#0f172a" : "#f8fafc"; // Slate-900 or Slate-50
|
|
|
+ return isLight(props.color) ? "#0f172a" : "#f8fafc";
|
|
|
});
|
|
|
|
|
|
watch(() => props.color, (newColor) => {
|
|
|
@@ -79,7 +55,7 @@ onMounted(() => {
|
|
|
|
|
|
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
|
|
renderer.setSize(width, height);
|
|
|
- renderer.setClearColor(0x000000, 0); // Always transparent, handled by CSS
|
|
|
+ renderer.setClearColor(0x000000, 0);
|
|
|
container.value.appendChild(renderer.domElement);
|
|
|
|
|
|
const controls = new OrbitControls(camera, renderer.domElement);
|
|
|
@@ -87,7 +63,6 @@ onMounted(() => {
|
|
|
controls.autoRotate = true;
|
|
|
controls.autoRotateSpeed = 3.0;
|
|
|
|
|
|
- // Add lights
|
|
|
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.2);
|
|
|
hemiLight.position.set(0, 200, 0);
|
|
|
scene.add(hemiLight);
|