html5实现魔方自由落体运动

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<style type="text/css">
		* {
			margin: 0;
			padding: 0;
		}
		
		body {
			background: gray;
		}
		
		#box {
			width: 30px;
			height: 490px;
			background: black;
		}
		
		#box1 {
			width: 30px;
			height: 30px;
			background: white;
		}
		
		#box2 {
			/*设置魔方的位置*/
			top: 0;
			left: 0;
			position: fixed;
			transform-style: preserve-3d;
			/*3d渲染*/
			animation: cube_animation 3s linear infinite;
			/*魔方动画设置 forwards属性表示当动画完成后保持最后一帧的属性*/
			transform-origin: 15px 15px 0;
			/*设置中心基点,以box所在的div的边框左上角为原点(0,0)*/
		}
		/*魔方动画效果*/
		
		@keyframes cube_animation {
			0% {
				transform: rotateX(0) rotateY(0) rotateZ(45deg);
			}
			50% {
				transform: rotateX(0) rotateY(360deg) rotateZ(45deg);
			}
			100% {
				transform: rotateX(0) rotateY(720deg) rotateZ(45deg);
			}
		}
		/*魔方六面*/
		
		#whside {
			width: 30px;
			height: 30px;
			position: absolute;
			/* 
			 * 白色面放在上面
			 * rotateX(90deg) 基点为由于每一个维度有四个面,每个面占据的角度为360deg/4=90deg
			 * translateZ(90px) 往外移动90px的距离
			 * */
			transform: rotateX(90deg) translateZ(15px);
		}
		
		#whside div {
			width: 8px;
			height: 8px;
			border-radius: 2px;
			/*设置圆角才能看到格子与格子间的小孔*/
			float: left;
			/*没有top 和bottom*/
			border: 1px solid #000;
			/* 这里定义每个格子的边框是3px 所以一个格子总的长宽是8+1+1=30px 一行3个格子30*3=90px 一列同理 */
			background: white;
			/*上白色*/
		}
		
		#yeside {
			width: 30px;
			height: 30px;
			position: absolute;
			/*黄色面放在底面*/
			transform: rotateX(-90deg) translateZ(15px);
		}
		
		#yeside div {
			width: 8px;
			height:8px;
			border-radius: 2px;
			float: left;
			border: 1px solid #000;
			background: yellow;
			/*上黄色*/
		}
		
		#reside {
			width: 30px;
			height: 30px;
			position: absolute;
			/*红色面为正面,所以不用旋转,直接外移就可以了*/
			transform: translateZ(15px);
		}
		
		#reside div {
			width: 8px;
			height:8px;
			border-radius: 2px;
			float: left;
			border: 1px solid #000;
			background: red;
			/*上红色*/
		}
		
		#blside {
			width: 30px;
			height: 30px;
			position: absolute;
			/*蓝色面放在右面*/
			transform: rotateY(90deg) translateZ(15px);
		}
		
		#blside div {
			width: 8px;
			height:8px;
			border-radius: 2px;
			float: left;
			border: 1px solid #000;
			background: blue;
			/*上蓝色*/
		}
		
		#orside {
			width: 30px;
			height: 30px;
			position: absolute;
			/*橙色面放在后面*/
			transform: rotateY(180deg) translateZ(15px);
		}
		
		#orside div {
			width: 8px;
			height:8px;
			border-radius: 2px;
			float: left;
			border: 1px solid #000;
			background: orange;
			/*上橙色*/
		}
		
		#grside {
			width: 30px;
			height: 30px;
			position: absolute;
			/*绿色面放在左面 rotateY(-90deg)可以得到相同效果*/
			transform: rotateY(-90deg) translateZ(15px);
		}
		
		#grside div {
			width: 8px;
			height:8px;
			border-radius: 2px;
			float: left;
			border: 1px solid #000;
			background: green;
			/*上绿色*/
		}
		
		#btn {
			width: 50px;
			height: 30px;
			right: 50px;
			bottom: 50px;
			position: fixed;
		}
	</style>

	<body>
		<div id="box">
			<div id="box1">
				<div id="box2">
					<!--上面白色-->
					<div id="whside">
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
					</div>
					<!--底部黄色-->
					<div id="yeside">
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
					</div>
					<!--前面红色-->
					<div id="reside">
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
					</div>
					<!--右面蓝色-->
					<div id="blside">
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
					</div>
					<!--后面橙色-->
					<div id="orside">
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
					</div>
					<!--左面绿色-->
					<div id="grside">
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
						<div></div>
					</div>
				</div>
			</div>

		</div>

		<button id="btn">点击</button>
	</body>
	<script type="text/javascript">
		//获取按钮对象
		var btn = document.getElementById("btn");
		btn.onclick = function flow() {
			var mofa = document.getElementById("box2"); //获取整个魔方对象
			var winHeight = 490; //设置下落高度
			var gSpeed = 9.8; //重力加速度
			var firstV = 0; //初速度
			var endV = Math.sqrt(2 * gSpeed * winHeight); //末速度
			var limitHeight = winHeight; //判读位移是否越界
			var top_px = 0; //魔方位置
			var isFall = true; //判断是否处于下落状态
			var t = 0; //已经经历过的时间
			var shiftHeight = 0; //位移
			//记录点击时的时间戳
			var click_t = (new Date().getMinutes() * 60 * 1000) + (new Date().getSeconds() * 1000) + new Date().getMilliseconds();
			//每隔time秒执行一次下面function()匿名函数
			var timer = setInterval(function() {
				//判断是否到达上下顶点(误差为0.01px)
				if((limitHeight - shiftHeight) < 0.01) {
					isFall = !isFall; //状态反转
					endV = endV * 0.9; //设置弹起的速度为原来的下落的速度的90%;
					if(isFall) {
						firstV = 0; //下落时初速度重新设置为0
					} else {
						//限制高度重新计算:上抛的时候才重新计算限制高度,下落时不需要计算
						limitHeight = (endV * endV) / (2 * gSpeed);
						firstV = endV; //上抛时初速度重新设置为原来的末速度
					}
					shiftHeight = 0; //位移归零
					//记录每次状态改变的时候的时间戳
					click_t = (new Date().getMinutes() * 60 * 1000) + (new Date().getSeconds() * 1000) + new Date().getMilliseconds();
				}
				//获取时间差(本轮抛体运动开始到这一点的时间差)
				t = (((new Date().getMinutes() * 60 * 1000) + (new Date().getSeconds() * 1000) + new Date().getMilliseconds()) - click_t);
				//转化单位为秒
				t = t / 1000;
				t = t * 10; //加快物体降落的时间
				if(isFall) {
					//计算下拋位移
					shiftHeight = (firstV * t) + (gSpeed * t * t / 2);
					top_px = winHeight + shiftHeight - limitHeight; //魔方位置就是位移
				} else {
					//上抛位移
					shiftHeight = (firstV * t) - (gSpeed * t * t / 2); 
					top_px = winHeight - shiftHeight;
				}
				//关闭定时器(误差为0.01px)
				if(limitHeight <= 0.01) {
					clearInterval(timer);
				}
				mofa.style.top = top_px + "px";

			}, 0)
			
			
		}
		
	</script>

</html>

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值