1+ import { useEffect } from 'react' ;
2+
3+ export function Snowflakes ( ) {
4+
5+ useEffect ( ( ) => {
6+ function handlePageChange ( ) {
7+ clearSnowflakes ( ) ;
8+ generateSnowflakes ( ) ;
9+ }
10+
11+ function clearSnowflakes ( ) {
12+ const snowflakes = document . querySelectorAll ( ".snowflake" ) ;
13+ snowflakes . forEach ( snowflake => snowflake . remove ( ) ) ;
14+ }
15+
16+ function getSupportedPropertyName ( properties ) {
17+ for ( var i = 0 ; i < properties . length ; i ++ ) {
18+ if ( typeof document . body . style [ properties [ i ] ] !== "undefined" ) {
19+ return properties [ i ] ;
20+ }
21+ }
22+ return null ;
23+ }
24+
25+ class Snowflake {
26+ constructor ( element , speed , xPos , yPos ) {
27+ this . element = element ;
28+ this . speed = speed ;
29+ this . xPos = xPos ;
30+ this . yPos = yPos ;
31+ this . counter = 0 ;
32+ this . sign = Math . random ( ) < 0.5 ? 1 : - 1 ;
33+ this . element . style . opacity = 0.1 + Math . random ( ) ;
34+ this . element . style . fontSize = 12 + 50 * Math . random ( ) + 'px' ;
35+ }
36+
37+ update ( ) {
38+ this . counter += this . speed / 5000 ;
39+ this . xPos += this . sign * this . speed * Math . cos ( this . counter ) / 40 ;
40+ this . yPos += Math . sin ( this . counter ) / 40 + this . speed / 30 ;
41+ setTranslate3DTransform ( this . element , Math . round ( this . xPos ) , Math . round ( this . yPos ) ) ;
42+
43+ if ( this . yPos > browserHeight ) {
44+ this . yPos = - 50 ;
45+ }
46+ }
47+ }
48+
49+ function setTranslate3DTransform ( element , x , y ) {
50+ var transform = "translate3d(" + x + "px, " + y + "px, 0)" ;
51+ element . style [ transformProperty ] = transform ;
52+ }
53+
54+ function generateSnowflakes ( ) {
55+ var originalSnowflake = document . querySelector ( ".snowflake" ) ;
56+ if ( ! originalSnowflake ) {
57+ console . error ( "No element with class 'snowflake' found" ) ;
58+ return ;
59+ }
60+ var container = originalSnowflake . parentNode ;
61+ browserWidth = document . documentElement . clientWidth ;
62+ browserHeight = document . documentElement . clientHeight ;
63+
64+ for ( var i = 0 ; i < numberOfSnowflakes ; i ++ ) {
65+ var clone = originalSnowflake . cloneNode ( true ) ;
66+ container . appendChild ( clone ) ;
67+ var xPos = getPosition ( 50 , browserWidth ) ;
68+ var yPos = getPosition ( 50 , browserHeight ) ;
69+ var speed = 5 + 40 * Math . random ( ) ;
70+ var snowflake = new Snowflake ( clone , speed , xPos , yPos ) ;
71+ snowflakes . push ( snowflake ) ;
72+ }
73+ container . removeChild ( originalSnowflake ) ;
74+ moveSnowflakes ( ) ;
75+ }
76+
77+ function moveSnowflakes ( ) {
78+ for ( var i = 0 ; i < snowflakes . length ; i ++ ) {
79+ var snowflake = snowflakes [ i ] ;
80+ snowflake . update ( ) ;
81+ }
82+ if ( resetPosition ) {
83+ browserWidth = document . documentElement . clientWidth ;
84+ browserHeight = document . documentElement . clientHeight ;
85+ for ( var i = 0 ; i < snowflakes . length ; i ++ ) {
86+ var snowflake = snowflakes [ i ] ;
87+ snowflake . xPos = getPosition ( 50 , browserWidth ) ;
88+ snowflake . yPos = getPosition ( 50 , browserHeight ) ;
89+ }
90+ resetPosition = false ;
91+ }
92+ requestAnimationFrame ( moveSnowflakes ) ;
93+ }
94+
95+ function getPosition ( offset , size ) {
96+ return Math . round ( - 1 * offset + Math . random ( ) * ( size + 2 * offset ) ) ;
97+ }
98+
99+ function setResetFlag ( ) {
100+ resetPosition = true ;
101+ }
102+
103+ var requestAnimationFrame = window . requestAnimationFrame || window . mozRequestAnimationFrame || window . webkitRequestAnimationFrame || window . msRequestAnimationFrame ;
104+ var transforms = [ "transform" , "msTransform" , "webkitTransform" , "mozTransform" , "oTransform" ] ;
105+ var transformProperty = getSupportedPropertyName ( transforms ) ;
106+ var snowflakes = [ ] ;
107+ var browserWidth ;
108+ var browserHeight ;
109+ var numberOfSnowflakes = 25 ;
110+ var resetPosition = false ;
111+
112+ generateSnowflakes ( ) ;
113+ window . addEventListener ( "resize" , setResetFlag , false ) ;
114+ window . addEventListener ( "popstate" , handlePageChange , false ) ;
115+
116+ return ( ) => {
117+ window . removeEventListener ( "resize" , setResetFlag , false ) ;
118+ window . removeEventListener ( "popstate" , handlePageChange , false ) ;
119+ } ;
120+ } , [ ] ) ;
121+
122+ return null ;
123+ }
0 commit comments