@splatrac/vue-snowfall 1.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Erlan Kaparov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ <div align="center">
2
+ <a href="https://www.npmjs.com/package/vue-snowfall">
3
+ <img alt="current version" src="https://img.shields.io/npm/v/vue-snowfall">
4
+ </a>
5
+ <img alt="license" src="https://img.shields.io/github/license/NooBiToo/vue-snowfall" />
6
+ </div>
7
+
8
+ # Snowfall Effect in Vue.js
9
+
10
+ This repository provides a simple and customizable snowfall effect for your web applications using Vue.js. The useSnowfall function allows you to easily add and control falling snowflakes on your webpage.
11
+
12
+ ## Table of Contents
13
+ - [Snowfall Effect in Vue.js](#snowfall-effect-in-vuejs)
14
+ - [Table of Contents](#table-of-contents)
15
+ - [Installation](#installation)
16
+ - [Usage](#usage)
17
+ - [Customization](#customization)
18
+ - [License](#license)
19
+
20
+ ## Installation
21
+ To use the snowfall effect, you can simply copy the useSnowfall function into your Vue.js project. Ensure you have Vue.js installed in your project.
22
+
23
+ ```bash
24
+ npm install vue-snowfall
25
+ ```
26
+
27
+ ## Usage
28
+ 1. Import the useSnowfall function in your Vue component:
29
+
30
+ ```javascript
31
+ import { useSnowfall } from 'vue-snowfall'
32
+ ```
33
+ 2. Initialize the snowfall effect in your component's setup function:
34
+
35
+ ```javascript
36
+ export default {
37
+ setup() {
38
+ const { startSnowflakes, stopSnowflakes } = useSnowfall()
39
+
40
+ // Start snowfall when the component is mounted
41
+ onMounted(() => {
42
+ startSnowflakes()
43
+ })
44
+
45
+ // Stop snowfall when the component is unmounted
46
+ onBeforeUnmount(() => {
47
+ stopSnowflakes('all')
48
+ })
49
+ }
50
+ }
51
+ ```
52
+
53
+ 3. Add styles to your component if needed, or let the useSnowfall function handle it.
54
+
55
+ ## Customization
56
+ You can customize the snowfall effect by modifying the following parameters in the `useSnowfall` function:
57
+
58
+ **Falling Time**: Adjust the duration of the falling animation by changing the `fallingTime` variable in the `createSnowflake` function.
59
+ **Flake Size**: Modify the size of the snowflakes by changing the calculation of `flakeSize`.
60
+ **Animation Styles**: Customize the CSS styles in the `addStyles` function to change the appearance of the snowflakes.
61
+ Example of Customization
62
+ To change the falling speed and size of the snowflakes, you can modify the createSnowflake function like this:
63
+
64
+ ```javascript
65
+ const fallingTime = Math.floor(Math.random() * 5) + 5; // Faster falling speed
66
+ const flakeSize = (Math.floor(Math.random() * 50) + 50) / 100; // Larger snowflakes
67
+ ```
68
+
69
+ ## License
70
+ This project is licensed under the MIT License. Feel free to use and modify it as per your needs.
71
+
72
+ ---
73
+ Enjoy the beautiful snowfall effect on your web applications! If you have any questions or suggestions, feel free to open an issue in this repository.
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export { useSnowfall } from './src/useSnowfall.js';
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@splatrac/vue-snowfall",
3
+ "version": "1.1.0",
4
+ "description": "A Vue 3 composable for creating snowfall effects",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "main": "index.js",
9
+ "module": "index.js",
10
+ "keywords": [
11
+ "vue",
12
+ "snowfall",
13
+ "animation",
14
+ "effect",
15
+ "composable"
16
+ ],
17
+ "author": "Splatrac",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/splatrac/vue-snowfall.git"
22
+ },
23
+ "peerDependencies": {
24
+ "vue": "^3.0.0"
25
+ }
26
+ }
@@ -0,0 +1,114 @@
1
+ export function useSnowfall() {
2
+ let flakeIntervalId = null
3
+ let styleElement = null
4
+ const DEFAULT_OPTIONS = {
5
+ // Ranges for the random generators (same as the previous defaults)
6
+ timeRange: { min: 20, max: 29 }, // seconds the flake falls
7
+ posRange: { min: 4, max: 93 }, // % across the viewport
8
+ sizeRange: { min: 0.10, max: 1.09 } // scale factor
9
+ };
10
+
11
+ const addStyles = () => {
12
+ if (!styleElement) {
13
+ styleElement = document.createElement('style')
14
+ styleElement.textContent = `
15
+ .flake {
16
+ position: absolute;
17
+ top: -20px;
18
+ z-index: 999;
19
+ width: 30px;
20
+ height: 30px;
21
+ pointer-events: none;
22
+ }
23
+ @keyframes falling {
24
+ 0% { transform: translateX(0) translateY(0) rotate(0deg); opacity: 1; }
25
+ 12.5% { transform: translateX(-15px) translateY(12.5vh) rotate(45deg); opacity: 1; }
26
+ 25% { transform: translateX(15px) translateY(25vh) rotate(90deg); opacity: 1; }
27
+ 37.5% { transform: translateX(-20px) translateY(37.5vh) rotate(135deg); opacity: 0.9; }
28
+ 50% { transform: translateX(20px) translateY(50vh) rotate(180deg); opacity: 0.9; }
29
+ 62.5% { transform: translateX(-15px) translateY(62.5vh) rotate(225deg); opacity: 0.8; }
30
+ 75% { transform: translateX(15px) translateY(75vh) rotate(270deg); opacity: 0.7; }
31
+ 87.5% { transform: translateX(-10px) translateY(87.5vh) rotate(315deg); opacity: 0.6; }
32
+ 100% { transform: translateX(0) translateY(100vh) rotate(360deg); opacity: 0; }
33
+ }
34
+ `
35
+ document.head.appendChild(styleElement)
36
+ }
37
+ }
38
+
39
+ const removeStyles = () => {
40
+ if (styleElement) {
41
+ document.head.removeChild(styleElement)
42
+ styleElement = null
43
+ }
44
+ }
45
+
46
+ const htmlToElement = (html) => {
47
+ const template = document.createElement('template')
48
+ template.innerHTML = html.trim()
49
+ return template.content.firstChild
50
+ }
51
+
52
+ const createSnowflake = ({
53
+ time = { min: 20, max: 29 },
54
+ pos = { min: 4, max: 93 },
55
+ size = { min: 10, max: 100 }
56
+ }) => {
57
+ const flakeSVG = `
58
+ <svg width="100%" height="100%" viewBox="0 0 50 55" fill="none" xmlns="http://www.w3.org/2000/svg">
59
+ <path d="M42.2911 35.3845L50 39.8113L48.2293 42.8628L40.4446 38.3917L42.4879 45.9679L39.0858 46.8756L36.4208 36.9513L36.1578 35.9111L26.8388 30.5397V41.3708L27.522 42.0754L34.8573 49.3969L32.3809 51.8771L26.8388 46.3317V55H23.3558V46.2429L17.7319 51.7892L15.1906 49.309L22.5264 42.0443L23.3558 41.2825V30.5397L13.9388 35.9111L13.5949 36.9513L10.9216 46.8756L7.51561 45.9679L9.55669 38.3917L1.77114 42.8628L0 39.8113L7.70849 35.3845L0.0914308 33.3543L1.004 29.9663L11.0592 32.6462L12.0271 32.9043L21.4575 27.4887L12.1041 22.1174L11.0583 22.3963L1.08106 25.0553L0.168494 21.6674L7.78555 19.6372L0.000870706 15.1657L1.77289 12.1143L9.48355 16.5411L7.44682 8.965L10.8611 8.05728L13.5705 18.0591L13.8618 19.0218L23.3558 24.4373V13.6946L22.5425 12.9332L15.191 5.66803L17.7162 3.18783L23.3558 8.73417V0H26.8388V8.64539L32.3891 3.09906L34.8569 5.57925L27.5133 12.9012L26.8388 13.6062V24.4373L36.2349 19.0218L36.46 18.0591L39.1541 8.05728L42.5602 8.965L40.5191 16.5411L48.2276 12.1143L49.9987 15.1657L42.2131 19.6367L49.8298 21.667L48.9172 25.0549L38.9399 22.3958L37.8941 22.1169L28.5416 27.4883L37.9716 32.9043L38.9395 32.6462L48.9947 29.9663L49.9073 33.3543L42.2911 35.3845Z" fill="#fff"/>
60
+ </svg>`
61
+ const fallingTime = Math.floor(Math.random() * (time.max - time.min)) + time.min
62
+ const flakePos = Math.floor(Math.random() * (pos.max - pos.min)) + pos.min
63
+ const flakeSize = (Math.floor(Math.random() * (size.max - size.min)) + size.min) / 100
64
+ const snowflake = htmlToElement(
65
+ `<div
66
+ class='flake'
67
+ style='
68
+ left:${flakePos}%;
69
+ transform:scale(${flakeSize});
70
+ animation:falling ${fallingTime}s linear infinite;'
71
+ >
72
+ ${flakeSVG}
73
+ </div>`,
74
+ )
75
+ document.body.appendChild(snowflake)
76
+ }
77
+
78
+ const removeSnowflakes = (params) => {
79
+ const flakes = document.querySelectorAll('.flake')
80
+ flakes.forEach((el) => {
81
+ const flakeRect = el.getBoundingClientRect()
82
+ const bodyHeight = window.innerHeight
83
+ if (flakeRect.bottom > bodyHeight || params === 'all') {
84
+ el.remove()
85
+ }
86
+ })
87
+ }
88
+
89
+ const startSnowflakes = (userOptions = {}) => {
90
+ const {
91
+ timeRange = DEFAULT_OPTIONS.timeRange,
92
+ posRange = DEFAULT_OPTIONS.posRange,
93
+ sizeRange = DEFAULT_OPTIONS.sizeRange,
94
+ interval = 500
95
+ } = userOptions;
96
+
97
+ addStyles()
98
+ flakeIntervalId = setInterval(() => {
99
+ createSnowflake(finalOptions)
100
+ removeSnowflakes()
101
+ }, interval)
102
+ }
103
+
104
+ const stopSnowflakes = () => {
105
+ clearInterval(flakeIntervalId)
106
+ removeSnowflakes('all')
107
+ removeStyles()
108
+ }
109
+
110
+ return {
111
+ startSnowflakes,
112
+ stopSnowflakes,
113
+ }
114
+ }