JAVA、PHP、前端、APP、网站开发 - 开发技术学习

开发技术学习 » 前端设计 » html页面js撒金币实例

html页面js撒金币实例

此文被围观3254 日期: 2016-10-03 分类 : 前端设计  标签:  ······

移动端html撒金币,js撒金币

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>摇一摇撒金币</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui" />
<style>
	body{margin:0;padding:0;}
	input{position:absolute;z-index:1000}
	canvas{position:absolute;top:0;left:0;}
</style>
<script>
	function Coin(opts){
		//默认参数
		this.defaults={
			coinSrc:"http://gw.alicdn.com/tps/i3/TB1QJ5DGpXXXXaBXXXXuv2kGFXX-39-39.png_40x40Q50s150.jpg",     //金币图片地址
			audioSrc:"http://download.taobaocdn.com/freedom/26370/media/shake.mp3",	//金币音频地址
			coinWidth:20,           //金币宽度
			coinHeight:20,          //金币高度
			density:30
		};
		this.settings=this._extendDeep(this.defaults,opts);   //深拷贝
		this.density=this.settings.density;                   //密度,即金币个数
		this.timeLag=1000;                                    //金币散落的事件间隔,数字越大表示间隔越大
		this.coinWidth=this.settings.coinWidth;               //金币宽度
		this.coinHeight=this.settings.coinHeight;             //金币高度
		this.wrapWidth=0;
		this.wrapHeight=0;
		this._init();
	}
	Coin.prototype={
		constructor:Coin,
		/**
		 * 动画初始化方法
		 * @method _init
		**/
		_init:function(){
			//初始化包括尺寸大小
			this.wrapWidth=document.documentElement.clientWidth;
			this.wrapHeight=document.documentElement.clientHeight;
			this._requestAnimationFrame();
			this._createCanvas();
			this._createAudio();
		},
		/**
		 * 对象深拷贝方法
		 * @method _extendDeep
		 * @param  {object} parent 父对象
				   {object} child  子对象
		   @return {object} child  父对象继承给子对象
		**/
		_extendDeep:function(child,parent){
			var i,
			toStr = Object.prototype.toString,
			astr = "[object Array]";
			child = child || {};
			for (i in parent) {
				if (parent.hasOwnProperty(i)) {
					if (typeof parent[i] === "object") {
						child[i] = (toStr.call(parent[i]) === astr) ? [] : {};
						extendDeep(parent[i], child[i]);
					} else {
						child[i] = parent[i];
					}
				}
			}
			return child;
		},
		/**
		 * requestAnimationFrame做兼容
		 * @method _requestAnimationFrame
		**/
		_requestAnimationFrame:function(){
			var lastTime = 0;
			var vendors = ['webkit', 'moz'];
			for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
				window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
				window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||    // name has changed in Webkit
											  window[vendors[x] + 'CancelRequestAnimationFrame'];
			}
			if (!window.requestAnimationFrame) {
				window.requestAnimationFrame = function(callback, element) {
					var currTime = new Date().getTime();
					var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
					var id = window.setTimeout(function() {
						callback(currTime + timeToCall);
					}, timeToCall);
					lastTime = currTime + timeToCall;
					return id;
				};
			}
			if (!window.cancelAnimationFrame) {
				window.cancelAnimationFrame = function(id) {
					clearTimeout(id);
				};
			}
		},
		/**
		 * 创建canvas画布
		 * @method _createCanvas
		**/
		_createCanvas:function(){
			var _self=this;
			this.canvas=document.createElement('canvas');
			this.canvas.setAttribute("data-id",Date.now());
			if(!this.canvas.getContext){
				alert("您的浏览器不支持canvas");
				return;
			}
			this.context=this.canvas.getContext('2d');
			this.canvas.width=this.wrapWidth;
			this.canvas.height=this.wrapHeight;
			var oBody=document.getElementsByTagName('body')[0];
			oBody.appendChild(this.canvas);
			this._createCacheCanvas();
		},
		_createCacheCanvas:function(){
			var _self=this;
			this.cacheCanvas=document.createElement('canvas');
			this.cacheContext=this.cacheCanvas.getContext('2d');
			this.cacheCanvas.width=this.wrapWidth;
			this.cacheCanvas.height=this.wrapHeight;
			this.coinImg=new Image();
			this.coinImg.src=this.settings.coinSrc;
			this.coinImg.onload=function(){
				_self._startCacheCanvasAnim();
			}
		},
		/**
		 * 执行金币绘制动画
		 * @method _startCanvasAnim
		**/
		_startCacheCanvasAnim:function(){
			var _self=this;
			var availWidth=this.cacheCanvas.width-this.coinWidth;
			var availHeight=this.cacheCanvas.height-this.coinHeight;
			//var disX=availWidth/this.density;  //每个硬币X轴的间距
			var coinRange=availWidth*this.density/(this.density+15);
			var rangeStart=(availWidth-coinRange)/2;
			var g=9.8*280;   //重力加速度
			var bPlayAudio=false;
			var coinAttrArr=[];  //存储金币下落过程中的一些属性参数
			for(var i=0;i<_self.density;i++){
				coinAttrArr[i]={
					rndX:Math.random(),                                    //存储金币开始降落x轴随机值
					rndOrder:Math.round(Math.random()*_self.timeLag/17),   //存储金币撒落顺序的一个数组
					time:0,									               //存储金币绘制的具体时间
					top:0,                                                 //存储金币绘制距离顶部的距离
					left:0,                                                //存储金币弹起后距离左边的距离
					endSpeed:0,                                            //存储金币第一次接触地面的速度
					bEnd:false,								               //存储金币是否触碰到地面
					reDownSpeed:0,                                         //存储金币弹起后重新降落的速度
					reDownHDelta:Math.random()*100+250,                    //存储金币弹起的高度参数,随机值250~350之间
					rndOffsetX:Math.random()*0.06+0.97                     //存储金币x轴的偏移量,随机值0.97~1.03之间
				}
			}
			var startTime =  Date.now();  //开始绘制前的时间
			function draw(){
				var drawStart = Date.now();  //记录重绘的结束事件
				var diff = (drawStart - startTime)/1000;  //计算每次重绘所需要的事件,单位为秒
				startTime = drawStart;   //结束事件传给开始事件
				_self.context.clearRect(0,0,_self.canvas.width,_self.canvas.height);  //清除画布,方便重绘
				_self.cacheContext.clearRect(0,0,_self.cacheCanvas.width,_self.cacheCanvas.height);  //清除画布,方便重绘
				_self.cacheContext.save();
				//根据金币个数循环绘制金币
				for(var i=0;i<_self.density;i++){
					if((coinAttrArr[i].rndOrder==0&&coinAttrArr[i].time==0)){   //如果顺序为0,表示开始下落,同时下落的初始时间为0时,赋值初始时间
						coinAttrArr[i].time=diff;
					}
					if(coinAttrArr[i].time>0){     //如果初始事件大于0,表示已经在下落过程中,则每次的初始时间递增
						coinAttrArr[i].time=coinAttrArr[i].time+diff;
					}
					if(coinAttrArr[i].rndOrder==0){  //如果顺序为0,开始下落,则开始绘制金币
						if(!coinAttrArr[i].bEnd){   //金币下落(过程一),自由落体运动
							coinAttrArr[i].top=g*Math.pow(coinAttrArr[i].time,2)/2-_self.coinHeight;   //自由落体加速度运动,求下落的高度
							//coinAttrArr[i].left=disX*coinAttrArr[i].rndX+i*disX;
							coinAttrArr[i].left=coinRange*coinAttrArr[i].rndX+rangeStart;
						}else if(coinAttrArr[i].endSpeed==0){   //金币弹起后在空中重新下落(过程三)
							coinAttrArr[i].reDownSpeed=coinAttrArr[i].reDownSpeed*1.1;
							coinAttrArr[i].top=coinAttrArr[i].top+coinAttrArr[i].reDownSpeed;
							coinAttrArr[i].left=coinAttrArr[i].left*coinAttrArr[i].rndOffsetX;
						}else{   //金币弹起(过程二)
							coinAttrArr[i].endSpeed=-Math.abs(coinAttrArr[i].endSpeed*0.96);
							if(Math.abs(coinAttrArr[i].endSpeed)<1) coinAttrArr[i].endSpeed=0;
							coinAttrArr[i].top=coinAttrArr[i].top+coinAttrArr[i].endSpeed;
							coinAttrArr[i].left=coinAttrArr[i].left*coinAttrArr[i].rndOffsetX;
						}
						//金币第一次降落超过地面时,将其高度设置和地面齐平
						if(coinAttrArr[i].top>_self.cacheCanvas.height-_self.coinHeight&&!coinAttrArr[i].bEnd){
							coinAttrArr[i].top=_self.cacheCanvas.height-_self.coinHeight;
						}
						//金币落地时,计算落地的速度
						if(coinAttrArr[i].top==_self.cacheCanvas.height-_self.coinHeight){
							coinAttrArr[i].endSpeed=g*coinAttrArr[i].time/coinAttrArr[i].reDownHDelta;
							coinAttrArr[i].reDownSpeed=coinAttrArr[i].endSpeed/10;
							coinAttrArr[i].bEnd=true;
						}
						//绘制金币
						_self.cacheContext.drawImage(_self.coinImg,coinAttrArr[i].left,coinAttrArr[i].top,_self.coinWidth,_self.coinHeight);
					}
					coinAttrArr[i].rndOrder=coinAttrArr[i].rndOrder==0?0:coinAttrArr[i].rndOrder-1;//顺序每一次重绘则递减一次,直到为0时,代表开始下落
				}
				_self.cacheContext.restore();
				_self.context.drawImage(_self.cacheCanvas,0,0,_self.canvas.width,_self.canvas.height);
				var firstH=_self._maxNum(coinAttrArr,"top");//求降落过程中高度最大的金币高度
				if(firstH>=_self.cacheCanvas.height-_self.coinHeight&&!bPlayAudio){
					_self._playAudio();
					bPlayAudio=true;
				}
				var lastH=_self._minNum(coinAttrArr,"top");//求降落过程中高度最小的金币高度
				if(lastH<=_self.cacheCanvas.height+_self.coinHeight){ //最后一个金币高度超出canvas的高度停止重绘
					window.requestAnimationFrame(draw);  //重绘,递回调用绘制方法
				}else{
					console.log("金币都撒完了");
					_self._destory();
				}
			}
			window.requestAnimationFrame(draw);  //第一次绘制
		},
		/**
		 * 求最小值
		 * @method _minNum
		 * @param   {arr}    arr  属性数组
					{string} attr 数组下的属性名称
		 * @return  {number}      返回数组下属性值最小的值
		**/
		_minNum:function(arr,attr){
			var tempArr=[];
			for(var i=0;i<arr.length;i++){
				tempArr.push(arr[i][attr]);
			}
			return tempArr.sort(function(a,b){return a-b})[0];
		},
		/**
		 * 求最大值
		 * @method _minNum
		 * @param   {arr}    arr  属性数组
					{string} attr 数组下的属性名称
		 * @return  {number}      返回数组下属性值最大的值
		**/
		_maxNum:function(arr,attr){
			var tempArr=[];
			for(var i=0;i<arr.length;i++){
				tempArr.push(arr[i][attr]);
			}
			return tempArr.sort(function(a,b){return b-a})[0];
		},
		/**
		 * 创建音频对象
		 * @method _createAudio
		**/
		_createAudio:function(){
			this.audio=document.createElement('audio');
			this.audio.setAttribute("preload","load");
			var oSource=document.createElement('source');
			oSource.setAttribute("src",this.settings.audioSrc);
			oSource.setAttribute("type","audio/mp3");
			this.audio.appendChild(oSource);
			var oBody=document.getElementsByTagName('body')[0];
			oBody.appendChild(this.audio);
		},
		/**
		 * 播放音频
		 * @method _playAudio
		**/
		_playAudio:function(){
			this.audio.play();
		},
		/**
		 * 销毁canvas和audio
		 * @method _destory
		**/
		_destory:function(){
			var oBody=document.getElementsByTagName('body')[0];
			oBody.removeChild(this.canvas);
			oBody.removeChild(this.audio);
		}
	}
</script>
<script>
	window.onload=function(){
		var oBtn=document.getElementById('btn1');
		init();
		oBtn.onclick=function(){
			var coin=new Coin();
		}
		var SHAKE_THRESHOLD = 400;
        var last_update = 0;
		var index=0;
        var x = y = z = last_x = last_y = last_z = 0;
		var w_curTime=0;
        function init() {
            if (window.DeviceMotionEvent) {
                window.addEventListener('devicemotion', deviceMotionHandler, false);
            } else {
                alert('not support mobile event');
            }
        }
        function deviceMotionHandler(eventData) {
            var acceleration = eventData.accelerationIncludingGravity;
            var curTime = new Date().getTime();
            if ((curTime - last_update) > 100) {
                var diffTime = curTime - last_update;
                last_update = curTime;
                x = acceleration.x;
                y = acceleration.y;
                z = acceleration.z;
                var speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;
				var delta=Math.abs(x + y + z - last_x - last_y - last_z);
                if (speed > SHAKE_THRESHOLD) {
					if((curTime-w_curTime)>2000){
						w_curTime!=0 && new Coin({density:Math.round(delta)});
					 	w_curTime=curTime;
					}
                }
                last_x = x;
                last_y = y;
                last_z = z;
            }
        }
	}
</script>
</head>
<body>
<input type="button" value="撒金币" id="btn1" />
</body>
</html>

来源于网络

站点声明:部分内容源自互联网,为传播信息之用,如有侵权,请联系我们删除。

© Copyright 2011-2024 www.kfju.com. All Rights Reserved.
超级字帖 版权所有。 蜀ICP备12031064号      川公网安备51162302000234