2012-12-21 25 views
34

का उपयोग कर गिरने वाली बर्फ बनाना, मैंने Stack Exchange Winter Bash website का दौरा किया और मुझे गिरती बर्फ से प्यार है! मेरा सवाल यह है कि, मैं एक समान प्रभाव को कैसे पुनर्जीवित कर सकता हूं जो अच्छा दिखता है। मैंने यह देखने के लिए कोड को इंजीनियर करने का प्रयास किया कि क्या मैं इसे समझ सकता हूं लेकिन वहां कोई भाग्य नहीं है। जेएस मेरे सिर पर है। मैंने कुछ गुगल किया और कुछ examples में आया लेकिन वे एसई साइट के रूप में सुरुचिपूर्ण नहीं थे या बहुत अच्छे नहीं दिख रहे थे।एचटीएमएल 5 और जेएस

कोई भी एसई शीतकालीन बैश साइट बनाता है या एक जगह कहां से दोहराने के लिए कुछ निर्देश प्रदान कर सकता है जहां मैं यह सीख सकता हूं कि यह कैसे करें?

संपादित करें: मैं प्रभाव अधिक से अधिक निकट दोहराने के लिए चाहते हैं, IE: बर्फ के टुकड़े के साथ बर्फ गिरने, और माउस ले जाते हैं और बर्फ ले जाने या माउस क्षणों के साथ चक्कर आने के लिए पैदा करने के लिए सक्षम किया जा रहा।

+0

तुम सिर्फ बर्फ से परत-गिरने प्रभाव के लिए या भी माउसओवर समारोह के लिए पूछ रहे हैं ality? – Bergi

+0

@ बर्गि - अधिमानतः दोनों, मैंने जो कुछ भी ढूंढ रहा हूं उसे प्रतिबिंबित करने के लिए प्रश्न संपादित किया। – L84

+0

मैंने शेष कोड से बर्फ प्रभाव को कम करने में कामयाब रहा है। क्या आप चाहते हैं कि मैं इसे पोस्ट करूं या आप "कैसे करें: इसे स्वयं करने के लिए खोज रहे हैं? यह मूल रूप से गणित का _ बहुत_ है जो गिरने वाली बर्फ और अन्य उपहारों को अनुकरण करता है। – j08691

उत्तर

49

महान सवाल, मैंने वास्तव में कुछ समय पहले एक बर्फ प्लगइन लिखा था कि मैं लगातार see it in action अद्यतन करता हूं। Also a link to the pure js source

मैंने देखा कि आपने एचटीएमएल 5 और कैनवास को टैग किया है, हालांकि आप इसे बिना किसी प्रयोग किए और इसे छवियों या विभिन्न पृष्ठभूमि रंगों के साथ मानक तत्वों के बिना कर सकते हैं।

यहां दो वास्तव में सरल हैं जिन्हें मैंने अभी आपके साथ गड़बड़ कर रखा है। मेरी राय में कुंजी फ्लेक्स गिरने के रूप में अच्छा लहर प्रभाव प्राप्त करने के लिए पाप का उपयोग कर रही है। पहला कैनवास तत्व का उपयोग करता है, दूसरा एक नियमित डोम तत्वों का उपयोग करता है।

चूंकि मैं कैनवास का बिल्कुल आदी हूं, यहां एक कैनवास संस्करण है जो मेरी राय में काफी अच्छी तरह से प्रदर्शन करता है।

Canvas version

Full Screen

(function() { 
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || 
    function(callback) { 
     window.setTimeout(callback, 1000/60); 
    }; 
    window.requestAnimationFrame = requestAnimationFrame; 
})(); 


var flakes = [], 
    canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"), 
    flakeCount = 200, 
    mX = -100, 
    mY = -100 

    canvas.width = window.innerWidth; 
canvas.height = window.innerHeight; 

function snow() { 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 

    for (var i = 0; i < flakeCount; i++) { 
     var flake = flakes[i], 
      x = mX, 
      y = mY, 
      minDist = 150, 
      x2 = flake.x, 
      y2 = flake.y; 

     var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)), 
      dx = x2 - x, 
      dy = y2 - y; 

     if (dist < minDist) { 
      var force = minDist/(dist * dist), 
       xcomp = (x - x2)/dist, 
       ycomp = (y - y2)/dist, 
       deltaV = force/2; 

      flake.velX -= deltaV * xcomp; 
      flake.velY -= deltaV * ycomp; 

     } else { 
      flake.velX *= .98; 
      if (flake.velY <= flake.speed) { 
       flake.velY = flake.speed 
      } 
      flake.velX += Math.cos(flake.step += .05) * flake.stepSize; 
     } 

     ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")"; 
     flake.y += flake.velY; 
     flake.x += flake.velX; 

     if (flake.y >= canvas.height || flake.y <= 0) { 
      reset(flake); 
     } 


     if (flake.x >= canvas.width || flake.x <= 0) { 
      reset(flake); 
     } 

     ctx.beginPath(); 
     ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2); 
     ctx.fill(); 
    } 
    requestAnimationFrame(snow); 
}; 

function reset(flake) { 
    flake.x = Math.floor(Math.random() * canvas.width); 
    flake.y = 0; 
    flake.size = (Math.random() * 3) + 2; 
    flake.speed = (Math.random() * 1) + 0.5; 
    flake.velY = flake.speed; 
    flake.velX = 0; 
    flake.opacity = (Math.random() * 0.5) + 0.3; 
} 

function init() { 
    for (var i = 0; i < flakeCount; i++) { 
     var x = Math.floor(Math.random() * canvas.width), 
      y = Math.floor(Math.random() * canvas.height), 
      size = (Math.random() * 3) + 2, 
      speed = (Math.random() * 1) + 0.5, 
      opacity = (Math.random() * 0.5) + 0.3; 

     flakes.push({ 
      speed: speed, 
      velY: speed, 
      velX: 0, 
      x: x, 
      y: y, 
      size: size, 
      stepSize: (Math.random())/30, 
      step: 0, 
      angle: 180, 
      opacity: opacity 
     }); 
    } 

    snow(); 
}; 

canvas.addEventListener("mousemove", function(e) { 
    mX = e.clientX, 
    mY = e.clientY 
}); 

init();​ 

Standard element version

var flakes = [], 
    bodyHeight = getDocHeight(), 
    bodyWidth = document.body.offsetWidth; 


function snow() { 
    for (var i = 0; i < 50; i++) { 
     var flake = flakes[i]; 

     flake.y += flake.velY; 

     if (flake.y > bodyHeight - (flake.size + 6)) { 
      flake.y = 0; 
     } 

     flake.el.style.top = flake.y + 'px'; 
     flake.el.style.left = ~~flake.x + 'px'; 

     flake.step += flake.stepSize; 
     flake.velX = Math.cos(flake.step); 

     flake.x += flake.velX; 

     if (flake.x > bodyWidth - 40 || flake.x < 30) { 
      flake.y = 0; 
     } 
    } 
    setTimeout(snow, 10); 
}; 


function init() { 
    var docFrag = document.createDocumentFragment(); 
    for (var i = 0; i < 50; i++) { 
     var flake = document.createElement("div"), 
      x = Math.floor(Math.random() * bodyWidth), 
      y = Math.floor(Math.random() * bodyHeight), 
      size = (Math.random() * 5) + 2, 
      speed = (Math.random() * 1) + 0.5; 

     flake.style.width = size + 'px'; 
     flake.style.height = size + 'px'; 
     flake.style.background = "#fff"; 

     flake.style.left = x + 'px'; 
     flake.style.top = y; 
     flake.classList.add("flake"); 

     flakes.push({ 
      el: flake, 
      speed: speed, 
      velY: speed, 
      velX: 0, 
      x: x, 
      y: y, 
      size: 2, 
      stepSize: (Math.random() * 5)/100, 
      step: 0 
     }); 
     docFrag.appendChild(flake); 
    } 

    document.body.appendChild(docFrag); 
    snow(); 
}; 

document.addEventListener("mousemove", function(e) { 
    var x = e.clientX, 
     y = e.clientY, 
     minDist = 150; 

    for (var i = 0; i < flakes.length; i++) { 
     var x2 = flakes[i].x, 
      y2 = flakes[i].y; 

     var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)); 

     if (dist < minDist) { 
      rad = Math.atan2(y2, x2), angle = rad/Math.PI * 180; 

      flakes[i].velX = (x2/dist) * 0.2; 
      flakes[i].velY = (y2/dist) * 0.2; 

      flakes[i].x += flakes[i].velX; 
      flakes[i].y += flakes[i].velY; 
     } else { 
      flakes[i].velY *= 0.9; 
      flakes[i].velX 
      if (flakes[i].velY <= flakes[i].speed) { 
       flakes[i].velY = flakes[i].speed; 
      } 
     } 
    } 
}); 

init(); 

function getDocHeight() { 
    return Math.max(
    Math.max(document.body.scrollHeight, document.documentElement.scrollHeight), Math.max(document.body.offsetHeight, document.documentElement.offsetHeight), Math.max(document.body.clientHeight, document.documentElement.clientHeight)); 
}​ 
+0

जानकारी के लिए धन्यवाद! हालांकि फिडल में बर्फ नहीं गिर रहा है! मैं फ्लेक्स को बहुत ऊपर चल रहा हूं लेकिन बर्फ गिरने नहीं लगता है। – L84

+0

वास्तव में? आप कौन सा ब्राउज़र उपयोग कर रहे हैं? यह क्रोम में काम करता है हालांकि मैंने किसी अन्य के साथ परीक्षण नहीं किया था। – Loktar

+0

फ़ायरफ़ॉक्स, मैंने क्रोम में कोशिश की और यह वहां काम करता है। – L84

-6

गिरने वाली बर्फ सरल है: एक कैनवास बनाएं, बर्फ के टुकड़े का एक गुच्छा बनाएं, उन्हें खींचे।

तुम इतनी तरह एक स्नोफ़्लेक वर्ग बना सकते हैं:

function Snowflake() { 
    this.x = Math.random()*canvas.width; 
    this.y = -16; 
    this.speed = Math.random()*3+1; 
    this.direction = Math.random()*360; 
    this.maxSpeed = 4; 
} 

या कुछ इस तरह। फिर आपके पास एक टाइमर होता है, प्रत्येक चरण, प्रत्येक हिमपात की दिशा को एक छोटी राशि से समायोजित करता है, और फिर गति और दिशा में फैक्टरिंग करके अपने नए एक्स और वाई की गणना करता है।

समझाना मुश्किल है, लेकिन वास्तव में काफी बुनियादी है।

संबंधित मुद्दे