You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
275 lines
9.4 KiB
275 lines
9.4 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Butterfly Wing Flapping Test</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 50px;
|
|
background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
font-family: Arial, sans-serif;
|
|
}
|
|
|
|
.container {
|
|
text-align: center;
|
|
}
|
|
|
|
.butterfly {
|
|
width: 200px;
|
|
height: 160px;
|
|
position: relative;
|
|
margin: 50px auto;
|
|
}
|
|
|
|
/* Simple synchronized wing flapping - like reference images */
|
|
@keyframes wingFlapLeft {
|
|
0% {
|
|
transform: rotateZ(-20deg);
|
|
}
|
|
50% {
|
|
transform: rotateZ(-70deg);
|
|
}
|
|
100% {
|
|
transform: rotateZ(-20deg);
|
|
}
|
|
}
|
|
|
|
@keyframes wingFlapRight {
|
|
0% {
|
|
transform: rotateZ(20deg);
|
|
}
|
|
50% {
|
|
transform: rotateZ(70deg);
|
|
}
|
|
100% {
|
|
transform: rotateZ(20deg);
|
|
}
|
|
}
|
|
|
|
.wing-left {
|
|
transform-origin: 70px 80px; /* Where wing attaches to body */
|
|
animation: wingFlapLeft 0.6s ease-in-out infinite;
|
|
}
|
|
|
|
.wing-right {
|
|
transform-origin: 130px 80px; /* Where wing attaches to body */
|
|
animation: wingFlapRight 0.6s ease-in-out infinite;
|
|
}
|
|
|
|
/* Test different speeds */
|
|
.butterfly.slow .wing-left,
|
|
.butterfly.slow .wing-right {
|
|
animation-duration: 1.2s;
|
|
}
|
|
|
|
.butterfly.fast .wing-left,
|
|
.butterfly.fast .wing-right {
|
|
animation-duration: 0.3s;
|
|
}
|
|
|
|
.controls {
|
|
margin: 20px 0;
|
|
}
|
|
|
|
button {
|
|
margin: 0 10px;
|
|
padding: 10px 20px;
|
|
border: 2px solid #1976d2;
|
|
background: white;
|
|
color: #1976d2;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-weight: bold;
|
|
}
|
|
|
|
button.active {
|
|
background: #1976d2;
|
|
color: white;
|
|
}
|
|
|
|
h1 {
|
|
color: #333;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
p {
|
|
color: #666;
|
|
margin: 5px 0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🦋 Butterfly Wing Flapping Test</h1>
|
|
<p>Testing different wing flapping animations with 3D rotation</p>
|
|
|
|
<div class="butterfly" id="butterfly">
|
|
<svg viewBox="0 0 200 160" width="200" height="160">
|
|
<!-- Wing gradients -->
|
|
<defs>
|
|
<radialGradient id="morphoBlue" cx="50%" cy="30%" r="70%">
|
|
<stop offset="0%" style="stop-color: #00D4FF; stop-opacity: 1" />
|
|
<stop offset="40%" style="stop-color: #0099CC; stop-opacity: 1" />
|
|
<stop offset="80%" style="stop-color: #003366; stop-opacity: 1" />
|
|
<stop offset="100%" style="stop-color: #001122; stop-opacity: 1" />
|
|
</radialGradient>
|
|
|
|
<radialGradient id="morphoBlueSecondary" cx="50%" cy="30%" r="70%">
|
|
<stop offset="0%" style="stop-color: #33AAFF; stop-opacity: 1" />
|
|
<stop offset="40%" style="stop-color: #0077AA; stop-opacity: 1" />
|
|
<stop offset="80%" style="stop-color: #002244; stop-opacity: 1" />
|
|
<stop offset="100%" style="stop-color: #000D1A; stop-opacity: 1" />
|
|
</radialGradient>
|
|
|
|
<linearGradient id="bodyGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
<stop offset="0%" style="stop-color: #2D1B1B; stop-opacity: 1" />
|
|
<stop offset="50%" style="stop-color: #1A0F0F; stop-opacity: 1" />
|
|
<stop offset="100%" style="stop-color: #0D0505; stop-opacity: 1" />
|
|
</linearGradient>
|
|
|
|
<filter id="glow">
|
|
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
|
<feMerge>
|
|
<feMergeNode in="coloredBlur"/>
|
|
<feMergeNode in="SourceGraphic"/>
|
|
</feMerge>
|
|
</filter>
|
|
</defs>
|
|
|
|
<!-- Left wings -->
|
|
<g class="wing-left">
|
|
<!-- Left upper wing -->
|
|
<path
|
|
d="M70 80 Q30 50 15 30 Q10 20 15 15 Q30 10 50 25 Q64 40 70 60 Z"
|
|
fill="url(#morphoBlue)"
|
|
stroke="#001122"
|
|
stroke-width="1"
|
|
filter="url(#glow)"
|
|
/>
|
|
|
|
<!-- Left lower wing -->
|
|
<path
|
|
d="M70 80 Q40 100 25 120 Q15 130 20 135 Q30 145 50 125 Q64 105 70 90 Z"
|
|
fill="url(#morphoBlueSecondary)"
|
|
stroke="#001122"
|
|
stroke-width="1"
|
|
filter="url(#glow)"
|
|
/>
|
|
|
|
<!-- Wing spots -->
|
|
<circle cx="45" cy="40" r="4" fill="#00AAFF" opacity="0.7" />
|
|
<circle cx="35" cy="55" r="3" fill="#33BBFF" opacity="0.6" />
|
|
<circle cx="50" cy="110" r="3.5" fill="#00AAFF" opacity="0.7" />
|
|
</g>
|
|
|
|
<!-- Right wings -->
|
|
<g class="wing-right">
|
|
<!-- Right upper wing -->
|
|
<path
|
|
d="M130 80 Q170 50 185 30 Q190 20 185 15 Q170 10 150 25 Q136 40 130 60 Z"
|
|
fill="url(#morphoBlue)"
|
|
stroke="#001122"
|
|
stroke-width="1"
|
|
filter="url(#glow)"
|
|
/>
|
|
|
|
<!-- Right lower wing -->
|
|
<path
|
|
d="M130 80 Q160 100 175 120 Q185 130 180 135 Q170 145 150 125 Q136 105 130 90 Z"
|
|
fill="url(#morphoBlueSecondary)"
|
|
stroke="#001122"
|
|
stroke-width="1"
|
|
filter="url(#glow)"
|
|
/>
|
|
|
|
<!-- Wing spots -->
|
|
<circle cx="155" cy="40" r="4" fill="#00AAFF" opacity="0.7" />
|
|
<circle cx="165" cy="55" r="3" fill="#33BBFF" opacity="0.6" />
|
|
<circle cx="150" cy="110" r="3.5" fill="#00AAFF" opacity="0.7" />
|
|
</g>
|
|
|
|
<!-- Butterfly body -->
|
|
<ellipse
|
|
cx="100"
|
|
cy="80"
|
|
rx="6"
|
|
ry="50"
|
|
fill="url(#bodyGradient)"
|
|
stroke="#0D0505"
|
|
stroke-width="1"
|
|
/>
|
|
|
|
<!-- Head -->
|
|
<circle
|
|
cx="100"
|
|
cy="40"
|
|
r="8"
|
|
fill="#2D1B1B"
|
|
stroke="#0D0505"
|
|
stroke-width="1"
|
|
/>
|
|
|
|
<!-- Antennae -->
|
|
<path
|
|
d="M95 35 Q90 25 85 15"
|
|
stroke="#2D1B1B"
|
|
stroke-width="2"
|
|
fill="none"
|
|
stroke-linecap="round"
|
|
/>
|
|
<path
|
|
d="M105 35 Q110 25 115 15"
|
|
stroke="#2D1B1B"
|
|
stroke-width="2"
|
|
fill="none"
|
|
stroke-linecap="round"
|
|
/>
|
|
|
|
<!-- Antennae tips -->
|
|
<circle cx="85" cy="15" r="2" fill="#2D1B1B" />
|
|
<circle cx="115" cy="15" r="2" fill="#2D1B1B" />
|
|
|
|
<!-- Eyes -->
|
|
<circle cx="93" cy="35" r="2" fill="#000" />
|
|
<circle cx="107" cy="35" r="2" fill="#000" />
|
|
<circle cx="93" cy="35" r="1" fill="#FFF" opacity="0.6" />
|
|
<circle cx="107" cy="35" r="1" fill="#FFF" opacity="0.6" />
|
|
</svg>
|
|
</div>
|
|
|
|
<div class="controls">
|
|
<p>Wing Flapping Speed:</p>
|
|
<button class="active" onclick="setSpeed('normal')">Normal (0.6s)</button>
|
|
<button onclick="setSpeed('slow')">Slow (1.2s)</button>
|
|
<button onclick="setSpeed('fast')">Fast (0.3s)</button>
|
|
</div>
|
|
|
|
<p>Watch the wings! They should flap up and down with 3D rotation.</p>
|
|
</div>
|
|
|
|
<script>
|
|
function setSpeed(speed) {
|
|
const butterfly = document.getElementById('butterfly');
|
|
const buttons = document.querySelectorAll('button');
|
|
|
|
// Remove all speed classes
|
|
butterfly.classList.remove('slow', 'fast');
|
|
buttons.forEach(btn => btn.classList.remove('active'));
|
|
|
|
// Add new speed class
|
|
if (speed !== 'normal') {
|
|
butterfly.classList.add(speed);
|
|
}
|
|
|
|
// Mark active button
|
|
event.target.classList.add('active');
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |