<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<body onload="init()">
	<canvas id="myCanvas" width="640" height="640"></canvas>  	
	<div id="control">
		<ul>
		<li><p>snowfall</p></li>
		<li><input type="range" name="snowfall" value="5" id="snowFall" min="1" max="10" step="1" onchange="init()"></li>
		<li><span id="value">0</span></li>
		</ul>
	</div>    
</body>
		*{
			margin: 0;
		}

		canvas#myCanvas{
			background: linear-gradient(#171b1c, #040b10);
            display: block;
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
		}

		#control{
			display: block;
            position: absolute;
            background-color: rgba(255,255,255,0.1);
            opacity: 1;
            padding: 10px;
            bottom: 10px;
            left: 10px;
            user-select: none;
		}

	    #control ul{
	    	padding: 0;
		 	list-style-type: none;
		 	display: flex;
		}

		#control li:nth-child(n+2){
			margin-left: 10px;
		}

		#control p{
			color: #FFFFFF;
			display: block;
			
		}

		input#snowFall {
			height: 10px;
			margin-top: 4px;
           
		}

		#value{
			color: #FFFFFF;
		}
    var stage, stageWidth, stageHeight;//画面サイズ
    var snow;//雪
    var snowArray = [];//雪の配列
    var bigSnow;//至近距離の雪
    var bigSnowArray = [];//至近距離の雪の配列
    var snowfall = 1;//降雪量
    var wind = 0; //風向き
    var count = 0; //カウンター

    var mx;//マウスのx座標

    var vx = 0;//速度x軸
    var vy = 0;//速度y軸

    function init(){
    	stage = new createjs.Stage("myCanvas");
    	//画面リサイズ
		window.addEventListener("resize", handleResize);
		handleResize();
		//スマホセンサー
		window.addEventListener("deviceorientation", deviceorientationHandler);
		if (createjs.Touch.isSupported() === true) {
		   // タッチ操作を有効にします。
		   createjs.Touch.enable(stage);
		}
		//降雪量のコントロール
		var snowFallSlider = document.getElementById('snowFall');
		//降雪量の値
		var snowFallValue = document.getElementById('value');
		//値の変更と反映
		snowFallValue.textContent = snowFallSlider.value + "";
		snowfall = snowFallSlider.value;
		//tickイベント
		createjs.Ticker.timingMode = createjs.Ticker.RAF;
		createjs.Ticker.addEventListener("tick", handleTick);
    }

    //画面のリサイズ処理
	function handleResize(event) {
        // 画面幅・高さを取得
        var stageWidth = window.innerWidth;
        var stageHeight = window.innerHeight;
        // Canvas要素の大きさを画面幅・高さに合わせる
        stage.canvas.width = stageWidth;
        stage.canvas.height = stageHeight;
        // 画面更新する
        stage.update();
	}
	//ジャイロセンサー感知
	function deviceorientationHandler(event) {
		//Y軸
		var gamma = event.gamma;
		//風向きに反映
		wind = gamma*0.01;
	}

	function handleTick(event){
		//フレームを増やす
		count += 1;
		//デバイスの判別
		discrimination();
		//雪の描写
		emitSnow();
		fallSnow();
		//至近距離の雪の描写
		emitBigSnow();
		fallBigSnow();

		stage.update();	
	}

	//デバイスの判別
	function discrimination(){
		var ua = navigator.userAgent.toLowerCase();
		// iPhone
		var isiPhone = (ua.indexOf('iphone') > -1);
		// iPad
		var isiPad = (ua.indexOf('ipad') > -1);
		// Android
		var isAndroid = (ua.indexOf('android') > -1) && (ua.indexOf('mobile') > -1);
		// Android Tablet
		var isAndroidTablet = (ua.indexOf('android') > -1) && (ua.indexOf('mobile') == -1);
		//判別の条件
		var desktop = isiPhone || isiPad || isAndroid || isAndroidTablet;
		//スマホタブレットでないとき
		if(!desktop){
			//風向きをマウスの位置によって変える
			mx = stage.mouseX;
			if(mx < stage.canvas.width/2){
				wind = -0.1;
			}else{
				wind = 0.1;
			}
		}
	}
	//雪の量を調節
	function emitSnow(){
		for(var i = 0; i < snowfall; i++){
			if(count % (Math.floor(50 / snowfall)) === 0) {
				drawSnow();
			}
		}
	}
	//雪の描写
	function drawSnow(){
		var size = Math.random() * 4;		
		snow = new createjs.Shape();
		snow.graphics
			.beginFill("#FFFFFF")
			.drawCircle(0, 0, size);
		snow.x = Math.random() * ((stage.canvas.width*3)/2 - (-stage.canvas.width/2)) + (-stage.canvas.width/2);
		snow.y = 0;
		snow.vx = 0;
		snow.vy = 0;
		snow.angle = 0;
		//雪の種類にタイプをつける
		snow.type = Math.random();
		//雪をぼかす
		var blurStrong = size*2;
		var blurFilter = new createjs.BlurFilter(blurStrong, blurStrong, 2);
		snow.filters = [blurFilter];
		//1より大きいサイズの雪にぼかしを入れる
		if(size > 1){
			snow.cache(-size, -size, size*2, size*2);	
		}
		
		stage.addChild(snow);
		snowArray.push(snow);
	}
	//雪を落とす
	function fallSnow(){
		for(var i = 0; i < snowArray.length; i++){
			var snow = snowArray[i];
			//typeAの雪
			if(snow.type < 0.3){
				//速度
				snow.vy += 0.2;
				snow.vx += wind + 0.005;
			}
			//typeBの雪
			 else if(0.3 <= snow.type && snow.type < 0.6){
				//速度
				snow.vy += 0.4;
				snow.vx += wind;
			}
			//typeCの雪
			else if(0.6 <= snow.type && snow.type < 1){
				//速度
				snow.vy += 0.8;
				snow.vx += wind - 0.005;				
			}
			// 摩擦
			snow.vy *= 0.95;
			snow.vy *= 0.99;
			//反映
			snow.x += snow.vx;
			snow.y += snow.vy;
			//キャンバスから消えたら消す
			var rule = snow.x > stage.canvas.width || snow.y > stage.canvas.height || snow.x < -stage.canvas.width;
			if(rule){
				stage.removeChild(snow);
				snowArray.splice(i , 1);
			}
		}
	}
	//至近距離の雪の調節
	function emitBigSnow(){
		for(var i = 0; i < 1; i++){
			if(count % (Math.floor(100 / snowfall)) === 0) {
				drawBigSnow(i);
			}	
		}
	}
	//至近距離の雪の描写
	function drawBigSnow(){
		var size = 12 * Math.random() + 10;				
		bigSnow = new createjs.Shape();
		bigSnow.graphics
			.beginFill("#FFFFFF")
			.drawCircle(0, 0, size);
		bigSnow.x = Math.random() * ((stage.canvas.width*3)/2 - (-stage.canvas.width/2)) + (-stage.canvas.width/2);
		bigSnow.y = 0;
		bigSnow.vx = 0;
		bigSnow.vy = 0;
		bigSnow.angle = 0;
		//雪の種類にタイプをつける
		bigSnow.type = Math.random();
		//ぼかす
		var blurStrong = size*2;
		var blurFilter = new createjs.BlurFilter(blurStrong, blurStrong, 2);
		bigSnow.filters = [blurFilter];
		bigSnow.cache(-size, -size, size*2, size*2);
		stage.addChild(bigSnow);
		bigSnowArray.push(bigSnow);
	}
	//至近距離の雪を落とす
	function fallBigSnow(){
		for(var i = 0; i < bigSnowArray.length; i++){
			var bigSnow = bigSnowArray[i];
			//速度
			bigSnow.vx += wind*10;				
			bigSnow.vy += 1;
			//摩擦
			bigSnow.vx *= 0.99;
			bigSnow.vy *= 1.01;
			//反映
			bigSnow.x += bigSnow.vx;
			bigSnow.y += bigSnow.vy;
			//キャンバスから消えたら消す
			var rule = bigSnow.x > stage.canvas.width || bigSnow.y > stage.canvas.height || bigSnow.x < 0;
			if(rule){
				stage.removeChild(bigSnow);
				bigSnowArray.splice(i , 1);
			}
		}
	}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.