제목 | javascript - snow fall | ||
---|---|---|---|
글쓴이 | darkninja | 작성시각 | 2025/06/13 14:30:14 |
|
|||
첨부파일을 삭제한다는 것이 글을 삭제 했네요; 눈송이를 랜덤하게 뿌려주는 변수들을 조금 수정했습니다 글내용중에 background-image url 에 a태그가 붙는 현상이 있습니다. 글을 올리게 되면 코드의 최적화를 단시간내에 끝낼수 있습니다. 이젠 큰 수정은 필요 없어 보이는데 나머지는 여러분의 몫입니다.
html <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>눈 내리는 애니메이션</title> <style> body { background-image: url(https://images.unsplash.com/photo-1491002052546-bf38f186af56?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2200&q=80); background-size: cover; } </style> </head> <body> <script type="text/javascript" src="snowflakes.js"></script> <script> </script> </body> </html> js //https://codepen.io/tmrDevelops/pen/PPgjwz //https://stickode.tistory.com/413 //https://forum.squarespace.com/topic/174119-falling-snowflakes-on-webpage#comment-416466_wrap //https://chatgpt.com/ // Flag to reset the position of the snowflakes var resetPosition = false; var reduceMotionQuery = matchMedia("(prefers-reduced-motion)"); // Handle accessibility var enableAnimations = false; // Handle animation accessibility preferences function setAccessibilityState() { if (reduceMotionQuery.matches) { enableAnimations = false; } else { enableAnimations = true; } } setAccessibilityState(); reduceMotionQuery.addListener(setAccessibilityState); // // Trigger a reset of all the snowflakes' positions // function sf_setResetFlag(e) { resetPosition = true; } // // It all starts here... // function snowflake_setup() { if (enableAnimations) { window.addEventListener("DOMContentLoaded", generateSnowflakes, false); window.addEventListener("resize", sf_setResetFlag, false); } } snowflake_setup(); // // The function responsible for creating the snowflake // function generateSnowflakes() { // create our snowflake element's parent container var snowflakeDIV = document.getElementById("snowflakeDIV_id"); if (!snowflakeDIV) { snowflakeDIV = document.createElement("div"); snowflakeDIV.id = "snowflakeDIV_id"; snowflakeDIV.style.position = "fixed"; snowflakeDIV.style.left = "0px"; snowflakeDIV.style.top = "0px"; snowflakeDIV.style.bottom = "0px"; snowflakeDIV.style.width = "100vw"; snowflakeDIV.style.height = "100vh"; snowflakeDIV.style.overflow = "hidden"; snowflakeDIV.style.zindex = "9999999"; snowflakeDIV.style.pointerEvents = "none"; document.body.appendChild(snowflakeDIV); makeSnowflakes(snowflakeDIV); } } // // The function responsible for creating the snowflake // function makeSnowflakes(snowflakeDIV) { // Global variables to store our browser's window size var snowflake_cw = document.documentElement.clientWidth; var snowflake_ch = document.documentElement.clientHeight; var randMinMax = function(min,max) { return min + Math.floor(Math.random() * ((max - min) + 1)); }; var snowflakeColor = function() { var items = ["#dcf2fd", "#60b4f2", "#dbf2fd", "#d8f8ff", "#b8ddfa"]; var item = items[Math.floor(Math.random()*items.length)]; return item; }; var snowflakeColorRand = function() { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; }; // Array to store our Snowflake objects var snowflakes = []; // Specify the number of snowflakes you want visible var snowflakes_num = 50; var fmid = 100; var fend = 200; var spn = 100; var spd = 25; // 눈송이 떨어지는 속도 최소, 최대 var spv = 70; var szn = 100; var szd = 30; // 눈송이 크기 최소, 최대 var szv = 52; var spmin = 1; var sp = 0.25; // 눈송이 떨어지는 속도조절 var xpv = 0.17; // 눈송이 좌우이동 값 조절 var opacity = 0.65; var viewfpscount = false; var viewconsolelog = false; var viewcount = 0; var viewmax = 0; // // Constructor for our Snowflake object // function Snowflake() { } Snowflake.prototype.animate = function (fpsCount) { var snow = this; var xp = Math.random() * snow.sz * xpv; // 눈송이가 좌우로 이동하는 값 if (snow.sp > 3) { xp = xp * randMinMax(3, 5); // 눈송이가 떨어지는 속도가 빠르면 랜덤하게 좌우 이동값을 크게한다 } else if (snow.sp > 2) { xp = xp * randMinMax(1, 3); } if (snow.sp > 2.5) { // 속도가 빠르면 규칙적인 이동에 변화를 준다 if (Math.random() > snow.direction) { xp = xp * -1; } } snow.frame += 1; xp = snow.frame > snow.fmid ? xp * -1 : xp; // 특정 프레임마다 눈송이가 좌우로 이동하는 방향을 바꿈 snow.x += xp; snow.y += snow.sp; snow.frame = snow.frame >= snow.fend ? snow.frame = 0 : snow.frame; if (snow.y > snowflake_ch) { // 눈송이가 화면 하단을 벗어나면 if (viewconsolelog) { if (viewmax == 0 || (viewmax > 0 && viewcount < viewmax)) { viewcount++; console.log(); } } snow.y = 0; snow.x = Math.random() * snowflake_cw; snow.frame = randMinMax(1, fend); snow.fmid = randMinMax(1, fmid); snow.fend = randMinMax(snow.fmid, fend); snow.direction = Math.random(); snow.sz = szn / (szd + (szv * Math.random())); snow.scale = snow.sz / (szn / (szd + szv)); // 눈송이 크기 var spz = spn / (spd + (spv * Math.random())); snow.sp = Math.max(spmin, (Math.pow(spz, 2) * sp)); // 눈송이 떨어지는 속도 (눈송이 크기와 비례하지 않음) if (snow.sp > 3) { // 눈송이가 떨어지는 속도가 빠르면 좌우 이동값을 느리게 바꾼다 snow.fmid = snow.fmid * 2; snow.fend = snow.fend * 2; } else if (snow.sp > 2) { snow.fmid = snow.fmid * 1.5; snow.fend = snow.fend * 1.5; } snow.flake.style.backgroundColor = snowflakeColorRand(); snow.flake.style.opacity = (opacity + Math.random()) / 3; //0.22 ~ 0.55 } // 실제 눈송이 위치 이동 snow.flake.style.transform = "translate(" + snow.x + "px, " + snow.y + "px) scale(" + snow.scale + ")"; } // create snowflake and add it to snowflakeContainer var sf = document.createElement('div'); sf.className = "snowflake"; sf.style.position = "absolute"; sf.style.width = "7px"; sf.style.height = "7px"; sf.style.borderRadius = "50%"; var spz; // create each individual snowflake for (var i = 0; i < snowflakes_num; i++) { // create our Snowflake object var snow = new Snowflake(); // set initial snowflake properties snow.y = Math.random() * snowflake_ch; snow.x = Math.random() * snowflake_cw; snow.frame = randMinMax(1, fend); snow.fmid = randMinMax(1, fmid); snow.fend = randMinMax(snow.fmid, fend); snow.direction = Math.random(); snow.sz = szn / (szd + (szv * Math.random())); snow.scale = snow.sz / (szn / (szd + szv)); spz = spn / (spd + (spv * Math.random())); snow.sp = Math.max(spmin, (Math.pow(spz, 2) * sp)); if (snow.sp > 3) { // 눈송이가 떨어지는 속도가 빠르면 좌우 이동값을 느리게 바꾼다 snow.fmid = snow.fmid * 2; snow.fend = snow.fend * 2; } else if (snow.sp > 2) { snow.fmid = snow.fmid * 1.5; snow.fend = snow.fend * 1.5; } // clone our original snowflake and add it to snowflakeContainer snow.flake = sf.cloneNode(true); snow.flake.id = "snowflake"+i; snow.flake.style.backgroundColor = snowflakeColorRand(); snow.flake.style.opacity = (opacity + Math.random()) / 3; //0.22 ~ 0.55 if ((i % 3) == 0) { snow.flake.style.filter = "drop-shadow(0 0 "+snow.scale+"px blue)"; } snowflakes.push(snow); snowflakeDIV.appendChild(snow.flake); } sf.remove(); // 초기화 var fpsCount = 0; var lastCheck = performance.now(); var lowfpsCount = 0; var decsnowflake = false; // // Responsible for moving each snowflake by calling its update function // function snowflakes_frame_animate() { const now = performance.now(); fpsCount++; if (now - lastCheck >= 1000) { if (fpsCount < 60) { lowfpsCount++; if (lowfpsCount >= 3) { lowfpsCount = 0; decsnowflake = true; } } else { lowfpsCount = 0; } if (viewfpscount) console.log("fpsCount: " + fpsCount); fpsCount = 0; lastCheck = now; } for (let i = 0; i < snowflakes.length; i++) { const snow = snowflakes[i]; if (snow) snow.animate(fpsCount); // 눈송이를 움직인다 if (decsnowflake && snow.y == 0) { // 눈송이가 화면 하단을 벗어난 거 snowflakes.splice(i, 1); // 배열 삭제 snow.flake.remove(); // 눈송이 제거 decsnowflake = false; if (viewconsolelog) console.log(snow.flake.id+" 삭제 남은 갯수 : " + snowflakes.length); } } // Reset the position of all the snowflakes to a new value if (resetPosition) { resetPosition = false; snowflake_cw = document.documentElement.clientWidth; snowflake_ch = document.documentElement.clientHeight; var spz; for (let i = 0; i < snowflakes.length; i++) { let snow = snowflakes[i]; // set initial snowflake properties snow.y = Math.random() * snowflake_ch; snow.x = Math.random() * snowflake_cw; snow.frame = randMinMax(1, fend); snow.fmid = randMinMax(1, fmid); snow.fend = randMinMax(snow.fmid, fend); snow.direction = Math.random(); snow.sz = szn / (szd + (szv * Math.random())); snow.scale = snow.sz / (szn / (szd + szv)); spz = spn / (spd + (spv * Math.random())); snow.sp = Math.max(spmin, (Math.pow(spz, 2) * sp)); if (snow.sp > 3) { // 눈송이가 떨어지는 속도가 빠르면 좌우 이동값을 느리게 바꾼다 snow.fmid = snow.fmid * 2; snow.fend = snow.fend * 2; } else if (snow.sp > 2) { snow.fmid = snow.fmid * 1.5; snow.fend = snow.fend * 1.5; } snow.flake.style.backgroundColor = snowflakeColorRand(); snow.flake.style.opacity = (opacity + Math.random()) / 3; //0.22 ~ 0.55 } } requestAnimationFrame(snowflakes_frame_animate); } snowflakes_frame_animate(); }
|
|||
첨부파일 |
snowfall.zip (3.6 KB) |
||
이전글 | ajaxcall function (beforeSend)... | ||
없음 |