Test files für LifeWave mit anime.js
This commit is contained in:
parent
c6dd063eee
commit
9c48a17152
7 changed files with 3573 additions and 0 deletions
635
test/anime-points-fine.html
Normal file
635
test/anime-points-fine.html
Normal file
|
|
@ -0,0 +1,635 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Welle Hintergrund (SVG)</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background-color: #f0f0f0;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
svg {
|
||||
border: 1px solid #ccc; /* Optional: Rahmen zur Visualisierung */
|
||||
overflow: visible; /* Damit Punkte am Rand nicht abgeschnitten werden */
|
||||
}
|
||||
|
||||
.point {
|
||||
fill: #000000; /* Farbe der Punkte */
|
||||
opacity: 0.8; /* Punkte sichtbar machen */
|
||||
r: 3.5; /* Einheitliche Punktgröße */
|
||||
}
|
||||
|
||||
.line {
|
||||
fill: none; /* Keine Füllung für die Linie */
|
||||
stroke-width: 2; /* Dickere Hauptlinie */
|
||||
}
|
||||
|
||||
.offset-spline {
|
||||
fill: none;
|
||||
stroke-width: 1; /* Dickere mittlere Linien */
|
||||
stroke-opacity: 0.6; /* Angepasste Transparenz */
|
||||
transition: stroke-opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.offset-spline-far {
|
||||
fill: none;
|
||||
stroke-width: 1; /* Etwas dickere äußere Linien */
|
||||
stroke-opacity: 0.4; /* Höhere Transparenz */
|
||||
transition: stroke-opacity 0.3s ease;
|
||||
}
|
||||
.offset-spline-far-2 {
|
||||
fill: none;
|
||||
stroke-width: 1; /* Etwas dickere äußere Linien */
|
||||
stroke-opacity: 0.2; /* Höhere Transparenz */
|
||||
transition: stroke-opacity 0.3s ease;
|
||||
}
|
||||
|
||||
/* Steuerelemente für die Slider */
|
||||
.controls {
|
||||
margin-top: 20px;
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
width: 600px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.control-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.control-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.control-label {
|
||||
width: 140px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.control-slider {
|
||||
flex-grow: 1;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.control-value {
|
||||
width: 50px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.control-header {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 8px 15px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welleneffekt (SVG)</h1>
|
||||
|
||||
<svg width="600" height="200" id="point-canvas">
|
||||
<defs>
|
||||
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:rgb(226, 245, 172);stop-opacity:1" />
|
||||
<stop offset="35%" style="stop-color:rgb(135, 241, 36);stop-opacity:1" />
|
||||
<stop offset="70%" style="stop-color:rgb(62, 200, 232);stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:rgb(4, 162, 254);stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- Punkte und Linie werden hier per JavaScript hinzugefügt -->
|
||||
</svg>
|
||||
|
||||
<!-- Steuerelemente hinzufügen -->
|
||||
<div class="controls">
|
||||
<div class="control-header">Wellenanimation einstellen</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="control-row">
|
||||
<div class="control-label">Zeitfaktor:</div>
|
||||
<input type="range" id="time-factor" class="control-slider" min="0.2" max="3.0" step="0.1" value="1.0">
|
||||
<div class="control-value"><span id="time-factor-value">1.0</span></div>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<div class="control-label">Amplitude:</div>
|
||||
<input type="range" id="amplitude-factor" class="control-slider" min="0.2" max="3.0" step="0.1" value="1.0">
|
||||
<div class="control-value"><span id="amplitude-factor-value">1.0</span></div>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<div class="control-label">Turbulenz:</div>
|
||||
<input type="range" id="turbulence" class="control-slider" min="0" max="3" step="0.1" value="0.5">
|
||||
<div class="control-value"><span id="turbulence-value">0.5</span></div>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<div class="control-label">Geschwindigkeit:</div>
|
||||
<input type="range" id="animation-speed" class="control-slider" min="0.2" max="10.0" step="0.1" value="1.0">
|
||||
<div class="control-value"><span id="animation-speed-value">1.0</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-header">Linieneinstellungen</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="control-row">
|
||||
<div class="control-label">Linienanzahl:</div>
|
||||
<input type="range" id="total-lines" class="control-slider" min="4" max="24" step="1" value="12">
|
||||
<div class="control-value"><span id="total-lines-value">12</span></div>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<div class="control-label">Linienabstand:</div>
|
||||
<input type="range" id="line-offset" class="control-slider" min="5" max="30" step="1" value="12">
|
||||
<div class="control-value"><span id="line-offset-value">12</span></div>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<div class="control-label">Linienspannung:</div>
|
||||
<input type="range" id="tension" class="control-slider" min="0.5" max="5.0" step="0.1" value="1.5">
|
||||
<div class="control-value"><span id="tension-value">1.5</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="reset-button">Zurücksetzen</button>
|
||||
</div>
|
||||
|
||||
<!-- Anime.js wird vorerst nicht benötigt, kann aber später wieder eingebunden werden -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Konstanten und Konfigurationen
|
||||
const svg = document.getElementById('point-canvas');
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
let TENSION = 1.5;
|
||||
const MIN_OFFSET_FACTOR = 0.2;
|
||||
const OFFSET_NEAR = 5;
|
||||
let OFFSET_FAR = 12;
|
||||
let TOTAL_LINES = 12; // Mehr Linien für ein dichteres Aussehen
|
||||
|
||||
// Neue Variable für Animationsgeschwindigkeit
|
||||
let animationSpeed = 1.0;
|
||||
|
||||
// Variablen für die Animation
|
||||
let currentAnimation = null;
|
||||
let continuousAnimation = null;
|
||||
|
||||
// DOM-Elemente für Steuerelemente
|
||||
const timeFactorSlider = document.getElementById('time-factor');
|
||||
const timeFactorValue = document.getElementById('time-factor-value');
|
||||
const amplitudeFactorSlider = document.getElementById('amplitude-factor');
|
||||
const amplitudeFactorValue = document.getElementById('amplitude-factor-value');
|
||||
const turbulenceSlider = document.getElementById('turbulence');
|
||||
const turbulenceValue = document.getElementById('turbulence-value');
|
||||
const totalLinesSlider = document.getElementById('total-lines');
|
||||
const totalLinesValue = document.getElementById('total-lines-value');
|
||||
const lineOffsetSlider = document.getElementById('line-offset');
|
||||
const lineOffsetValue = document.getElementById('line-offset-value');
|
||||
const tensionSlider = document.getElementById('tension');
|
||||
const tensionValue = document.getElementById('tension-value');
|
||||
const animationSpeedSlider = document.getElementById('animation-speed');
|
||||
const animationSpeedValue = document.getElementById('animation-speed-value');
|
||||
const resetButton = document.getElementById('reset-button');
|
||||
|
||||
// Mouse-tracking Variablen
|
||||
let isMouseOver = false;
|
||||
let mouseX = 0;
|
||||
let mouseY = 0;
|
||||
|
||||
// Dynamische Faktoren
|
||||
let timeFactor = 1.0;
|
||||
let amplitudeFactor = 1.0;
|
||||
let turbulence = 0.5;
|
||||
|
||||
// Basispunkte definieren
|
||||
const points = [
|
||||
{ x: 20, y: 100 },
|
||||
{ x: 150, y: 60 },
|
||||
{ x: 300, y: 140 },
|
||||
{ x: 450, y: 60 },
|
||||
{ x: 580, y: 100 }
|
||||
];
|
||||
|
||||
// Speichern der DOM-Elemente für Punkte
|
||||
let pointElements = [];
|
||||
|
||||
// Container für Pfad-Referenzen
|
||||
const pathElements = {};
|
||||
|
||||
// Berechnet Normalen für alle Punkte
|
||||
function calculateNormals(points) {
|
||||
const normals = [];
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const p0 = i > 0 ? points[i - 1] : points[i];
|
||||
const p1 = points[i];
|
||||
const p2 = i < points.length - 1 ? points[i + 1] : points[i];
|
||||
|
||||
let dx = p2.x - p0.x;
|
||||
let dy = p2.y - p0.y;
|
||||
|
||||
// Tangente an Endpunkten approximieren
|
||||
if (i === 0) {
|
||||
dx = points[1].x - points[0].x;
|
||||
dy = points[1].y - points[0].y;
|
||||
} else if (i === points.length - 1) {
|
||||
dx = points[i].x - points[i-1].x;
|
||||
dy = points[i].y - points[i-1].y;
|
||||
}
|
||||
|
||||
const length = Math.sqrt(dx * dx + dy * dy);
|
||||
let normalX = 0, normalY = 0;
|
||||
|
||||
if (length > 0) {
|
||||
normalX = -dy / length;
|
||||
normalY = dx / length;
|
||||
}
|
||||
|
||||
normals.push({ x: normalX, y: normalY });
|
||||
}
|
||||
return normals;
|
||||
}
|
||||
|
||||
// Erzeugt Pfad mit variablem Offset
|
||||
function generateOffsetSplinePath(originalPoints, normals, offsetDistance) {
|
||||
if (originalPoints.length < 2) return "";
|
||||
|
||||
// Startpunkt des Offset-Pfades
|
||||
const startNormal = normals[0];
|
||||
const startOffsetX = originalPoints[0].x + startNormal.x * offsetDistance * MIN_OFFSET_FACTOR;
|
||||
const startOffsetY = originalPoints[0].y + startNormal.y * offsetDistance * MIN_OFFSET_FACTOR;
|
||||
let d = `M ${startOffsetX} ${startOffsetY}`;
|
||||
|
||||
for (let i = 0; i < originalPoints.length - 1; i++) {
|
||||
const p0 = i > 0 ? originalPoints[i - 1] : originalPoints[0];
|
||||
const p1 = originalPoints[i];
|
||||
const p2 = originalPoints[i + 1];
|
||||
const p3 = i < originalPoints.length - 2 ? originalPoints[i + 2] : originalPoints[originalPoints.length - 1];
|
||||
|
||||
// Originale Kontrollpunkte berechnen
|
||||
const cp1x = p1.x + (p2.x - p0.x) / 6 * TENSION;
|
||||
const cp1y = p1.y + (p2.y - p0.y) / 6 * TENSION;
|
||||
const cp2x = p2.x - (p3.x - p1.x) / 6 * TENSION;
|
||||
const cp2y = p2.y - (p3.y - p1.y) / 6 * TENSION;
|
||||
|
||||
// Normalen an den relevanten Punkten
|
||||
const n1 = normals[i];
|
||||
const n2 = normals[i+1];
|
||||
|
||||
// Offset-Kontrollpunkte und Endpunkt berechnen
|
||||
const offsetCp1x = cp1x + n1.x * offsetDistance;
|
||||
const offsetCp1y = cp1y + n1.y * offsetDistance;
|
||||
const offsetCp2x = cp2x + n2.x * offsetDistance;
|
||||
const offsetCp2y = cp2y + n2.y * offsetDistance;
|
||||
const offsetP2x = p2.x + n2.x * offsetDistance * MIN_OFFSET_FACTOR;
|
||||
const offsetP2y = p2.y + n2.y * offsetDistance * MIN_OFFSET_FACTOR;
|
||||
|
||||
// Füge kubisches Bézier-Segment hinzu
|
||||
d += ` C ${offsetCp1x} ${offsetCp1y}, ${offsetCp2x} ${offsetCp2y}, ${offsetP2x} ${offsetP2y}`;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Erstellt oder aktualisiert einen Pfad
|
||||
function updateOrCreatePath(existingPath, points, normals, offsetDistance, className) {
|
||||
const d = generateOffsetSplinePath(points, normals, offsetDistance);
|
||||
|
||||
if (existingPath) {
|
||||
existingPath.setAttribute('d', d);
|
||||
return existingPath;
|
||||
} else {
|
||||
const path = document.createElementNS(svgNS, 'path');
|
||||
path.setAttribute('class', className);
|
||||
path.setAttribute('stroke', 'url(#lineGradient)');
|
||||
path.setAttribute('d', d);
|
||||
svg.appendChild(path);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// Erstellt SVG-Punktelemente
|
||||
function createPoints(points) {
|
||||
return points.map(p => {
|
||||
const circle = document.createElementNS(svgNS, 'circle');
|
||||
circle.setAttribute('class', 'point');
|
||||
circle.setAttribute('cx', p.x);
|
||||
circle.setAttribute('cy', p.y);
|
||||
circle.setAttribute('r', 3.5);
|
||||
svg.appendChild(circle);
|
||||
return circle;
|
||||
});
|
||||
}
|
||||
|
||||
// Aktualisiert Punktpositionen
|
||||
function updatePointsVisualization(points, pointElements) {
|
||||
points.forEach((p, i) => {
|
||||
if (pointElements[i]) {
|
||||
pointElements[i].setAttribute('cx', p.x);
|
||||
pointElements[i].setAttribute('cy', p.y);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Hauptaktualisierungsfunktion für die Animation
|
||||
function updateVisualization() {
|
||||
const normals = calculateNormals(points);
|
||||
|
||||
// Zeit-basierter Animationsfaktor für die Offset-Linien
|
||||
const time = Date.now() / 1000;
|
||||
|
||||
// Füge turbulente Bewegung hinzu wenn Maus über SVG
|
||||
const turbulenceFactor = true ?
|
||||
turbulence * Math.sin(time * 3) :
|
||||
turbulence * 0.3 * Math.sin(time * 1.5);
|
||||
|
||||
// Zeichne die Hauptlinie
|
||||
pathElements.main = updateOrCreatePath(pathElements.main, points, normals, 0, 'line');
|
||||
|
||||
// Zeichne mehrere Offset-Linien in unterschiedlichen Abständen
|
||||
for (let i = 1; i <= TOTAL_LINES; i++) {
|
||||
// Berechne einen variablen Offset für jede Linie
|
||||
const offsetFactor = i / TOTAL_LINES;
|
||||
const maxOffset = OFFSET_FAR * 2.5;
|
||||
|
||||
|
||||
// Verschiedene dynamische Wellenkomponenten
|
||||
const primaryWave = Math.sin(time * timeFactor * 0.8 + i * 0.2) * 2 * amplitudeFactor;
|
||||
const secondaryWave = Math.cos(time * timeFactor * 0.5 + i * 0.3) * 2 * amplitudeFactor;
|
||||
const tertiaryWave = Math.sin(time * timeFactor * 1.2 + i * 0.15) * turbulenceFactor;
|
||||
|
||||
// Kombiniere alle Wellenkomponenten
|
||||
const wavePhase1 = primaryWave + tertiaryWave;
|
||||
const wavePhase2 = secondaryWave + tertiaryWave * 0.7;
|
||||
|
||||
// Positive Offsets (oberhalb der Hauptlinie)
|
||||
const offsetPositive = maxOffset * offsetFactor + wavePhase1;
|
||||
const className = offsetFactor < 0.3 ? 'offset-spline' :
|
||||
offsetFactor < 0.6 ? 'offset-spline-far' : 'offset-spline-far-2';
|
||||
|
||||
// Speichere jede Linie mit einem eindeutigen Schlüssel
|
||||
const keyPos = `line_pos_${i}`;
|
||||
pathElements[keyPos] = updateOrCreatePath(
|
||||
pathElements[keyPos],
|
||||
points,
|
||||
normals,
|
||||
offsetPositive,
|
||||
className
|
||||
);
|
||||
|
||||
// Negative Offsets (unterhalb der Hauptlinie)
|
||||
const offsetNegative = -maxOffset * offsetFactor + wavePhase2;
|
||||
const keyNeg = `line_neg_${i}`;
|
||||
pathElements[keyNeg] = updateOrCreatePath(
|
||||
pathElements[keyNeg],
|
||||
points,
|
||||
normals,
|
||||
offsetNegative,
|
||||
className
|
||||
);
|
||||
}
|
||||
|
||||
// Aktualisiere Punkte
|
||||
updatePointsVisualization(points, pointElements);
|
||||
|
||||
// Alle Punkteelemente nach vorne bringen
|
||||
pointElements.forEach(p => svg.appendChild(p));
|
||||
}
|
||||
|
||||
// Animation starten
|
||||
function startAnimation() {
|
||||
// Alle bestehenden Animationen stoppen
|
||||
if (currentAnimation) anime.remove(currentAnimation);
|
||||
if (continuousAnimation) anime.remove(continuousAnimation);
|
||||
|
||||
// Basis-Animation
|
||||
currentAnimation = anime({
|
||||
targets: points,
|
||||
y: function(p, i) {
|
||||
const baseY = [100, 60, 140, 60, 100][i];
|
||||
return baseY;
|
||||
},
|
||||
duration: 100 / animationSpeed,
|
||||
direction: 'alternate',
|
||||
loop: true,
|
||||
easing: 'easeInOutSine',
|
||||
delay: anime.stagger(100 / animationSpeed),
|
||||
update: updateVisualization,
|
||||
complete: startContinuousAnimation
|
||||
});
|
||||
}
|
||||
|
||||
// Kontinuierliche wellenförmige Animation
|
||||
function startContinuousAnimation() {
|
||||
// Stoppen einer möglicherweise noch laufenden Animation
|
||||
if (continuousAnimation) anime.remove(continuousAnimation);
|
||||
|
||||
continuousAnimation = anime({
|
||||
targets: points,
|
||||
y: function(p, i) {
|
||||
const baseY = i % 2 === 0 ? 100 : i % 3 === 0 ? 60 : 140;
|
||||
const amplitude = 20;
|
||||
return function() {
|
||||
// Komplexere Wellenbewegung mit mehreren Frequenzen und dynamischen Faktoren
|
||||
const t = Date.now() / 1000 * animationSpeed; // Direkte Multiplikation der Zeit mit der Geschwindigkeit
|
||||
|
||||
// Berechne dynamische Amplitude basierend auf Position und Zeit
|
||||
const dynamicAmplitude = amplitude * amplitudeFactor;
|
||||
|
||||
// Mehrere überlagerte Wellen mit dynamischen Faktoren
|
||||
const wave1 = dynamicAmplitude * Math.sin(t * timeFactor * 0.8 + i * 0.7);
|
||||
const wave2 = dynamicAmplitude/2 * Math.sin(t * timeFactor * 1.2 + i * 0.5);
|
||||
const wave3 = dynamicAmplitude/4 * Math.sin(t * timeFactor * 2.1 + i * 0.3);
|
||||
|
||||
// Füge Mauseinfluss hinzu wenn Maus über dem SVG
|
||||
let mouseEffect = 0;
|
||||
if (isMouseOver) {
|
||||
const dx = p.x - mouseX;
|
||||
const distanceFactor = Math.max(0, 1 - Math.abs(dx) / 200);
|
||||
mouseEffect = (mouseY - baseY) * distanceFactor * 0.3;
|
||||
}
|
||||
|
||||
return baseY + wave1 + wave2 + wave3 + mouseEffect;
|
||||
};
|
||||
},
|
||||
duration: (1000 / animationSpeed),
|
||||
autoplay: true,
|
||||
easing: 'linear',
|
||||
loop: true,
|
||||
update: function() {
|
||||
requestAnimationFrame(updateVisualization);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Event-Listener für Steuerelemente
|
||||
function setupControlListeners() {
|
||||
// Zeitfaktor
|
||||
timeFactorSlider.addEventListener('input', function() {
|
||||
timeFactor = parseFloat(this.value);
|
||||
timeFactorValue.textContent = timeFactor.toFixed(1);
|
||||
});
|
||||
|
||||
// Amplitudenfaktor
|
||||
amplitudeFactorSlider.addEventListener('input', function() {
|
||||
amplitudeFactor = parseFloat(this.value);
|
||||
amplitudeFactorValue.textContent = amplitudeFactor.toFixed(1);
|
||||
});
|
||||
|
||||
// Turbulenz
|
||||
turbulenceSlider.addEventListener('input', function() {
|
||||
turbulence = parseFloat(this.value);
|
||||
turbulenceValue.textContent = turbulence.toFixed(1);
|
||||
});
|
||||
|
||||
// Animationsgeschwindigkeit
|
||||
animationSpeedSlider.addEventListener('input', function() {
|
||||
const newSpeed = parseFloat(this.value);
|
||||
|
||||
// Nur aktualisieren, wenn sich der Wert tatsächlich ändert
|
||||
if (newSpeed !== animationSpeed) {
|
||||
animationSpeed = newSpeed;
|
||||
animationSpeedValue.textContent = animationSpeed.toFixed(1);
|
||||
// Animation komplett neu starten, um Geschwindigkeitsänderungen zu übernehmen
|
||||
anime.remove(points);
|
||||
if (currentAnimation) anime.remove(currentAnimation);
|
||||
if (continuousAnimation) anime.remove(continuousAnimation);
|
||||
startAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
// Gesamtanzahl der Linien
|
||||
totalLinesSlider.addEventListener('input', function() {
|
||||
TOTAL_LINES = parseInt(this.value);
|
||||
totalLinesValue.textContent = TOTAL_LINES;
|
||||
|
||||
// Bestehende Linien entfernen, die nicht mehr benötigt werden
|
||||
for (let key in pathElements) {
|
||||
if (key.startsWith('line_pos_') || key.startsWith('line_neg_')) {
|
||||
const lineNum = parseInt(key.split('_').pop());
|
||||
if (lineNum > TOTAL_LINES) {
|
||||
if (pathElements[key].parentNode) {
|
||||
pathElements[key].parentNode.removeChild(pathElements[key]);
|
||||
}
|
||||
delete pathElements[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Linienabstand
|
||||
lineOffsetSlider.addEventListener('input', function() {
|
||||
OFFSET_FAR = parseInt(this.value);
|
||||
lineOffsetValue.textContent = OFFSET_FAR;
|
||||
});
|
||||
|
||||
// Linienspannung
|
||||
tensionSlider.addEventListener('input', function() {
|
||||
TENSION = parseFloat(this.value);
|
||||
tensionValue.textContent = TENSION.toFixed(1);
|
||||
});
|
||||
|
||||
// Zurücksetzen-Button
|
||||
resetButton.addEventListener('click', function() {
|
||||
// Standardwerte wiederherstellen
|
||||
timeFactorSlider.value = 1.0;
|
||||
amplitudeFactorSlider.value = 1.0;
|
||||
turbulenceSlider.value = 0.5;
|
||||
totalLinesSlider.value = 12;
|
||||
lineOffsetSlider.value = 12;
|
||||
tensionSlider.value = 1.5;
|
||||
animationSpeedSlider.value = 1.0;
|
||||
|
||||
// UI-Werte aktualisieren
|
||||
timeFactorValue.textContent = "1.0";
|
||||
amplitudeFactorValue.textContent = "1.0";
|
||||
turbulenceValue.textContent = "0.5";
|
||||
totalLinesValue.textContent = "12";
|
||||
lineOffsetValue.textContent = "12";
|
||||
tensionValue.textContent = "1.5";
|
||||
animationSpeedValue.textContent = "1.0";
|
||||
|
||||
// Variablen zurücksetzen
|
||||
timeFactor = 1.0;
|
||||
amplitudeFactor = 1.0;
|
||||
turbulence = 0.5;
|
||||
TOTAL_LINES = 12;
|
||||
OFFSET_FAR = 12;
|
||||
TENSION = 1.5;
|
||||
animationSpeed = 1.0;
|
||||
|
||||
// Animation neu starten
|
||||
anime.remove(points);
|
||||
if (currentAnimation) anime.remove(currentAnimation);
|
||||
if (continuousAnimation) anime.remove(continuousAnimation);
|
||||
startAnimation();
|
||||
});
|
||||
|
||||
// Mouse-Tracking für SVG
|
||||
svg.addEventListener('mouseover', function() {
|
||||
isMouseOver = true;
|
||||
});
|
||||
|
||||
svg.addEventListener('mouseout', function() {
|
||||
isMouseOver = false;
|
||||
});
|
||||
|
||||
svg.addEventListener('mousemove', function(e) {
|
||||
const rect = svg.getBoundingClientRect();
|
||||
mouseX = e.clientX - rect.left;
|
||||
mouseY = e.clientY - rect.top;
|
||||
});
|
||||
}
|
||||
|
||||
// Initialisierung
|
||||
function init() {
|
||||
pointElements = createPoints(points);
|
||||
setupControlListeners();
|
||||
updateVisualization();
|
||||
startAnimation();
|
||||
}
|
||||
|
||||
// Starte die Anwendung
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue