Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions love14/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Glowing Heart Animation

A beautiful, interactive heart animation created with HTML, CSS, and JavaScript. This project features a multi-layered glowing blue heart with dynamic effects and interactive elements.

## Features

- **Multi-layered Heart Design**: 5 concentric heart layers with different sizes and opacity levels
- **Glowing Effects**: CSS box-shadow and border effects create a beautiful blue glow
- **Pulsing Animation**: Smooth scale and opacity animations with staggered timing
- **Interactive Elements**:
- Click hearts to create burst particle effects
- Play/pause button to control animation
- Mouse movement creates subtle parallax effects
- Touch support for mobile devices
- **Responsive Design**: Adapts to different screen sizes
- **Keyboard Controls**: Spacebar to pause/resume, R to reset

## File Structure

```
love14/
├── index.html # Main HTML structure
├── style.css # CSS styles and animations
├── script.js # JavaScript interactivity
└── README.md # This file
```

## How to Run

1. **Simple Method**: Open `index.html` directly in a web browser
2. **Local Server** (Recommended):
- Use a local server like Live Server in VS Code
- Or run: `python -m http.server 3000` in the project directory
- Then visit: `http://localhost:3000/love14/index.html`

## Code Analysis

### HTML Structure (`index.html`)
- Clean, semantic HTML5 structure
- Container div for centering and positioning
- Multiple heart divs with different classes for layering
- Play button with icon for user interaction

### CSS Styling (`style.css`)
- **Heart Creation**: Uses CSS pseudo-elements (`::before`, `::after`) to create heart shapes from squares
- **Layering System**: 5 heart layers with decreasing sizes and increasing opacity
- **Animation**: CSS `@keyframes` for smooth pulsing effect with staggered delays
- **Glow Effects**: Multiple `box-shadow` properties create the glowing appearance
- **Responsive Design**: Media queries for mobile optimization

### JavaScript Functionality (`script.js`)
- **Event Listeners**: Handles clicks, mouse movement, keyboard input, and touch events
- **Particle System**: Creates burst effects when hearts are clicked
- **Animation Control**: Play/pause functionality with visual feedback
- **Parallax Effect**: Subtle movement based on mouse position
- **Touch Support**: Different behaviors for short taps vs long presses
- **Random Effects**: Periodic sparkle animations for added visual interest

## Technical Details

### Heart Shape Creation
The heart shape is created using CSS by:
1. Starting with a square element rotated 45 degrees
2. Adding two circular pseudo-elements positioned to form the heart curves
3. Using `border-radius: 50%` to create the circular parts

### Animation System
- Uses CSS `animation` property with `ease-in-out` timing
- Staggered delays create a wave-like pulsing effect
- JavaScript controls animation state (play/pause)

### Performance Optimizations
- Uses CSS transforms for smooth animations
- Efficient event handling with proper cleanup
- Minimal DOM manipulation for particle effects

## Browser Compatibility

- Modern browsers with CSS3 and ES6 support
- Mobile browsers with touch event support
- Tested on Chrome, Firefox, Safari, and Edge

## Customization

You can easily customize the animation by modifying:
- Colors in the CSS (change `rgba(0, 150, 255, ...)` values)
- Animation timing in the CSS `@keyframes`
- Number of heart layers by adding/removing HTML elements
- Particle effects in the JavaScript

## License

This project is open source and available under the MIT License.
24 changes: 24 additions & 0 deletions love14/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Glowing Heart Animation</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="heart-container">
<div class="heart heart-1"></div>
<div class="heart heart-2"></div>
<div class="heart heart-3"></div>
<div class="heart heart-4"></div>
<div class="heart heart-5"></div>
<div class="play-button">
<div class="play-icon"></div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
213 changes: 213 additions & 0 deletions love14/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// Heart Animation JavaScript
document.addEventListener('DOMContentLoaded', function() {
const hearts = document.querySelectorAll('.heart');
const playButton = document.querySelector('.play-button');
const container = document.querySelector('.container');

// Add click effect to hearts
hearts.forEach(heart => {
heart.addEventListener('click', function() {
createHeartBurst(this);
});
});

// Play button functionality
playButton.addEventListener('click', function() {
toggleAnimation();
});

// Add mouse move effect
container.addEventListener('mousemove', function(e) {
const rect = container.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;

// Create subtle parallax effect
hearts.forEach((heart, index) => {
const speed = (index + 1) * 0.02;
const moveX = (x - rect.width / 2) * speed;
const moveY = (y - rect.height / 2) * speed;

heart.style.transform = `rotate(-45deg) translate(${moveX}px, ${moveY}px)`;
});
});

// Create heart burst effect
function createHeartBurst(heart) {
for (let i = 0; i < 8; i++) {
const particle = document.createElement('div');
particle.className = 'heart-particle';
particle.style.cssText = `
position: absolute;
width: 10px;
height: 10px;
background: rgba(0, 150, 255, 0.8);
border-radius: 50%;
pointer-events: none;
z-index: 1000;
`;

const angle = (i * 45) * Math.PI / 180;
const distance = 50;
const startX = heart.offsetLeft + heart.offsetWidth / 2;
const startY = heart.offsetTop + heart.offsetHeight / 2;

particle.style.left = startX + 'px';
particle.style.top = startY + 'px';

container.appendChild(particle);

// Animate particle
setTimeout(() => {
const endX = startX + Math.cos(angle) * distance;
const endY = startY + Math.sin(angle) * distance;

particle.style.transition = 'all 0.5s ease-out';
particle.style.left = endX + 'px';
particle.style.top = endY + 'px';
particle.style.opacity = '0';
particle.style.transform = 'scale(0)';

setTimeout(() => {
container.removeChild(particle);
}, 500);
}, 10);
}
}

// Toggle animation
function toggleAnimation() {
const isPaused = hearts[0].style.animationPlayState === 'paused';

hearts.forEach(heart => {
heart.style.animationPlayState = isPaused ? 'running' : 'paused';
});

// Change play button icon
const playIcon = playButton.querySelector('.play-icon');
if (isPaused) {
playIcon.style.borderLeft = '15px solid rgba(255, 255, 255, 0.8)';
playIcon.style.borderTop = '10px solid transparent';
playIcon.style.borderBottom = '10px solid transparent';
} else {
playIcon.style.borderLeft = 'none';
playIcon.style.borderTop = 'none';
playIcon.style.borderBottom = 'none';
playIcon.style.border = '2px solid rgba(255, 255, 255, 0.8)';
playIcon.style.width = '20px';
playIcon.style.height = '20px';
}
}

// Add keyboard controls
document.addEventListener('keydown', function(e) {
switch(e.key) {
case ' ':
e.preventDefault();
toggleAnimation();
break;
case 'r':
case 'R':
resetAnimation();
break;
}
});

// Reset animation
function resetAnimation() {
hearts.forEach(heart => {
heart.style.animation = 'none';
heart.offsetHeight; // Trigger reflow
heart.style.animation = null;
});
}

// Add touch support for mobile
let touchStartTime = 0;
container.addEventListener('touchstart', function(e) {
touchStartTime = Date.now();
});

container.addEventListener('touchend', function(e) {
const touchEndTime = Date.now();
const touchDuration = touchEndTime - touchStartTime;

if (touchDuration < 200) {
// Short tap - create burst
const touch = e.changedTouches[0];
const element = document.elementFromPoint(touch.clientX, touch.clientY);
if (element && element.classList.contains('heart')) {
createHeartBurst(element);
}
} else {
// Long press - toggle animation
toggleAnimation();
}
});

// Add window resize handler
window.addEventListener('resize', function() {
// Reset any transform effects
hearts.forEach(heart => {
heart.style.transform = 'rotate(-45deg)';
});
});

// Add some random sparkle effects
setInterval(() => {
if (Math.random() < 0.3) {
createRandomSparkle();
}
}, 2000);

function createRandomSparkle() {
const sparkle = document.createElement('div');
sparkle.style.cssText = `
position: absolute;
width: 4px;
height: 4px;
background: rgba(0, 150, 255, 1);
border-radius: 50%;
pointer-events: none;
z-index: 999;
left: ${Math.random() * 100}%;
top: ${Math.random() * 100}%;
animation: sparkle 1s ease-out forwards;
`;

container.appendChild(sparkle);

setTimeout(() => {
if (container.contains(sparkle)) {
container.removeChild(sparkle);
}
}, 1000);
}

// Add sparkle animation to CSS
const style = document.createElement('style');
style.textContent = `
@keyframes sparkle {
0% {
transform: scale(0) rotate(0deg);
opacity: 1;
}
50% {
transform: scale(1) rotate(180deg);
opacity: 1;
}
100% {
transform: scale(0) rotate(360deg);
opacity: 0;
}
}
`;
document.head.appendChild(style);

console.log('Heart animation loaded successfully!');
console.log('Controls:');
console.log('- Click hearts to create burst effects');
console.log('- Click play button or press SPACE to pause/resume');
console.log('- Press R to reset animation');
console.log('- Long press on mobile to toggle animation');
});
Loading