-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshape.html
273 lines (225 loc) · 8.8 KB
/
shape.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css" />
<title>Übersicht</title>
<script async src="https://ga.jspm.io/npm:[email protected]/dist/es-module-shims.js" crossorigin="anonymous"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js",
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
}
}
</script>
</head>
<body>
<!-- Platzhalter für den Header -->
<div id="header-placeholder"></div>
<section class="features">
<div class="container">
<h1>Dynamic Shapes with Three.js</h1>
<p>Scroll down to see the dynamic shapes on both sides.</p>
</div>
</section>
<script type="module">
/* VERSION ZWEI
import * as THREE from "three";
let scene, camera, renderer, shapes = [];
let lastScrollY = 0, viewportHeight;
function init() {
// Szene, Kamera und Renderer initialisieren
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor("gainsboro", 1); // Hintergrundfarbe
document.body.appendChild(renderer.domElement);
// Shapes am Rand erzeugen
viewportHeight = window.innerHeight / 100;
let yOffset = 0;
for (let i = 0; i < 20; i++) {
const spacing = Math.random() * 0.2 + 0.1; // Variable Distanz (10 % bis 30 %)
yOffset += spacing * window.innerHeight; // Y-Versatz basierend auf Distanz
const leftShape = createDynamicShape(-6, yOffset); // Links
const rightShape = createDynamicShape(6, yOffset); // Rechts
shapes.push(leftShape, rightShape);
scene.add(leftShape, rightShape);
}
// Event-Listener für Fenstergrößenänderung und Scrollen
window.addEventListener("resize", onWindowResize);
window.addEventListener("scroll", onScroll);
// Animation starten
animate();
}
function createDynamicShape(xPosition, yOffset) {
// Erstellt ein Shape mit zufälliger Form und Farbe
const N = 8 + Math.floor(Math.random() * 5); // Zufällige Anzahl von Punkten (8–12)
const vertices = [];
for (let i = 0; i < N; i++) {
const angle = (i / (N - 1)) * Math.PI; // Halber Kreis
const radiusX = (1.5 + Math.random() * 0.5) * 0.5; // Reduziert um 50%
const radiusY = (4 + Math.random() * 2) * 0.5; // Reduziert um 50%
vertices.push(new THREE.Vector3(radiusX * Math.cos(angle), radiusY * Math.sin(angle), 0));
}
// Form schließen
vertices.push(new THREE.Vector3(-0.75, -2, 0)); // Linke untere Ecke
vertices.push(new THREE.Vector3(0.75, -2, 0)); // Rechte untere Ecke
const shapeGeom = new THREE.Shape(vertices);
const geometry = new THREE.ExtrudeGeometry(shapeGeom, {
steps: 1,
depth: 0.1, // Dünne Tiefe
bevelEnabled: false, // Keine Kantenabrundung
});
// Farbe variieren (Helligkeit und Sättigung ±10 %)
const baseColor = new THREE.Color("#b2c2a1"); // Basisfarbe
const hsl = baseColor.getHSL({});
const randomSaturation = Math.min(1, Math.max(0, hsl.s + (Math.random() - 0.5) * 0.1));
const randomLightness = Math.min(1, Math.max(0, hsl.l + (Math.random() - 0.5) * 0.1));
baseColor.setHSL(hsl.h, randomSaturation, randomLightness);
const material = new THREE.MeshBasicMaterial({
color: baseColor,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(xPosition, yOffset, 0);
return mesh;
}
function onWindowResize() {
// Anpassung an Fenstergröße
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onScroll() {
// Scroll-Position aktualisieren
const currentScrollY = window.scrollY / window.innerHeight;
const deltaScroll = currentScrollY - lastScrollY; // Veränderung seit dem letzten Scroll
lastScrollY = currentScrollY; // Neue letzte Position speichern
// Shapes basierend auf Scrollmenge verschieben
shapes.forEach((shape) => {
shape.position.y -= deltaScroll * 10; // Scroll-basierte Bewegung
if (shape.position.y < -viewportHeight) {
shape.position.y += viewportHeight * 10; // Recyclen: Unten wieder einfügen
regenerateShape(shape); // Neue zufällige Form und Farbe erstellen
} else if (shape.position.y > viewportHeight * 10) {
shape.position.y -= viewportHeight * 10; // Recyclen: Oben wieder einfügen
regenerateShape(shape); // Neue zufällige Form und Farbe erstellen
}
});
}
function regenerateShape(shape) {
// Erzeugt eine neue zufällige Form und Farbe für ein Shape
const N = 8 + Math.floor(Math.random() * 5);
const vertices = [];
for (let i = 0; i < N; i++) {
const angle = (i / (N - 1)) * Math.PI;
const radiusX = (1.5 + Math.random() * 0.5) * 0.5;
const radiusY = (4 + Math.random() * 2) * 0.5;
vertices.push(new THREE.Vector3(radiusX * Math.cos(angle), radiusY * Math.sin(angle), 0));
}
vertices.push(new THREE.Vector3(-0.75, -2, 0));
vertices.push(new THREE.Vector3(0.75, -2, 0));
const shapeGeom = new THREE.Shape(vertices);
shape.geometry.dispose();
shape.geometry = new THREE.ExtrudeGeometry(shapeGeom, {
steps: 1,
depth: 0.1,
bevelEnabled: false,
});
// Farbe variieren
const baseColor = new THREE.Color("#b2c2a1");
const hsl = baseColor.getHSL({});
const randomSaturation = Math.min(1, Math.max(0, hsl.s + (Math.random() - 0.5) * 0.1));
const randomLightness = Math.min(1, Math.max(0, hsl.l + (Math.random() - 0.5) * 0.1));
baseColor.setHSL(hsl.h, randomSaturation, randomLightness);
shape.material.color = baseColor;
}
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
// Initialisierung starten
init();
*/
/* VERSION EINS */
import * as THREE from "three";
let scene, camera, renderer, shapes = [], scrollY = 0;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor("gainsboro", 1);
document.body.appendChild(renderer.domElement);
// Links und rechts Formen hinzufügen
for (let i = 0; i < 2; i++) {
const shape = createDynamicShape(i === 0 ? -5 : 5);
shapes.push(shape);
scene.add(shape);
}
window.addEventListener("resize", onWindowResize);
window.addEventListener("scroll", onScroll);
animate();
}
function createDynamicShape(xPosition) {
const geometry = new THREE.BufferGeometry();
const material = new THREE.MeshBasicMaterial({
color: "coral", // Hier die Farbe ändern
side: THREE.DoubleSide,
clippingPlanes: [
new THREE.Plane(new THREE.Vector3(0, 0, -1), 0),
new THREE.Plane(new THREE.Vector3(0, 0, 1), 0.001)
]
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.x = xPosition; // Links oder rechts
return mesh;
}
function updateShape(shape, time) {
const N = 8; // Weniger Punkte für einfachere, organische Formen
const vertices = [];
for (let i = 0; i < N; i++) {
const angle = (i / (N - 1)) * Math.PI; // Nur die obere Hälfte für "seitliche" Wellen
const radiusX = 3 + Math.sin(time / 3000 + i) * 0.5; // Sanfte Wellenbewegung
const radiusY = 8; // Vertikale Ausdehnung
vertices.push(new THREE.Vector3(radiusX * Math.cos(angle), radiusY * Math.sin(angle), 0));
}
// Form schließen (unten zurück zur Achse)
vertices.push(new THREE.Vector3(-3, -8, 0)); // Linke untere Ecke
vertices.push(new THREE.Vector3(3, -8, 0)); // Rechte untere Ecke
const shapeGeom = new THREE.Shape(vertices);
shape.geometry.dispose();
shape.geometry = new THREE.ExtrudeGeometry(shapeGeom, {
steps: 1,
depth: 0.5,
bevelEnabled: false, // Kein Bevel für klare Kanten
});
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onScroll() {
scrollY = -window.scrollY / window.innerHeight; // Invertiere den Scroll-Wert
}
function animate(time) {
shapes.forEach((shape, index) => {
updateShape(shape, time + index * 500); // Offset für mehr Dynamik
shape.position.y = -scrollY * 5 + (index === 0 ? 2 : -2); // Scroll-abhängige Position
});
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
</script>
<!-- Platzhalter für den Footer -->
<div id="footer-placeholder"></div>
<!-- Externes JavaScript einbinden -->
<script src="script.js"></script>
</body>
</html>