제목 | javascript - snow fall | ||
---|---|---|---|
글쓴이 | darkninja | 작성시각 | 2025/06/09 23:06:26 |
|
|||
눈내리는 소스는 canvas 에 직접 그리는 것과 css animation 을 사용하는 것이 있는데 홈페이지 위에 덧 그리는 것은 css animation 을 사용하기 때문에 각각의 눈송이가 랜덤하게 움직이는데 한계가 있습니다. 눈송이를 개별적으로 특성을 주어 움직이게 하려면 눈송이 하나하나 마다 정보를 저장해야 하는데...
cpu 시간을 약간 사용합니다. 눈송이 50개나 100개나 별 차이가 없고.. 이해가 되지 않는 부분은 chatGPT 에게 코드를 전부 제공하고 알고 싶은 부분을 질문하면 됩니다.
background image 에 a태그가 추가 되어 있으면 제거해야 이미지가 보입니다. ?
Wham! - Last Christmas (Official Video) https://www.youtube.com/watch?v=E8gmARGvPlI
<!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> //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 spow = 1; var spn = 100; var spd = 25; // 눈송이 떨어지는 속도 최소, 최대 var spv = 70; var szn = 100; var szd = 30; // 눈송이 크기 최소, 최대 var szv = 52; var sc = 1; var sz = 1; var sp = 1; var spmin = 1; var spz; var xp; var xpv = 0.17; // 눈송이 좌우이동 값 조절 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; 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())) * sz; snow.scale = snow.sz / (szn / (szd + szv)) * sc; // 눈송이 크기 spz = spn / (spd + (spv * Math.random())) * sp; snow.sp = Math.max(spmin, (Math.pow(spz * spow, 2) * 0.25) * 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 = (0.65 + 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())) * sz; snow.scale = snow.sz / (szn / (szd + szv)) * sc; spz = spn / (spd + (spv * Math.random())) * sp; snow.sp = Math.max(spmin, (Math.pow(spz * spow, 2) * 0.25) * 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 = (0.65 + 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())) * sz; snow.scale = snow.sz / (szn / (szd + szv)) * sc; spz = spn / (spd + (spv * Math.random())) * sp; snow.sp = Math.max(spmin, (Math.pow(spz * spow, 2) * 0.25) * 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 = (0.65 + Math.random()) / 3; //0.22 ~ 0.55 } } requestAnimationFrame(snowflakes_frame_animate); } snowflakes_frame_animate(); } </script> </body> </html>
|
|||
첨부파일 |
snowfall.zip (3.6 KB) |
||
이전글 | ajaxcall function (beforeSend)... | ||
없음 |