feat: Latest production version with interior scene and glass
Includes room interior with floor, walls, glass you can see through, and all uncommitted production changes that were running live. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRef, useMemo, Suspense } from "react";
|
||||
import { useConfiguratorStore } from "@/lib/store";
|
||||
import { useConfiguratorStore, type GlassColor, type Finish } from "@/lib/store";
|
||||
import { RoundedBox, useTexture } from "@react-three/drei";
|
||||
import * as THREE from "three";
|
||||
import {
|
||||
@@ -26,28 +26,58 @@ import {
|
||||
type PhysicalPart,
|
||||
} from "@/lib/door-models";
|
||||
|
||||
// ============================================
|
||||
// FRAME COLOR MAPPING
|
||||
// ============================================
|
||||
|
||||
const FRAME_COLORS: Record<Finish, string> = {
|
||||
zwart: "#1a1a1a",
|
||||
brons: "#8B6F47",
|
||||
grijs: "#525252",
|
||||
goud: "#B8860B",
|
||||
beige: "#C8B88A",
|
||||
ral: "#4A6741",
|
||||
};
|
||||
|
||||
const FRAME_TEXTURE_PATHS: Record<Finish, string> = {
|
||||
zwart: "/textures/proinn/proinn-metaalkleur-zwart.jpg",
|
||||
brons: "/textures/proinn/proinn-metaalkleur-brons.jpg",
|
||||
grijs: "/textures/proinn/proinn-metaalkleur-antraciet.jpg",
|
||||
goud: "/textures/proinn/proinn-metaalkleur-goud.jpg",
|
||||
beige: "/textures/proinn/proinn-metaalkleur-beige.jpg",
|
||||
ral: "/textures/proinn/proinn-metaalkleur-ral-keuze.jpg",
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// GLASS COLOR MAPPING
|
||||
// ============================================
|
||||
|
||||
interface GlassColorProps {
|
||||
color: string;
|
||||
transmission: number;
|
||||
roughness: number;
|
||||
}
|
||||
|
||||
const GLASS_COLOR_MAP: Record<GlassColor, GlassColorProps> = {
|
||||
helder: { color: "#eff6ff", transmission: 0.98, roughness: 0.05 },
|
||||
grijs: { color: "#3a3a3a", transmission: 0.85, roughness: 0.1 },
|
||||
brons: { color: "#8B6F47", transmission: 0.85, roughness: 0.1 },
|
||||
"mat-blank": { color: "#e8e8e8", transmission: 0.7, roughness: 0.3 },
|
||||
"mat-brons": { color: "#A0845C", transmission: 0.6, roughness: 0.35 },
|
||||
"mat-zwart": { color: "#1a1a1a", transmission: 0.5, roughness: 0.4 },
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// PHOTOREALISTIC MATERIALS
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Steel Material with Aluwdoors Texture
|
||||
* Vertical steel grain for industrial look
|
||||
*/
|
||||
function SteelMaterialTextured({ color, finish }: { color: string; finish: string }) {
|
||||
function SteelMaterialTextured({ color, finish }: { color: string; finish: Finish }) {
|
||||
try {
|
||||
// Load texture based on finish
|
||||
const texturePath = {
|
||||
zwart: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-zwart.jpg",
|
||||
brons: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-brons.jpg",
|
||||
grijs: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-antraciet.jpg",
|
||||
}[finish] || "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-zwart.jpg";
|
||||
|
||||
const texturePath = FRAME_TEXTURE_PATHS[finish];
|
||||
const texture = useTexture(texturePath);
|
||||
|
||||
// Configure texture for vertical steel grain
|
||||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
||||
texture.repeat.set(0.5, 3); // Vertical grain
|
||||
texture.repeat.set(0.5, 3);
|
||||
texture.colorSpace = THREE.SRGBColorSpace;
|
||||
|
||||
return (
|
||||
@@ -59,14 +89,11 @@ function SteelMaterialTextured({ color, finish }: { color: string; finish: strin
|
||||
envMapIntensity={1.5}
|
||||
/>
|
||||
);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return <SteelMaterialFallback color={color} />;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback Steel Material (Solid Color)
|
||||
*/
|
||||
function SteelMaterialFallback({ color }: { color: string }) {
|
||||
return (
|
||||
<meshStandardMaterial
|
||||
@@ -78,40 +105,37 @@ function SteelMaterialFallback({ color }: { color: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Photorealistic Glass Material
|
||||
* High transmission for realistic glass look
|
||||
*/
|
||||
const GlassMaterial = () => (
|
||||
<meshPhysicalMaterial
|
||||
transmission={0.98}
|
||||
roughness={0.05}
|
||||
thickness={0.007}
|
||||
ior={1.5}
|
||||
color="#eff6ff"
|
||||
transparent
|
||||
opacity={0.98}
|
||||
envMapIntensity={1.0}
|
||||
/>
|
||||
);
|
||||
function GlassMaterial({ glassColor }: { glassColor: GlassColor }) {
|
||||
const props = GLASS_COLOR_MAP[glassColor];
|
||||
return (
|
||||
<meshPhysicalMaterial
|
||||
transmission={props.transmission}
|
||||
roughness={props.roughness}
|
||||
thickness={0.007}
|
||||
ior={1.5}
|
||||
color={props.color}
|
||||
transparent
|
||||
opacity={0.98}
|
||||
envMapIntensity={1.0}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// PHYSICAL PART RENDERER
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Renders a single physical part with correct geometry
|
||||
*/
|
||||
function PhysicalPartComponent({
|
||||
part,
|
||||
frameColor,
|
||||
finish,
|
||||
glassColor,
|
||||
}: {
|
||||
part: PhysicalPart;
|
||||
frameColor: string;
|
||||
finish: string;
|
||||
finish: Finish;
|
||||
glassColor: GlassColor;
|
||||
}) {
|
||||
// Convert mm to meters
|
||||
const x = mmToMeters(part.x);
|
||||
const y = mmToMeters(part.y);
|
||||
const z = mmToMeters(part.z);
|
||||
@@ -119,17 +143,15 @@ function PhysicalPartComponent({
|
||||
const height = mmToMeters(part.height);
|
||||
const depth = mmToMeters(part.depth);
|
||||
|
||||
// Glass uses different material
|
||||
if (part.isGlass) {
|
||||
return (
|
||||
<mesh position={[x, y, z]} castShadow receiveShadow>
|
||||
<boxGeometry args={[width, height, depth]} />
|
||||
<GlassMaterial />
|
||||
<GlassMaterial glassColor={glassColor} />
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
// Steel profiles use RoundedBox for realistic edges
|
||||
const cornerRadius = mmToMeters(PROFILE_CORNER_RADIUS);
|
||||
|
||||
return (
|
||||
@@ -153,32 +175,21 @@ function PhysicalPartComponent({
|
||||
// ============================================
|
||||
|
||||
export function Door3DEnhanced() {
|
||||
const { doorType, gridType, finish, handle, glassPattern, doorLeafWidth, height } =
|
||||
const { doorType, gridType, finish, handle, glassPattern, glassColor, doorLeafWidth, height } =
|
||||
useConfiguratorStore();
|
||||
const doorRef = useRef<THREE.Group>(null);
|
||||
|
||||
// Frame color based on finish
|
||||
const frameColor = {
|
||||
zwart: "#1a1a1a",
|
||||
brons: "#8B6F47",
|
||||
grijs: "#525252",
|
||||
}[finish] || "#1a1a1a";
|
||||
const frameColor = FRAME_COLORS[finish] || "#1a1a1a";
|
||||
|
||||
// Generate door assembly from manufacturing specs
|
||||
const doorAssembly = useMemo(
|
||||
() => generateDoorAssembly(doorType, gridType, doorLeafWidth, height),
|
||||
[doorType, gridType, doorLeafWidth, height]
|
||||
);
|
||||
|
||||
// Convert dimensions to meters
|
||||
const doorWidth = mmToMeters(doorLeafWidth);
|
||||
const doorHeight = mmToMeters(height);
|
||||
|
||||
// Profile dimensions in meters (for handle positioning)
|
||||
const stileWidth = mmToMeters(40);
|
||||
const railDepth = mmToMeters(40);
|
||||
|
||||
// Get divider positions for glass patterns (backward compatibility)
|
||||
const dividerPositions = getDividerPositions(gridType, height);
|
||||
|
||||
return (
|
||||
@@ -190,6 +201,7 @@ export function Door3DEnhanced() {
|
||||
part={part}
|
||||
frameColor={frameColor}
|
||||
finish={finish}
|
||||
glassColor={glassColor}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -208,13 +220,12 @@ export function Door3DEnhanced() {
|
||||
{ depth: 0.01, bevelEnabled: false },
|
||||
]}
|
||||
/>
|
||||
<GlassMaterial />
|
||||
<GlassMaterial glassColor={glassColor} />
|
||||
</mesh>
|
||||
)}
|
||||
|
||||
{glassPattern === "dt10-ushape" && dividerPositions.length > 0 && (
|
||||
<>
|
||||
{/* Top section - Inverted U */}
|
||||
<mesh
|
||||
position={[0, (doorHeight / 4 + dividerPositions[0]) / 2, 0]}
|
||||
castShadow
|
||||
@@ -229,10 +240,9 @@ export function Door3DEnhanced() {
|
||||
{ depth: 0.01, bevelEnabled: false },
|
||||
]}
|
||||
/>
|
||||
<GlassMaterial />
|
||||
<GlassMaterial glassColor={glassColor} />
|
||||
</mesh>
|
||||
|
||||
{/* Bottom section - Normal U */}
|
||||
<mesh
|
||||
position={[
|
||||
0,
|
||||
@@ -255,7 +265,7 @@ export function Door3DEnhanced() {
|
||||
{ depth: 0.01, bevelEnabled: false },
|
||||
]}
|
||||
/>
|
||||
<GlassMaterial />
|
||||
<GlassMaterial glassColor={glassColor} />
|
||||
</mesh>
|
||||
</>
|
||||
)}
|
||||
@@ -264,58 +274,22 @@ export function Door3DEnhanced() {
|
||||
|
||||
{/* PROFESSIONAL 3D HANDLES */}
|
||||
{handle === "beugelgreep" && (
|
||||
<Beugelgreep
|
||||
finish={finish}
|
||||
doorWidth={doorWidth}
|
||||
doorHeight={doorHeight}
|
||||
railDepth={railDepth}
|
||||
stileWidth={stileWidth}
|
||||
/>
|
||||
<Beugelgreep finish={finish} doorWidth={doorWidth} doorHeight={doorHeight} railDepth={railDepth} stileWidth={stileWidth} />
|
||||
)}
|
||||
{handle === "hoekgreep" && (
|
||||
<Hoekgreep
|
||||
finish={finish}
|
||||
doorWidth={doorWidth}
|
||||
doorHeight={doorHeight}
|
||||
railDepth={railDepth}
|
||||
stileWidth={stileWidth}
|
||||
/>
|
||||
<Hoekgreep finish={finish} doorWidth={doorWidth} doorHeight={doorHeight} railDepth={railDepth} stileWidth={stileWidth} />
|
||||
)}
|
||||
{handle === "maangreep" && (
|
||||
<Maangreep
|
||||
finish={finish}
|
||||
doorWidth={doorWidth}
|
||||
doorHeight={doorHeight}
|
||||
railDepth={railDepth}
|
||||
stileWidth={stileWidth}
|
||||
/>
|
||||
<Maangreep finish={finish} doorWidth={doorWidth} doorHeight={doorHeight} railDepth={railDepth} stileWidth={stileWidth} />
|
||||
)}
|
||||
{handle === "ovaalgreep" && (
|
||||
<Ovaalgreep
|
||||
finish={finish}
|
||||
doorWidth={doorWidth}
|
||||
doorHeight={doorHeight}
|
||||
railDepth={railDepth}
|
||||
stileWidth={stileWidth}
|
||||
/>
|
||||
<Ovaalgreep finish={finish} doorWidth={doorWidth} doorHeight={doorHeight} railDepth={railDepth} stileWidth={stileWidth} />
|
||||
)}
|
||||
{handle === "klink" && (
|
||||
<Klink
|
||||
finish={finish}
|
||||
doorWidth={doorWidth}
|
||||
doorHeight={doorHeight}
|
||||
railDepth={railDepth}
|
||||
stileWidth={stileWidth}
|
||||
/>
|
||||
<Klink finish={finish} doorWidth={doorWidth} doorHeight={doorHeight} railDepth={railDepth} stileWidth={stileWidth} />
|
||||
)}
|
||||
{handle === "u-greep" && (
|
||||
<UGreep
|
||||
finish={finish}
|
||||
doorWidth={doorWidth}
|
||||
doorHeight={doorHeight}
|
||||
railDepth={railDepth}
|
||||
stileWidth={stileWidth}
|
||||
/>
|
||||
<UGreep finish={finish} doorWidth={doorWidth} doorHeight={doorHeight} railDepth={railDepth} stileWidth={stileWidth} />
|
||||
)}
|
||||
</group>
|
||||
);
|
||||
|
||||
@@ -36,11 +36,14 @@ export function Door3D() {
|
||||
const doorRef = useRef<THREE.Group>(null);
|
||||
|
||||
// Frame color based on finish
|
||||
const frameColor = {
|
||||
const frameColor = ({
|
||||
zwart: "#1a1a1a",
|
||||
brons: "#8B6F47",
|
||||
grijs: "#525252",
|
||||
}[finish];
|
||||
goud: "#b8960c",
|
||||
beige: "#c8b88a",
|
||||
ral: "#2a2a2a",
|
||||
} as Record<string, string>)[finish] ?? "#1a1a1a";
|
||||
|
||||
// Convert mm to meters for 3D scene
|
||||
const doorWidth = doorLeafWidth / 1000; // Convert mm to m
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { Suspense, useCallback } from "react";
|
||||
import { useConfiguratorStore } from "@/lib/store";
|
||||
import { Scene3D } from "./scene";
|
||||
import { Camera } from "lucide-react";
|
||||
|
||||
function LoadingFallback() {
|
||||
return (
|
||||
@@ -15,8 +16,31 @@ function LoadingFallback() {
|
||||
);
|
||||
}
|
||||
|
||||
function formatPrice(amount: number): string {
|
||||
return new Intl.NumberFormat("nl-NL", {
|
||||
style: "currency",
|
||||
currency: "EUR",
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
export function DoorVisualizer() {
|
||||
const { doorType, gridType, finish, handle } = useConfiguratorStore();
|
||||
const { doorType, gridType, finish, handle, priceBreakdown, setScreenshotDataUrl } =
|
||||
useConfiguratorStore();
|
||||
|
||||
const handleScreenshot = useCallback(() => {
|
||||
const canvas = document.querySelector("canvas");
|
||||
if (!canvas) return;
|
||||
const dataUrl = canvas.toDataURL("image/png");
|
||||
setScreenshotDataUrl(dataUrl);
|
||||
|
||||
// Also trigger download
|
||||
const link = document.createElement("a");
|
||||
link.download = "proinn-deur-configuratie.png";
|
||||
link.href = dataUrl;
|
||||
link.click();
|
||||
}, [setScreenshotDataUrl]);
|
||||
|
||||
return (
|
||||
<div className="relative h-full w-full overflow-hidden rounded-[2.5rem]">
|
||||
@@ -28,13 +52,36 @@ export function DoorVisualizer() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Screenshot Button */}
|
||||
<div className="absolute right-8 top-8 z-10">
|
||||
<button
|
||||
onClick={handleScreenshot}
|
||||
className="flex items-center gap-2 rounded-full bg-[#1A2E2E]/80 px-3 py-2 text-xs font-medium text-white shadow-lg backdrop-blur-sm transition-all hover:bg-[#1A2E2E]"
|
||||
>
|
||||
<Camera className="size-3.5" />
|
||||
Screenshot
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 3D Scene */}
|
||||
<Suspense fallback={<LoadingFallback />}>
|
||||
<Scene3D />
|
||||
</Suspense>
|
||||
|
||||
{/* Live Price Badge */}
|
||||
<div className="absolute right-8 bottom-24 z-10 lg:bottom-8">
|
||||
<div className="rounded-2xl bg-[#1A2E2E] px-5 py-3 text-right shadow-lg">
|
||||
<div className="text-[10px] font-medium uppercase tracking-wider text-gray-400">
|
||||
Indicatieprijs
|
||||
</div>
|
||||
<div className="text-xl font-bold text-[#C4D668]">
|
||||
{formatPrice(priceBreakdown.totalPrice)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Configuration Info Card */}
|
||||
<div className="absolute bottom-8 left-8 right-8 z-10">
|
||||
<div className="absolute bottom-8 left-8 z-10">
|
||||
<div className="rounded-2xl bg-white/90 p-4 shadow-lg backdrop-blur-sm">
|
||||
<div className="grid grid-cols-2 gap-3 text-sm">
|
||||
<div>
|
||||
@@ -64,9 +111,9 @@ export function DoorVisualizer() {
|
||||
</div>
|
||||
|
||||
{/* Controls Hint */}
|
||||
<div className="absolute bottom-8 right-8 z-10 hidden lg:block">
|
||||
<div className="absolute bottom-8 right-8 z-10 hidden lg:hidden">
|
||||
<div className="rounded-xl bg-[#1A2E2E]/80 px-3 py-2 text-xs text-white backdrop-blur-sm">
|
||||
<p className="font-medium">🖱️ Drag to rotate • Scroll to zoom</p>
|
||||
<p className="font-medium">Drag to rotate - Scroll to zoom</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -37,11 +37,14 @@ export interface HandleProps {
|
||||
*/
|
||||
function HandleMaterialTextured({ color, finish }: { color: string; finish: string }) {
|
||||
try {
|
||||
const texturePath = {
|
||||
zwart: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-zwart.jpg",
|
||||
brons: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-brons.jpg",
|
||||
grijs: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-antraciet.jpg",
|
||||
}[finish] || "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-zwart.jpg";
|
||||
const texturePath = ({
|
||||
zwart: "/textures/proinn/proinn-metaalkleur-zwart.jpg",
|
||||
brons: "/textures/proinn/proinn-metaalkleur-brons.jpg",
|
||||
grijs: "/textures/proinn/proinn-metaalkleur-antraciet.jpg",
|
||||
goud: "/textures/proinn/proinn-metaalkleur-goud.jpg",
|
||||
beige: "/textures/proinn/proinn-metaalkleur-beige.jpg",
|
||||
ral: "/textures/proinn/proinn-metaalkleur-ral-keuze.jpg",
|
||||
} as Record<string, string>)[finish] || "/textures/proinn/proinn-metaalkleur-zwart.jpg";
|
||||
|
||||
const texture = useTexture(texturePath);
|
||||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
||||
@@ -83,7 +86,14 @@ function PowderCoatMaterial({ color, finish }: { color: string; finish: string }
|
||||
}
|
||||
|
||||
function getColor(finish: string): string {
|
||||
return { zwart: "#1a1a1a", brons: "#8B6F47", grijs: "#525252" }[finish] || "#1a1a1a";
|
||||
return ({
|
||||
zwart: "#1a1a1a",
|
||||
brons: "#8B6F47",
|
||||
grijs: "#525252",
|
||||
goud: "#B8860B",
|
||||
beige: "#C8B88A",
|
||||
ral: "#4A6741",
|
||||
} as Record<string, string>)[finish] || "#1a1a1a";
|
||||
}
|
||||
|
||||
// ============================================
|
||||
@@ -122,14 +132,16 @@ function MountStandoff({
|
||||
/**
|
||||
* U-Greep: Proper U-shaped bar handle with two standoff mounts.
|
||||
* The grip sits 40mm off the door face, connected by two cylindrical pootjes.
|
||||
* Mounted on the right stile (vertical frame profile).
|
||||
*/
|
||||
export function UGreep({ finish, doorHeight }: HandleProps) {
|
||||
export function UGreep({ finish, doorWidth, doorHeight, stileWidth }: HandleProps) {
|
||||
const color = getColor(finish);
|
||||
const gripLength = Math.min(doorHeight * 0.25, 0.6); // Max 60cm, proportional
|
||||
const mountSpacing = gripLength - GRIP_BAR_SIZE; // Distance between mount centers
|
||||
const xPos = doorWidth / 2 - stileWidth / 2; // Center of right stile
|
||||
|
||||
return (
|
||||
<group position={[0, 0, 0]}>
|
||||
<group position={[xPos, 0, 0]}>
|
||||
{/* Top mount standoff */}
|
||||
<MountStandoff
|
||||
position={[0, mountSpacing / 2, MOUNT_CENTER_Z]}
|
||||
@@ -163,16 +175,18 @@ export function UGreep({ finish, doorHeight }: HandleProps) {
|
||||
* Beugelgreep: Vertical bar handle (round) with mounting blocks.
|
||||
* Two rectangular mounting blocks press against the door face,
|
||||
* with a round bar connecting them.
|
||||
* Mounted on the right stile (vertical frame profile).
|
||||
*/
|
||||
export function Beugelgreep({ finish, doorHeight }: HandleProps) {
|
||||
export function Beugelgreep({ finish, doorWidth, doorHeight, stileWidth }: HandleProps) {
|
||||
const color = getColor(finish);
|
||||
const gripLength = Math.min(doorHeight * 0.35, 0.8); // Max 80cm
|
||||
const barDiameter = 0.025; // 25mm
|
||||
const mountBlockSize: [number, number, number] = [0.04, 0.05, MOUNT_LENGTH];
|
||||
const mountSpacing = gripLength * 0.85;
|
||||
const xPos = doorWidth / 2 - stileWidth / 2; // Center of right stile
|
||||
|
||||
return (
|
||||
<group position={[0, 0, 0]}>
|
||||
<group position={[xPos, 0, 0]}>
|
||||
{/* Top mounting block (sits on door face, extends outward) */}
|
||||
<RoundedBox
|
||||
args={mountBlockSize}
|
||||
@@ -229,8 +243,8 @@ export function Hoekgreep({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
const barThickness = 0.02;
|
||||
const barWidth = 0.03;
|
||||
|
||||
// Position near right stile
|
||||
const xPos = doorWidth / 2 - stileWidth - 0.12;
|
||||
// Position on right stile center
|
||||
const xPos = doorWidth / 2 - stileWidth / 2;
|
||||
|
||||
return (
|
||||
<group position={[xPos, 0, 0]}>
|
||||
@@ -289,7 +303,8 @@ export function Hoekgreep({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
export function Maangreep({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
const color = getColor(finish);
|
||||
const curveRadius = 0.08;
|
||||
const xPos = doorWidth / 2 - stileWidth - 0.12;
|
||||
// Position on right stile center
|
||||
const xPos = doorWidth / 2 - stileWidth / 2;
|
||||
|
||||
return (
|
||||
<group position={[xPos, 0, 0]}>
|
||||
@@ -338,7 +353,8 @@ export function Maangreep({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
*/
|
||||
export function Ovaalgreep({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
const color = getColor(finish);
|
||||
const xPos = doorWidth / 2 - stileWidth - 0.12;
|
||||
// Position on right stile center
|
||||
const xPos = doorWidth / 2 - stileWidth / 2;
|
||||
|
||||
const shape = new THREE.Shape();
|
||||
const rx = 0.06;
|
||||
@@ -391,7 +407,8 @@ export function Ovaalgreep({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
export function Klink({ finish, doorWidth, stileWidth }: HandleProps) {
|
||||
const color = getColor(finish);
|
||||
const leverLength = 0.12;
|
||||
const xPos = doorWidth / 2 - stileWidth - 0.1;
|
||||
// Position on right stile center
|
||||
const xPos = doorWidth / 2 - stileWidth / 2;
|
||||
|
||||
return (
|
||||
<group position={[xPos, 0, 0]}>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,9 @@ export function useMetalTexture(finish: string) {
|
||||
|
||||
useEffect(() => {
|
||||
const mapping: Record<string, string> = {
|
||||
zwart: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-zwart.jpg",
|
||||
brons: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-brons.jpg",
|
||||
grijs: "/textures/aluwdoors/aluwdoors-configurator-metaalkleur-antraciet.jpg",
|
||||
zwart: "/textures/proinn/proinn-metaalkleur-zwart.jpg",
|
||||
brons: "/textures/proinn/proinn-metaalkleur-brons.jpg",
|
||||
grijs: "/textures/proinn/proinn-metaalkleur-antraciet.jpg",
|
||||
};
|
||||
|
||||
setTextureUrl(mapping[finish] || mapping.zwart);
|
||||
|
||||
Reference in New Issue
Block a user