96 lines
2.7 KiB
JavaScript
96 lines
2.7 KiB
JavaScript
import * as THREE from 'three';
|
|
|
|
export const FloralPhyllo = ({ scene, rotation, params, viewport, objectsToDispose = [] }) => {
|
|
const {
|
|
width,
|
|
depth,
|
|
start,
|
|
colour1,
|
|
colour2
|
|
} = params;
|
|
|
|
// The effective rotation with start offset
|
|
const effectiveRotation = rotation + start;
|
|
|
|
// Generate points in phyllotaxis pattern
|
|
for (let n = 1; n <= depth; n++) {
|
|
// Calculate position using phyllotaxis formula
|
|
// Use the golden angle (137.5 degrees) for natural-looking pattern
|
|
const a = n * 0.1 + effectiveRotation / 100;
|
|
const r = Math.sqrt(n) * (width / 25);
|
|
const x = r * Math.cos(a);
|
|
const y = r * Math.sin(a);
|
|
|
|
// Calculate color using gradient based on position in the sequence
|
|
const colorFraction = n / depth;
|
|
const color = lerpColor(colour1, colour2, colorFraction);
|
|
|
|
// Create a petal/eye shape at this position
|
|
createPetal(scene, n/2 + 10, x, y, 0, color, objectsToDispose);
|
|
}
|
|
};
|
|
|
|
// Helper function to create a petal/eye shape
|
|
function createPetal(scene, size, x, y, z, color, objectsToDispose) {
|
|
// Create a custom shape for the petal/eye
|
|
const shape = new THREE.Shape();
|
|
|
|
// Define control points for the petal shape
|
|
const halfSize = size / 2;
|
|
|
|
// Starting point
|
|
shape.moveTo(-halfSize, 0);
|
|
|
|
// Top curve
|
|
shape.quadraticCurveTo(0, halfSize, halfSize, 0);
|
|
|
|
// Bottom curve
|
|
shape.quadraticCurveTo(0, -halfSize, -halfSize, 0);
|
|
|
|
// Create geometry from shape
|
|
const geometry = new THREE.ShapeGeometry(shape);
|
|
|
|
// Create material with specified color
|
|
const material = new THREE.MeshBasicMaterial({
|
|
color: new THREE.Color(color),
|
|
side: THREE.DoubleSide
|
|
});
|
|
|
|
// Create mesh and position it
|
|
const petal = new THREE.Mesh(geometry, material);
|
|
petal.position.set(x, y, z);
|
|
|
|
// Calculate angle based on position relative to origin
|
|
const angle = Math.atan2(y, x);
|
|
petal.rotation.z = angle; // Rotate to face outward
|
|
|
|
// Add stroke outline
|
|
const edgesGeometry = new THREE.EdgesGeometry(geometry);
|
|
const edgesMaterial = new THREE.LineBasicMaterial({
|
|
color: new THREE.Color(0x000000),
|
|
linewidth: 1
|
|
});
|
|
const edges = new THREE.LineSegments(edgesGeometry, edgesMaterial);
|
|
|
|
petal.add(edges);
|
|
scene.add(petal);
|
|
|
|
// Add to objects to dispose list
|
|
if (objectsToDispose) {
|
|
objectsToDispose.push(petal);
|
|
// Also track the edges for disposal
|
|
objectsToDispose.push(edges);
|
|
}
|
|
}
|
|
|
|
// Convert hex color string to THREE.js color and interpolate
|
|
function lerpColor(colorA, colorB, t) {
|
|
const a = new THREE.Color(colorA);
|
|
const b = new THREE.Color(colorB);
|
|
|
|
return new THREE.Color(
|
|
a.r + (b.r - a.r) * t,
|
|
a.g + (b.g - a.g) * t,
|
|
a.b + (b.b - a.b) * t
|
|
).getHex();
|
|
} |