JavaScript实现的3D旋转魔方动画效果实例代码


Posted in Javascript onJuly 31, 2019

JS1K是JavaScript编程竞赛——参加竞赛的规则很简单,脚本必须小于1K,竞赛网站开始也只是为了娱乐,却意外地收到了很多优秀的作品。

这是2016年JS1k上传的作品,用几十行代码实现的一个3D旋转魔方:

JavaScript实现的3D旋转魔方动画效果实例代码

代码如下:

function z(t, e) {
  return t? e? t.appendChild(e) : "width:"+t+"px;height:"+t+"
px;position:absolute;" : document.createElement("div")
}

function w() {
  ++t==360&&(t=0, x=++x%3)
  for (i in m) 2 == m[i][s[x]] ? m[i][u][a] = r+s[x]+"(" + t + "deg)" : 0;
  c[u][a] = r+"3d(1,1,1," + t + "deg)", 
	requestAnimationFrame(w)
}
var a = "transform",
	p = "background-color:",
	y = a+"-style:preserve-3d;",
  u = "style",
  v = "cssText",
  B = z(),
  c = z(),
  t = x = 0,
  d, e, f, g, h, k, l, m = [], n, i, r="rotate", s = ["X","Y","Z"];

B[u][v] = "perspective:900px;"+z(600)+p+"#666";
c[u][v] = y + z(240) +"top:30%;left:30%", z(B, c), z(window.b, B);

for (l = 27; l--; z(c, f)) {
  f = z(), 
  f[u][v] = y + z(240), 
  f.X = g = l % 3, 
  f.Y = h = (l - g) % 9 / 3, 
  f.Z = k = ~~(l / 9), e = z(), 
  e[u][v] = y + z(80) +a+":translate3d(" + 80 * g + "px," + 
80 * h + "px," + 80 * (k-1) + "px)";
  for (n = 6; n--; z(e, d)) 
  	d = z(), 
  	d[u][v] = y + z(72) + "border-radius:9px;border:4px solid
 #000;opacity:0.9;"+a+":"+r+"X(" + (4 > n ? 90 * n : 0) 
 + "deg)"+r+"Y(" + (4 > n ? 0 : 4 == n ? -90 : 90) + "deg)translateZ(40px);"+p+ 
  	(0==n&&2==k?"#05C":1==n&&0==h?"#FD0":
 2==n&&0==k?"#0A6":3==n&&2==h?"#FFF":4==n&&0==g?"#F60":5==n&&2==g?"#C24":"#000");
  z(f, e), m.push(f)
}

w();

知识点扩展

JS如何实现旋转的魔方,浏览器从其他标签页回来依然匀速旋转?

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <div class="cube" onclick="stop()">
    <div class="front">front</div>
    <div class="back">back</div>
    <div class="left">left</div>
    <div class="right">right</div>
    <div class="top">top</div>
    <div class="bottom">bottom</div>
  </div>
</body>
<style>
  .cube {
    width: 400px;
    height: 400px;
    transition: all 3s;
    margin: 300px auto;
    /* 作用于所有3d转换的子元素 设置给父级 */
    /* perspective: 1000px; */
    /* transform: rotateX(30deg) rotateY(45deg); */
    /* 平面到立方 默认值:平面flat*/
    transform-style: preserve-3d;

    position: relative;
  }

  /* div:hover {
    transform: rotateY(90deg) translateZ(-200px);
    opacity: 0.5;
  } */
  .front,
  .back,
  .left,
  .right,
  .top,
  .bottom {
    width: 100%;
    height: 100%;
    text-align: center;
    line-height: 400px;
    position: absolute;
    opacity: 0.9;
    left: 0;
    top: 0;
  }

  .front {
    background-color: palevioletred;
    background-image: url('http://img1.gtimg.com/tj/pics/hv1/117/208/2153/140051982.jpg');
    transform: translateZ(200px);
  }

  .back {
    background-color: yellow;
    transform: translateZ(-200px);
    background-image: url('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=841408372,3004217725&fm=11&gp=0.jpg');
  }

  .left {
    background-color: pink;
    background-image: url('https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2388632836,3966607624&fm=26&gp=0.jpg');
    transform: rotateY(90deg) translateZ(-200px)
  }

  .right {
    background-color: yellowgreen;
    background-image: url('https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=192610795,467565159&fm=26&gp=0.jpg');
    transform: rotateY(90deg) translateZ(200px)
  }

  .top {
    background-color: skyblue;
    background-image: url("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2936477803,4198185787&fm=15&gp=0.jpg");
    transform: rotateX(90deg) translateZ(200px)
  }

  .bottom {
    background-color: orange;
    background-image: url('http://img0.pclady.com.cn/pclady/1611/02/1612285_jyz.jpg');
    transform: rotateX(90deg) translateZ(-200px)
  }
</style>
<script>
  window.onload = function () {
    let cube = document.querySelector('.cube')
    let timer = null
    let x = 0; y = 0;
    function rotate() {
      cube.style.transform = 'rotateX(' + x + 'deg)' + '' + 'rotateY(' + y + 'deg)';
      x += 30
      y += 45
    }
    function stop() {
      clearInterval(timer)
    }
    clearInterval(timer);
    timer = setInterval(() => {
      rotate();
    }, 1000);
    // 监听是否在当前页,并置为已读
    // document.addEventListener("visibilitychange", function () {
    //   if (document.hidden) {  //不处于当前页面
    //     // do something
    //     clearInterval(timer)
    //   } else {
    //     timer;
    //   }
    // });

    var hiddenProperty = 'hidden' in document ? 'hidden' :
      'webkitHidden' in document ? 'webkitHidden' :
        'mozHidden' in document ? 'mozHidden' :
          null;
    var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
    var onVisibilityChange = function () {
      if (!document[hiddenProperty]) {
        timer = setInterval(() => {
          rotate();
        }, 1000);
        console.log(hiddenProperty);
      } else {
        clearInterval(timer)
      }
    }
    document.addEventListener(visibilityChangeEvent, onVisibilityChange);
    // document.addEventListener("visibilitychange", function () {
    //   if (!document.hidden) {  //处于当前页面
    //     timer = setInterval(() => {
    //       rotate();
    //     }, 1000);
    //     console.log('active');
    //   } else {
    //     clearInterval(timer);
    //     console.log('hidden');
    //   }
    // });
  }
</script>

</html>
Javascript 相关文章推荐
六款帮助你实现惊艳视差滚动效果的jQuery插件
Sep 14 Javascript
JS简单实现文件上传实例代码(无需插件)
Nov 15 Javascript
JQuery.get提交页面不跳转的解决方法
Jan 13 Javascript
js实现人才网站职位选择功能的方法
Aug 14 Javascript
利用AngularJs实现京东首页轮播图效果
Sep 08 Javascript
SVG描边动画
Feb 23 Javascript
详解React开发必不可少的eslint配置
Feb 05 Javascript
微信小程序实现上传图片功能
May 28 Javascript
vue 监听屏幕高度的实例
Sep 05 Javascript
JavaScript的查询机制LHS和RHS解析
Aug 16 Javascript
基于vue-draggable 实现三级拖动排序效果
Jan 10 Javascript
Vue 3.0 全家桶抢先体验
Apr 28 Javascript
vue 实现滚动到底部翻页效果(pc端)
Jul 31 #Javascript
js实现一个简易计算器
Mar 30 #Javascript
微信小程序iBeacon测距及稳定程序的实现解析
Jul 31 #Javascript
JS获取动态添加元素的方法详解
Jul 31 #Javascript
JS/jQuery实现超简单的Table表格添加,删除行功能示例
Jul 31 #jQuery
详解Vuex下Store的模块化拆分实践
Jul 31 #Javascript
ES6 Iterator接口和for...of循环用法分析
Jul 31 #Javascript
You might like
为php4加入动态flash文件的生成的支持
2006/10/09 PHP
PHP获取和操作配置文件php.ini的几个函数介绍
2013/06/24 PHP
php中try catch捕获异常实例详解
2014/11/21 PHP
php中判断数组相等的方法以及数组运算符介绍
2015/03/30 PHP
firefox浏览器不支持innerText的解决方法
2013/08/07 Javascript
运用JQuery的toggle实现网页加载完成自动弹窗
2014/03/18 Javascript
jquery trigger伪造a标签的click事件取代window.open方法
2014/06/23 Javascript
jquery实现简单的自动播放幻灯片效果
2015/06/13 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
2015/09/27 Javascript
javascript中apply、call和bind的使用区别
2016/04/05 Javascript
基于javascript实现按圆形排列DIV元素(一)
2016/12/02 Javascript
canvas 弹幕效果(实例分享)
2017/01/11 Javascript
js简单实现网页换肤功能
2017/04/07 Javascript
jQuery获取table表中的td标签(实例讲解)
2017/07/28 jQuery
React中使用collections时key的重要性详解
2017/08/07 Javascript
React/Redux应用使用Async/Await的方法
2017/11/16 Javascript
微信小程序左右滑动的实现代码
2017/12/15 Javascript
vue中tab选项卡的实现思路
2018/11/25 Javascript
vue动态绑定class的几种常用方式小结
2019/05/21 Javascript
微信小程序实现的picker多级联动功能示例
2019/05/23 Javascript
vue项目中引入Sass实例方法
2019/08/27 Javascript
layer 刷新某个页面的实现方法
2019/09/05 Javascript
Vue实现页面添加水印功能
2019/11/09 Javascript
vue实现户籍管理系统
2020/05/29 Javascript
vue 判断页面是首次进入还是再次刷新的实例
2020/11/05 Javascript
python算法学习之基数排序实例
2013/12/18 Python
使用wxpython实现的一个简单图片浏览器实例
2014/07/10 Python
python实现清屏的方法
2015/04/30 Python
Python编程中使用Pillow来处理图像的基础教程
2015/11/20 Python
Python随机读取文件实现实例
2017/05/25 Python
Python queue队列原理与应用案例分析
2019/09/27 Python
PyCharm上安装Package的实现(以pandas为例)
2020/09/18 Python
意大利单身交友网站:Meetic
2020/07/12 全球购物
应届毕业生求职信范例分享
2013/12/17 职场文书
2014年党建工作汇报材料
2014/11/02 职场文书
DIV CSS实现网页背景半透明效果
2021/12/06 HTML / CSS