龙空技术网

css-画一个3D地球

web端开发 1627

前言:

现在同学们对“css3地球”大体比较注重,我们都需要知道一些“css3地球”的相关资讯。那么小编也在网络上搜集了一些关于“css3地球””的相关知识,希望你们能喜欢,朋友们快快来了解一下吧!

略微有点标题党,轻拍。。

先看效果:

说到球首先想到的,就是地球经纬度那样的线框图。

18条经线,18个圆,绕Y轴方法依次旋转10度17条纬线,从-80度开始一直到80度。纬线半径为cos(R),纬线偏移为sin(R)地球倾角为23度左右,加上一个旋转的动画效果

使用js来生成经纬线:

.container,.box {   	position: relative;      width: 100%;      height: 100%;      display: flex;     justify-content: center;     align-items: center;    transform-style: preserve-3d;}.container {    perspective: 500px;    overflow: hidden;}.box {    animation: rotate 20s linear infinite;}.box>div {    position: absolute;    width: 320px;    height: 320px;    border: solid 1px #000;  border-radius: 50%;}@keyframes rotate {   0% { transform: rotateZ(23deg) rotateY(0deg); }100% { transform: rotateZ(23deg) rotateY(360deg); }}
<div class="container">  <div class="box"> </div></div>
function addLongitude() {    var count = 18    var stepDeg = 180 / count    var fragment = document.createDocumentFragment()    for (var i = 0; i < count; i++) {        var div = document.createElement('div')        div.style.transform = 'rotateY(' + ~~(i * stepDeg) + 'deg)'        fragment.appendChild(div)    }    document.querySelector('.box').appendChild(fragment)}  function addLatitude() {      var r = 160      var stepDeg = 10      var start = -80      var end = 80      var fragment = document.createDocumentFragment()     for (var i = start; i <= end; i += stepDeg) {          var div = document.createElement('div')         var _r = ~~(Math.cos(i / 180 * Math.PI) * r * 2) + 'px'          div.style.width = _r          div.style.height = _r          div.style.transform = 'translateY(' + ~~(Math.sin(i / 180 * Math.PI) * r) + 'px) rotateX(90deg)'          fragment.appendChild(div)     }      document.querySelector('.box').appendChild(fragment)}    window.onload = function () {        addLongitude()        addLatitude()    }

线框图显然是不满足作为一个球的。

我们换个思路。把一个div填充了颜色,贴在球形的表面。

画一个有背景颜色的圆在Y轴上选择经度的角度,在X轴上旋转纬度的角度,在Z轴上向外偏移半径R然后纬度从-90度开始到90度依次铺满这个圆由于相同大小的填充圆,在两极用到的数量比赤道要少很多。我们根据纬线半径来调整一下填充数量

上边代码修改内部div样式

.box>div {    position: absolute;    width: 50px;    height: 50px;    border-radius: 50%;    background: rgba(255, 0, 0, .6);}
function draw(deg) {    var fragment = document.createDocumentFragment()   var r = 180 // 赤道半径    r *= Math.cos(deg * Math.PI * 2 / 360) // 对应纬度 圆半径    var size = 46 // 填充圆直径    var len = r * 2 * Math.PI / size    for (var i = 0; i < len; i++) {        var div = document.createElement('div')        div.style.transform = 'rotateY(' + ~~(360 / len * i) + 'deg) rotateX(' + deg + 'deg) translateZ(160px)'        fragment.appendChild(div)   }  document.querySelector('.box').appendChild(fragment)}window.onload = function () {    for (var i = -90; i <= 90; i += 20) {       draw(i)    }}

这个时候,我们调整div的大小和密度。理论上是可以得到一个比较完美的3D圆的。就是渲染起来会特别卡。

突然。我想起来,我电脑上有这么一张图:

现在,我们将这个图作为div的背景,然后调整每个div的background-position

div.style.backgroundPosition = (100 * i / len) + '% -' + (deg + 90) / 180 * 100 + '%'

当然,div颗粒越小,渲染出来的越平滑,越圆润但是也越卡。

手机上无法渲染了,要看的话下载源码使用chrome查看吧。

代码仓库地址:

演示地址:

(PC查看)

标签: #css3地球