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 相关文章推荐
在一个form用一个SUBMIT(或button)分别提交到两个处理表单页面的代码
Feb 15 Javascript
动态加载图片路径 保持JavaScript控件的相对独立性
Sep 03 Javascript
jquery下动态显示jqGrid以及jqGrid的属性设置容易出现问题的解决方法
Oct 22 Javascript
读jQuery之三(构建选择器)
Jun 11 Javascript
如何根据百度地图计算出两地之间的驾驶距离(两种语言js和C#)
Oct 29 Javascript
JavaScript设计模式经典之命令模式
Feb 24 Javascript
js中利用cookie实现记住密码功能
Aug 20 Javascript
echarts3 使用总结(绘制各种图表,地图)
Jan 05 Javascript
Vue2.0中集成UEditor富文本编辑器的方法
Mar 03 Javascript
JavaScript 高性能数组去重的方法
Sep 20 Javascript
详解Vue中的自定义指令
Dec 07 Vue.js
原生js实现无缝轮播图效果
Jan 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
PHP PDO函数库详解
2010/04/27 PHP
memcached 和 mysql 主从环境下php开发代码详解
2010/05/16 PHP
PHP中最容易忘记的一些知识点总结
2013/04/28 PHP
PHP与javascript实现变量交互的示例代码
2013/07/23 PHP
ThinkPHP提交表单时默认自动转义的解决方法
2014/11/25 PHP
php删除文本文件中重复行的方法
2015/04/28 PHP
PHP设计模式之适配器模式定义与用法详解
2018/04/03 PHP
javascript 特性检测并非浏览器检测
2010/01/15 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
2014/10/29 Javascript
JQuery实现动态添加删除评论的方法
2015/05/18 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
2015/08/06 Javascript
JavaScript为事件句柄绑定监听函数实例详解
2015/12/15 Javascript
JavaScript中ES6字符串扩展方法
2016/08/26 Javascript
详解前端路由实现与react-router使用姿势
2017/08/07 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
微信小程序canvas拖拽、截图组件功能
2018/09/04 Javascript
vue element table 表格请求后台排序的方法
2018/09/28 Javascript
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
vue两组件间值传递 $router.push实现方法
2019/05/15 Javascript
详解如何在Javascript和Sass之间共享变量
2019/11/13 Javascript
jQuery实现移动端笔触canvas电子签名
2020/05/21 jQuery
ES5和ES6中类的区别总结
2020/12/21 Javascript
python发送邮件的实例代码(支持html、图片、附件)
2013/03/04 Python
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
python实现猜数字游戏(无重复数字)示例分享
2014/03/29 Python
pygame实现俄罗斯方块游戏(基础篇2)
2019/10/29 Python
TensorFlow自定义损失函数来预测商品销售量
2020/02/05 Python
python爬虫开发之Beautiful Soup模块从安装到详细使用方法与实例
2020/03/09 Python
Python实现一个优先级队列的方法
2020/07/31 Python
使用python库xlsxwriter库来输出各种xlsx文件的示例
2020/09/01 Python
Clos19英国:高档香槟、葡萄酒和烈酒在线购物平台
2020/07/10 全球购物
群众路线教育实践活动实施方案
2014/10/31 职场文书
结婚保证书(卖身契)
2015/02/26 职场文书
正确使用MySQL INSERT INTO语句
2021/05/26 MySQL
Python echarts实现数据可视化实例详解
2022/03/03 Python
python神经网络Xception模型
2022/05/06 Python