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 相关文章推荐
window.open的功能全解析
Oct 10 Javascript
原创javascript小游戏实现代码
Aug 19 Javascript
鼠标移动到图片名上,显示图片的简单实例
Jul 14 Javascript
一个支付页面DEMO附截图
Jul 22 Javascript
jQuery链式操作实例分析
Nov 16 Javascript
浅析Javascript中bind()方法的使用与实现
Apr 29 Javascript
JS实现表单验证功能(验证手机号是否存在,验证码倒计时)
Oct 11 Javascript
基于angularJS的表单验证指令介绍
Oct 21 Javascript
JavaScript实现的搜索及高亮显示功能示例
Aug 14 Javascript
详解vue路由篇(动态路由、路由嵌套)
Jan 27 Javascript
layer扩展打开/关闭动画的方法
Sep 23 Javascript
使用React代码动态生成栅格布局的方法
May 24 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 递归效率分析
2009/11/24 PHP
Sorting Array Values in PHP(数组排序)
2011/09/15 PHP
PHP高级对象构建 工厂模式的使用
2012/02/05 PHP
php自定义函数实现统计中文字符串长度的方法小结
2017/04/15 PHP
利用laravel+ajax实现文件上传功能方法示例
2017/08/13 PHP
thinkPHP5框架导出Excel文件简单操作示例
2018/08/03 PHP
php判断目录存在的简单方法
2019/09/26 PHP
laravel-admin 后台表格筛选设置默认的查询日期方法
2019/10/03 PHP
浅谈php常用的7大框架的优缺点
2020/07/20 PHP
js查错流程归纳
2012/05/04 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
js复制内容到剪贴板代码,js复制代码的简单实例
2016/10/27 Javascript
详解支持Angular 2的表格控件
2017/01/19 Javascript
jquery.param()实现数组或对象的序列化方法
2018/10/08 jQuery
node获取客户端ip功能简单示例
2019/08/24 Javascript
小程序跨页面交互的作用与方法详解
2020/01/07 Javascript
Node.js中文件系统fs模块的使用及常用接口
2020/03/06 Javascript
浅谈利用numpy对矩阵进行归一化处理的方法
2018/07/11 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
2018/07/27 Python
python 将日期戳(五位数时间)转换为标准时间
2019/07/11 Python
Python实现生成密码字典的方法示例
2019/09/02 Python
python:动态路由的Flask程序代码
2019/11/22 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
python实现QQ邮箱发送邮件
2020/03/06 Python
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
2019/06/03 HTML / CSS
澳大利亚和新西兰最大的在线旅行社之一:Aunt Betty
2019/08/07 全球购物
blueseventy官网:铁人三项和比赛泳衣
2021/02/06 全球购物
教堂婚礼主持词
2014/03/14 职场文书
关爱留守儿童倡议书
2014/04/15 职场文书
应急处置方案
2014/06/16 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
惹女朋友生气检讨书
2015/05/06 职场文书
党纪处分决定书
2015/06/24 职场文书
2019思想汇报范文
2019/05/21 职场文书
Python爬虫 简单介绍一下Xpath及使用
2022/04/26 Python