@sarthak03dot/romantic-animations 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # romantic-animations 💖
2
+
3
+ A beautiful JavaScript library for romantic particle effects such as floating hearts, heart trails, love bursts, and more. Perfect for Valentine's Day, wedding websites, or any love-themed project.
4
+
5
+ ## ✨ Features
6
+ - ❤️ Floating hearts animation
7
+ - 💘 Easy to integrate
8
+ - 📦 Zero dependencies
9
+ - ⚙️ Fully customizable (soon)
10
+
11
+ ## 📦 Installation
12
+ ```bash
13
+ npm install romantic-animations
14
+ ```
15
+
16
+ ## 🚀 Usage
17
+ ```html
18
+ <div id="animation-container"></div>
19
+ <script type="module">
20
+ import { startFloatingHearts } from 'romantic-animations';
21
+ startFloatingHearts("animation-container");
22
+ </script>
23
+ ```
24
+
25
+ ## 📁 File Structure
26
+ - `src/` – core engine and animation modules
27
+ - `demo/` – live preview setup using Vite
28
+ - `package.json` – npm config
29
+
30
+ ## 🔮 Upcoming
31
+ - 💫 Cursor heart trails
32
+ - 🎉 Love confetti bursts
33
+ - 🌈 Color customization
34
+ - 🎨 Preset themes
35
+
36
+ ## 🧑‍💻 Author
37
+ Made with ❤️ by **Sarthak Singh**
38
+
39
+ ## 📄 License
40
+ MIT
package/gitignore ADDED
@@ -0,0 +1,23 @@
1
+ # Ignore build output
2
+ dist/
3
+ node_modules/
4
+ demo
5
+
6
+ # Ignore Vite preview folder
7
+ .vite/
8
+
9
+ # Ignore logs
10
+ npm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+
14
+ # Ignore environment files
15
+ .env
16
+ .env.*
17
+
18
+ # Ignore IDE/editor files
19
+ .vscode/
20
+ .idea/
21
+
22
+ # Ignore demo files (optional for npm publish)
23
+ demo/
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@sarthak03dot/romantic-animations",
3
+ "version": "1.0.2",
4
+ "description": "Romantic animations like hearts, sparkles, trails",
5
+ "homepage": "https://github.com/sarthak03dot/romantic-animations#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/sarthak03dot/romantic-animations/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/sarthak03dot/romantic-animations.git"
12
+ },
13
+ "license": "ISC",
14
+ "keywords": [
15
+ "romantic",
16
+ "heart",
17
+ "animation",
18
+ "canvas"
19
+ ],
20
+ "author": "Sarthak Singh",
21
+ "type": "commonjs",
22
+ "main": "vite.config.js",
23
+ "scripts": {
24
+ "start": "vite",
25
+ "build": "vite build"
26
+ },
27
+ "devDependencies": {
28
+ "vite": "^7.0.2"
29
+ }
30
+ }
@@ -0,0 +1,35 @@
1
+ export function floatingHearts(canvas) {
2
+ const ctx = canvas.getContext("2d");
3
+ const hearts = [];
4
+
5
+ function createHeart() {
6
+ return {
7
+ x: Math.random() * canvas.width,
8
+ y: canvas.height + 20,
9
+ size: 20 + Math.random() * 10,
10
+ speed: 1 + Math.random() * 2,
11
+ };
12
+ }
13
+
14
+ function drawHeart(h) {
15
+ ctx.fillStyle = "pink";
16
+ ctx.beginPath();
17
+ ctx.moveTo(h.x, h.y);
18
+ ctx.bezierCurveTo(h.x + h.size / 2, h.y - h.size, h.x + h.size, h.y + h.size / 3, h.x, h.y + h.size);
19
+ ctx.bezierCurveTo(h.x - h.size, h.y + h.size / 3, h.x - h.size / 2, h.y - h.size, h.x, h.y);
20
+ ctx.fill();
21
+ }
22
+
23
+ function animate() {
24
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
25
+ if (Math.random() < 0.1) hearts.push(createHeart());
26
+ for (let i = 0; i < hearts.length; i++) {
27
+ hearts[i].y -= hearts[i].speed;
28
+ drawHeart(hearts[i]);
29
+ }
30
+ requestAnimationFrame(animate);
31
+ }
32
+
33
+ animate();
34
+ }
35
+
@@ -0,0 +1,56 @@
1
+ export function heartBurst(canvas) {
2
+ const ctx = canvas.getContext("2d");
3
+ const bursts = [];
4
+
5
+ function createHeart(x, y) {
6
+ const angle = Math.random() * Math.PI * 2;
7
+ const speed = 2 + Math.random() * 3;
8
+ return {
9
+ x,
10
+ y,
11
+ size: 10 + Math.random() * 5,
12
+ vx: Math.cos(angle) * speed,
13
+ vy: Math.sin(angle) * speed,
14
+ alpha: 1,
15
+ decay: 0.02
16
+ };
17
+ }
18
+
19
+ function drawHeart(h) {
20
+ ctx.fillStyle = `rgba(255, 20, 147, ${h.alpha})`;
21
+ ctx.beginPath();
22
+ ctx.moveTo(h.x, h.y);
23
+ ctx.bezierCurveTo(h.x + h.size / 2, h.y - h.size, h.x + h.size, h.y + h.size / 3, h.x, h.y + h.size);
24
+ ctx.bezierCurveTo(h.x - h.size, h.y + h.size / 3, h.x - h.size / 2, h.y - h.size, h.x, h.y);
25
+ ctx.fill();
26
+ }
27
+
28
+ canvas.addEventListener("click", (e) => {
29
+ const rect = canvas.getBoundingClientRect();
30
+ const burst = [];
31
+ for (let i = 0; i < 20; i++) {
32
+ burst.push(createHeart(e.clientX - rect.left, e.clientY - rect.top));
33
+ }
34
+ bursts.push(burst);
35
+ });
36
+
37
+ function animate() {
38
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
39
+ for (let b = bursts.length - 1; b >= 0; b--) {
40
+ const burst = bursts[b];
41
+ for (let i = burst.length - 1; i >= 0; i--) {
42
+ const h = burst[i];
43
+ h.x += h.vx;
44
+ h.y += h.vy;
45
+ h.alpha -= h.decay;
46
+ drawHeart(h);
47
+ if (h.alpha <= 0) burst.splice(i, 1);
48
+ }
49
+ if (burst.length === 0) bursts.splice(b, 1);
50
+ }
51
+ requestAnimationFrame(animate);
52
+ }
53
+
54
+ animate();
55
+ }
56
+
@@ -0,0 +1,41 @@
1
+ export function heartTrail(canvas) {
2
+ const ctx = canvas.getContext("2d");
3
+ const hearts = [];
4
+
5
+ function createHeart(x, y) {
6
+ return {
7
+ x,
8
+ y,
9
+ size: 8 + Math.random() * 5,
10
+ alpha: 1,
11
+ decay: 0.02
12
+ };
13
+ }
14
+
15
+ function drawHeart(h) {
16
+ ctx.fillStyle = `rgba(255, 105, 180, ${h.alpha})`;
17
+ ctx.beginPath();
18
+ ctx.moveTo(h.x, h.y);
19
+ ctx.bezierCurveTo(h.x + h.size / 2, h.y - h.size, h.x + h.size, h.y + h.size / 3, h.x, h.y + h.size);
20
+ ctx.bezierCurveTo(h.x - h.size, h.y + h.size / 3, h.x - h.size / 2, h.y - h.size, h.x, h.y);
21
+ ctx.fill();
22
+ }
23
+
24
+ canvas.addEventListener("mousemove", (e) => {
25
+ const rect = canvas.getBoundingClientRect();
26
+ hearts.push(createHeart(e.clientX - rect.left, e.clientY - rect.top));
27
+ });
28
+
29
+ function animate() {
30
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
31
+ for (let i = hearts.length - 1; i >= 0; i--) {
32
+ drawHeart(hearts[i]);
33
+ hearts[i].alpha -= hearts[i].decay;
34
+ if (hearts[i].alpha <= 0) hearts.splice(i, 1);
35
+ }
36
+ requestAnimationFrame(animate);
37
+ }
38
+
39
+ animate();
40
+ }
41
+
@@ -0,0 +1,13 @@
1
+ export function initCanvas(containerId) {
2
+ const container = document.getElementById(containerId);
3
+ const canvas = document.createElement('canvas');
4
+ canvas.width = container.offsetWidth;
5
+ canvas.height = container.offsetHeight;
6
+ canvas.style.position = 'absolute';
7
+ canvas.style.top = 0;
8
+ canvas.style.left = 0;
9
+ canvas.style.pointerEvents = 'none';
10
+ container.appendChild(canvas);
11
+ return canvas;
12
+ }
13
+
package/src/index.js ADDED
@@ -0,0 +1,19 @@
1
+ import { initCanvas } from "./core/engine.js";
2
+ import { floatingHearts } from "./animations/floatingHearts.js";
3
+ import { heartTrail } from "./animations/heartTrail.js";
4
+ import { heartBurst } from "./animations/heartBurst.js";
5
+
6
+ export function startFloatingHearts(containerId = 'body') {
7
+ const canvas = initCanvas(containerId);
8
+ floatingHearts(canvas);
9
+ }
10
+
11
+ export function startHeartTrail(containerId = 'body') {
12
+ const canvas = initCanvas(containerId);
13
+ heartTrail(canvas);
14
+ }
15
+
16
+ export function startHeartBurst(containerId = 'body') {
17
+ const canvas = initCanvas(containerId);
18
+ heartBurst(canvas);
19
+ }
package/vite.config.js ADDED
@@ -0,0 +1,13 @@
1
+ // vite.config.js
2
+ import { defineConfig } from 'vite';
3
+
4
+ export default defineConfig({
5
+ root: 'demo', // 👈 sets 'demo' as root
6
+ build: {
7
+ outDir: '../dist',
8
+ emptyOutDir: true,
9
+ },
10
+ server: {
11
+ open: true
12
+ }
13
+ });