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 相关文章推荐
2007/12/23更新创意无限,简单实用(javascript log)
Dec 24 Javascript
9个javascript语法高亮插件 推荐
Jul 18 Javascript
JavaScript回调(callback)函数概念自我理解及示例
Jul 04 Javascript
学习JavaScript鼠标响应事件
Dec 25 Javascript
jQuery Easyui datagrid editor为combobox时指定数据源实例
Dec 19 Javascript
JS封装通过className获取元素的函数示例
Dec 20 Javascript
BootStrap的两种模态框方式
May 10 Javascript
Vue.js tab实现选项卡切换
May 16 Javascript
详解webpack3如何正确引用并使用jQuery库
Aug 26 jQuery
React教程之Props验证的具体用法(Props Validation)
Sep 04 Javascript
浅谈super-vuex使用体验
Jun 25 Javascript
微信小程序背景音乐开发详解
Dec 12 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
基于initPHP的框架介绍
2013/04/18 PHP
从零开始学YII2框架(五)快速生成代码工具 Gii 的使用
2014/08/20 PHP
PHP中的empty、isset、isnull的区别与使用实例
2019/03/22 PHP
js实现简单的星级选择器提交效果适用于评论等
2013/10/18 Javascript
为jquery的ajaxfileupload增加附加参数的方法
2014/03/04 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
jquery实现动静态条形统计图
2015/08/17 Javascript
如何使用jquery修改css中带有!important的样式属性
2016/04/28 Javascript
js 点击a标签 获取a的自定义属性方法
2016/11/21 Javascript
Vue中img的src属性绑定与static文件夹实例
2017/05/18 Javascript
javascript 跨域问题以及解决办法
2017/07/17 Javascript
初探JavaScript 面向对象(推荐)
2017/09/03 Javascript
微信小程序使用audio组件播放音乐功能示例【附源码下载】
2017/12/08 Javascript
微信、QQ、微博、Safari中使用js唤起App
2018/01/24 Javascript
详解Angular如何正确的操作DOM
2018/07/06 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
2018/10/08 Javascript
详解微信小程序之一键复制到剪切板
2019/04/24 Javascript
node获取客户端ip功能简单示例
2019/08/24 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
python程序快速缩进多行代码方法总结
2019/06/23 Python
Python 计算任意两向量之间的夹角方法
2019/07/05 Python
opencv转换颜色空间更改图片背景
2019/08/20 Python
Python 下载及安装详细步骤
2019/11/04 Python
python实现高斯判别分析算法的例子
2019/12/09 Python
Windows下Pycharm远程连接虚拟机中Centos下的Python环境(图文教程详解)
2020/03/19 Python
如何配置关联Python 解释器 Anaconda的教程(图解)
2020/04/30 Python
Python中猜拳游戏与猜筛子游戏的实现方法
2020/09/04 Python
html5 video全屏播放/自动播放的实现示例
2020/08/06 HTML / CSS
Douglas意大利官网:购买香水和化妆品
2020/05/27 全球购物
竞选演讲稿范文
2013/12/28 职场文书
就业推荐表自我鉴定范文
2014/03/21 职场文书
班级年度安全计划书
2014/05/01 职场文书
安全生产专项整治方案
2014/05/06 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
男方家长婚礼致辞
2015/07/27 职场文书