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 相关文章推荐
javascript 写类方式之五
Jul 05 Javascript
jquery异步循环获取功能实现代码
Sep 19 Javascript
基于Jquery的动态创建DOM元素的代码
Dec 28 Javascript
jquery 层次选择器siblings与nextAll的区别介绍
Aug 02 Javascript
Javascript Ajax异步读取RSS文档具体实现
Dec 12 Javascript
javascript引用类型指针的工作方式
Apr 13 Javascript
jQuery动画效果实现图片无缝连续滚动
Jan 12 Javascript
js实现图片无缝滚动特效
Mar 19 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
Sep 11 Javascript
jquery实现企业定位式导航效果
Jan 01 jQuery
图文讲解vue的v-if使用方法
Feb 11 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
Oct 29 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
海贼王动画变成“真人”后,凯多神还原,雷利太帅了!
2020/04/09 日漫
隐性调用php程序的方法
2009/03/09 PHP
php更改目录及子目录下所有的文件后缀的代码
2010/09/24 PHP
PHP实现绘制3D扇形统计图及图片缩放实例
2014/10/01 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
JS类的封装及实现代码
2009/12/02 Javascript
intro.js 页面引导简单用法 分享
2013/08/06 Javascript
js 文本滚动效果的实例代码
2013/08/17 Javascript
Javascript中string转date示例代码
2013/11/01 Javascript
jquery css 设置table的奇偶行背景色示例
2014/06/03 Javascript
javascript制作幻灯片(360度全景图片)
2015/07/28 Javascript
jquery与ajax获取特殊字符实例详解
2017/01/08 Javascript
nodejs搭建本地服务器并访问文件的方法
2017/03/03 NodeJs
AngularJS前端页面操作之用户修改密码功能示例
2017/03/27 Javascript
使用prop解决一个checkbox选中后再次选中失效的问题
2017/07/05 Javascript
vue中实现methods一个方法调用另外一个方法
2018/02/08 Javascript
layui获取多选框中的值方法
2018/08/15 Javascript
微信小程序自定义toast的实现代码
2018/11/16 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
python使用MySQLdb访问mysql数据库的方法
2015/08/03 Python
Python数字图像处理之霍夫线变换实现详解
2018/01/12 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
2019/08/30 Python
基于Python解密仿射密码
2019/10/21 Python
如何导出python安装的所有模块名称和版本号到文件中
2020/06/05 Python
Vs Code中8个好用的python 扩展插件
2020/10/12 Python
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
阿迪达斯越南官网:adidas越南
2020/07/19 全球购物
电子商务专业个人的自我评价
2013/11/19 职场文书
九年级体育教学反思
2014/01/23 职场文书
成立公司计划书
2014/05/07 职场文书
护士自荐信范文
2015/03/25 职场文书
mysql在项目中怎么选事务隔离级别
2021/05/25 MySQL
Vue OpenLayer 为地图绘制风场效果
2022/04/24 Vue.js