前几天在园子里看到一篇关于CSS3D行星运转的文章,原文在这里,感觉这个效果也太酷炫了,于是自己也就心血来潮的来尝试的做了一下。因为懒得去用什么插件了,于是就原生的JS写,效果有点粗超,还有一些地方处理的不是很好,如果有好的建议万望留言告知,不胜感谢。源代码已上传到github上,点这里获取。好了不说废话了,下面附上代码。

HTML部分

  1. <div class="path-Saturn">
  2. <div id="Saturn" title="土星">
  3. <div class="x"></div>
  4. <div class="y"></div>
  5. <div class="z"></div>
  6. <div class="space space-x"></div>
  7. <div class="space space-x1"></div>
  8. <div class="space space-x2"></div>
  9.  
  10. <div class="space space-y"></div>
  11. <div class="space space-y1"></div>
  12. <div class="space space-y2"></div>
  13.  
  14. <div class="space space-z"></div>
  15. <div class="space space-z1"></div>
  16. <div class="space space-z2"></div>
  17.  
  18. <!-- 卫星 -->
  19. <div class="path-satellite">
  20. <div id="satellite" title="卫星">
  21. <div class="x"></div>
  22. <div class="y"></div>
  23. <div class="z"></div>
  24. <div class="space space-x"></div>
  25. <div class="space space-x1"></div>
  26. <div class="space space-x2"></div>
  27.  
  28. <div class="space space-y"></div>
  29. <div class="space space-y1"></div>
  30. <div class="space space-y2"></div>
  31.  
  32. <div class="space space-z"></div>
  33. <div class="space space-z1"></div>
  34. <div class="space space-z2"></div>
  35. </div>
  36. </div>
  37. </div>
  38. </div>

这里用前三个类为x、y、z的div来画的每一个星球的x、y、z轴,然后这些星球之间是可以嵌套的,就是像上面的代码一样,里面的星球是外面星球的卫星。

css部分

  1. .path-Saturn, .path-earth, .path-Venus, .path-Neptune, .path-Jupiter, .path-Mercury, .path-satellite, .path-moon{
  2. position: absolute;
  3. width: 95%;
  4. height: 95%;
  5. top: 2.5%;
  6. left: 2.5%;
  7. border: 1px solid #ddd;
  8. border-radius: 50%;
  9. transform: rotateX(60deg);
  10. transform-style: preserve-3d;
  11. }
  12. #sun, #earth, #Saturn, #Venus, #Neptune, #Jupiter, #Mercury, #satellite, #moon{
  13. width: 160px;
  14. height: 160px;
  15. position: absolute;
  16. transform-style: preserve-3d;
  17. top: 50%;
  18. left: 50%;
  19. margin: -80px 0 0 -80px;
  20. animation: rotateForward 10s linear infinite;
  21. cursor: pointer;
  22. transform: translateZ(-80px);
  23. }
  24. /*x, y, z轴*/
  25. .x, .y, .z{
  26. position: absolute;
  27. height: 100%;
  28. border: 1px solid #999;
  29. left: 50%;
  30. margin-left: -1px;
  31. }
  32. .y{
  33. transform: rotateZ(90deg);
  34. }
  35. .z{
  36. transform: rotateX(90deg);
  37. }
  38. @keyframes rotateForward {
  39. 0%{
  40. transform: rotate3d(1, 1, 1, 0deg);
  41. }
  42. 100%{
  43. transform: rotate3d(1, 1, 1, -360deg);
  44. }
  45. }
  46. /*Saturn*/
  47. #Saturn{
  48. width: 80px;
  49. height: 80px;
  50. left: 0%;
  51. margin: -40px 0 0 -40px;
  52. animation: rotateForward 4s linear infinite;
  53. transform: translateZ(-40px);
  54. }
  55. #Saturn .space{
  56. width: 80px;
  57. height: 80px;
  58. box-shadow: 0 0 60px rgba(90, 80, 53, 1);
  59. background-color: rgba(90, 80, 53, .3);
  60. }
  61. #Saturn .space-x1, #Saturn .space-x2, #Saturn .space-y1, #Saturn .space-y2, #Saturn .space-z1, #Saturn .space-z2{
  62. width: 87.5%;
  63. height: 87.5%;
  64. top: 6.25%;
  65. left: 6.25%;
  66. transform: rotate3d(0, 0, 0, 0deg) translateZ(20px);
  67. }
  68. #Saturn .space-x1{
  69. transform: rotate3d(0, 0, 0, 0deg) translateZ(-20px);
  70. }
  71. #Saturn .space-y{
  72. transform: rotate3d(0, 1, 0, 90deg) translateZ(0px);
  73. }
  74. #Saturn .space-y1{
  75. transform: rotate3d(0, 1, 0, 90deg) translateZ(-20px);
  76. }
  77. #Saturn .space-y2{
  78. transform: rotate3d(0, 1, 0, 90deg) translateZ(20px);
  79. }
  80. #Saturn .space-z{
  81. transform: rotate3d(1, 0, 0, 90deg) translateZ(0px);
  82. }
  83. #Saturn .space-z1{
  84. transform: rotate3d(1, 0, 0, 90deg) translateZ(-20px);
  85. }
  86. #Saturn .space-z2{
  87. transform: rotate3d(1, 0, 0, 90deg) translateZ(20px);
  88. }

CSS部分

主要就是用九个面通过各种旋转、平移来拼凑出一个球体。然后因为这里没有写兼容方面的代码,所以有兴趣down下来源代码的朋友,尽量用chrome浏览器打开。这里有几个CSS3属性需要说一下:

1、transform-style: preserve-3d;   用来让设置了该属性的容器的子元素以3D效果展示。

2、transform-origin: 设置旋转元素的旋转、平移的基点位置。

3、perspective:  设置元素被查看位置的视图。

JS部分

  1. (function(planetObj, TimeArr, judgeDirec) {
  2. //检测参数是否规范
  3. var timeRegexp = /^[1-9][0-9]*$/,
  4. direcRegexp = /^[01]$/;
  5. function checkArgs (arg, ele, regexp) {
  6. if(arg){
  7. $(arg).each(function (i, item) {
  8. if(arg.length != planetObj.length || !regexp.test(item)){
  9. throw Error('an error occured');
  10. return;
  11. }else{
  12. return arg;
  13. }
  14. })
  15. }else{
  16. arg = [];
  17. for(var i = 0; i < planetObj.length; i++){
  18. arg.push(ele);
  19. }
  20. }
  21. return arg;
  22. }
  23. TimeArr = checkArgs(TimeArr, 50, timeRegexp);
  24. judgeDirec = checkArgs(judgeDirec, 1, direcRegexp);
  25.  
  26. var PathArr = [];
  27. $(planetObj).each(function (i, item) {
  28. var n = 0; //定义一个标识,来判断当前是怎么运动的
  29. PathArr.push({
  30. a : $(item).parent().width() / 2,
  31. b : $(item).parent().height() / 2
  32. });
  33.  
  34. //变化x坐标,然后根据椭圆轨迹,获得y坐标,以达到运动的效果
  35. function getEllopsePath (x, PathObj) {
  36. x = x - PathObj.a;
  37. var m;
  38.  
  39. n ? (judgeDirec[i] ? m = 1 : m = -1) : (judgeDirec[i] ? m = -1 : m = 1); //判断开根号求得的y值是否为负数,从而确定旋转方向
  40. // if(judgeDirec[i]){
  41. // n ? (m = judgeDirec[i]) : (m = judgeDirec[i]-2);
  42. // }else{
  43. // n ? (m = judgeDirec[i] - 1) : (m = judgeDirec[i] + 1);
  44. // }
  45. return Math.sqrt((1 - x * x / (PathObj.a * PathObj.a)) * PathObj.b * PathObj.b) * m + PathObj.b;
  46. }
  47.  
  48. function moving () {
  49. var x = parseInt($(item).css('left'), 10);
  50. if(x == 2 * PathArr[i].a){ //到达轨迹的右零界点的时候x减小
  51. n--;
  52. }else if (x == 0) { //到达轨迹的左临界点的时候,x增加
  53. n++;
  54. }
  55. n ? x++ : x--;
  56. $(item).css({
  57. 'top' : getEllopsePath(x, PathArr[i]) + 'px',
  58. 'left' : x + 'px'
  59. });
  60. }
  61.  
  62. setInterval(moving, TimeArr[i]);
  63. });
  64. })(['#Saturn', '#earth', '#Venus', '#Neptune', '#Mercury', '#Jupiter', '#satellite', '#moon'], [40, 180, 240, 20, 120, 200, 30, 10]/*option默认为50毫秒*/, [1, 0, 0, 0, 1, 0, 1, 1]/*option 判断运动方向,0为顺时针,1为逆时针,默认为逆时针*/);

这里在实现星球运动的时候,有一些地方处理的不是很好,因为我是按照每隔一定的时间,让星球的left的位置变化,然后根据椭圆的公式,求出top的值。因为椭圆是不均匀的,所以这会使得星球的运动看起来时快时慢,因为他的top值,变化是不均匀的。

然后这里还有个地方需要注意下,就是Math.sqrt()这个方法开出来的值全是正数,而我们要让星球环绕一周,就需要在轨迹的左右两端动态的改变Math.sqrt()这个方法开出来的值的正负数。

下面附上一张效果图

好了,今天就先写到这里了,作者敲键盘码字也不容易,如果你觉得你对本文还能提得上来那么一点点兴趣的话,请稍微移动下你的右手,帮点下赞,谢谢^_^。

css3加js做一个简单的3D行星运转效果的更多相关文章

  1. 用JS做一个简单的电商产品放大镜功能

    使用js制作一个简单的产品放大图 购物网站的产品页经常会放有一个产品展示图区.该图区有一个功能就是产品图的放大功能,移动左侧的焦点区域,可以放大细节部分观看,详情如下图.实现该功能的方法也非常简单. ...

  2. 用js做一个简单的留言板效果

    html部分: 1: <!DOCTYPE> 2: <html lang="zh-en"> 3: <head> 4: <title>j ...

  3. D3.js 做一个简单的图表(条形图)

    柱形图是一种最简单的可视化图标,主要有矩形.文字标签.坐标轴组成. 本文为简单起见,只绘制矩形的部分,用以讲解如何使用 D3 在 SVG 画布中绘图. 一. 画布是什么 前几章的处理对象都是 HTML ...

  4. 用JS,做一个简单的计算器

    <!DOCTYPE html> <html> <head> <meta charset="utf-8">   <title&g ...

  5. 【 D3.js 入门系列 --- 3 】 做一个简单的图表!

    前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为 ...

  6. HTML 5 +CSS3 + 原生js 做(雪花全屏飘落 + 3d旋转图)

    原文:HTML 5 +CSS3 + 原生js 做(雪花全屏飘落 + 3d旋转图) 3d旋转图:主要用css3中transform属性中的rotate,translate;以及用来做舞台效果的 pers ...

  7. 【 D3.js 入门系列 — 3 】 做一个简单的图表!

    图1. 柱形图 1. 柱形图 前几章的例子,都是对文字进行处理.本章中将用 D3 做一个简单的柱形图.制作柱形图有很多种方法,比如用 HTML 的 <div> 标签,或在 SVG 上绘制 ...

  8. 使用React并做一个简单的to-do-list

    1. 前言 说到React,我从一年之前就开始试着了解并且看了相关的入门教程,而且还买过一本<React:引领未来的用户界面开发框架 >拜读.React的轻量组件化的思想及其virtual ...

  9. 第四章 .net core做一个简单的登录

    项目目标部署环境:CentOS 7+ 项目技术点:.netcore2.0 + Autofac +webAPI + NHibernate5.1 + mysql5.6 + nginx 开源地址:https ...

随机推荐

  1. ElasticSearch 常用 curl 命令

    1. 集群支持的选项 curl -XGET 'http://10.240.0.8:9200/_cat'  2. 查看节点信息 curl -XGET 'http://10.240.0.8:9200/_ ...

  2. 从零开始一起学习SALM-ICP原理及应用

    点"计算机视觉life"关注,星标更快接收干货! ## 小白:师兄,最近忙什么呢,都见不到你人影,我们的课也好久没更新了呢 师兄:抱歉,抱歉,最近忙于俗事.我后面一起补上,学习劲头 ...

  3. 并发编程-concurrent指南-阻塞队列-延迟队列DelayQueue

    DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的,即队头对象的延迟到期时间最长.注意:不能 ...

  4. flutter 如何实现文件读写(使用篇)

    flutter文件读写可以对磁盘文件进行操作,实现某些业务场景,那么我们开始来讲下这个文件读写操作. 使用的库插件(package) dart:io(用于数据处理) path_provider (用于 ...

  5. HDU XXXX:求[L,R]的素数数量(数位DP)

    Problem G Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/131072K (Java/Other) Total S ...

  6. django基础知识之Ajax:

    使用Ajax 使用视图通过上下文向模板中传递数据,需要先加载完成模板的静态页面,再执行模型代码,生成最张的html,返回给浏览器,这个过程将页面与数据集成到了一起,扩展性差 改进方案:通过ajax的方 ...

  7. Effective Java第三版(一) ——用静态工厂代替构造器

    此文做为<Effective Java>系列的第一篇,所以有必要大概说下此书的特点,当然很多人可能都看过,毕竟是有着Java四大名著之一的大名在外,不过总会有萌新不了解,例如我!<E ...

  8. python数据库-mongoDB的高级查询操作(55)

    一.MongoDB索引 为什么使用索引? 假设有一本书,你想看第六章第六节讲的是什么,你会怎么做,一般人肯定去看目录,找到这一节对应的页数,然后翻到这一页.这就是目录索引,帮助读者快速找到想要的章节. ...

  9. Java开发IDEA插件推荐

    IDEA插件推荐 Alibaba Java Coding Guidelines MyBatisCodeHelper-Pro Lombok GsonFormat AceJump Statistic Tr ...

  10. 一些ServiceFabric、Orleans、Asp.net Aore的例子

    Sample: ServiceFabric + Orleans + Asp.net Core : Asp.net Core 142 samples for ASP.NET Core 2.1 funda ...