PerspectiveTransform实现三维地球自转动画效果代码

代码语言:html

所属分类:三维

代码描述:PerspectiveTransform实现三维地球自转动画效果代码

代码标签: 地球 自转 动画 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开


<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  



  
  <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Oswald:400'>
  
<style>
html, body {
  position: absolute;
  width: 100%;
  height: 100%;
  margin: 0 0;
  overflow: hidden;
  font-family: 'Lato', sans-serif;
  background-color: #000;
  color: #fff;
}

.world {
  position: absolute;
  width: 100%;
  height: 100%;
  cursor: pointer;
  cursor: move;
  cursor: -moz-grab;
  cursor: -webkit-grab;
  cursor: grab;
}

.world-bg {
  position: absolute;
  width: 100%;
  height: 100%;
  background-position: 50% 50%;
  background-size: cover;
}

.world-globe {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
}

.world-globe-pole {
  position: absolute;
  width: 530px;
  height: 530px;
  left: -265px;
  top: -265px;
  border-radius: 50% 50%;
  background-color: #fff;
}

.world-globe-doms-container {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
}

.world-globe-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 730px;
  height: 715px;
  margin-left: -368px;
  margin-top: -350px;
}

.info {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  padding: 10px 10px;
  box-sizing: border-box;
  background-color: rgba(0, 0, 0, 0.8);
  color: #fff;
  font-size: 12px;
}

.info-desc {
  color: #ddd;
  font-size: 10px;
}

a {
  color: #ff5f5f;
}
</style>



</head>

<body >
  <div class="world">
    <div class="world-bg"></div>
    <div class="world-globe">
        <div class="world-globe-pole"></div>
        <div class="world-globe-doms-container"></div>
        <div class="world-globe-halo"></div>
    </div>
</div>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/stats-min.js"></script>
<script>
    (function (define) {
    define(function(){

function PerspectiveTransform(element, width, height, useBackFacing){

    this.element = element;
    this.style = element.style;
    this.computedStyle = window.getComputedStyle(element);
    this.width = width;
    this.height = height;
    this.useBackFacing = !!useBackFacing;

    this.topLeft = {x: 0, y: 0};
    this.topRight = {x: width, y: 0};
    this.bottomLeft = {x: 0, y: height};
    this.bottomRight = {x: width, y: height};
    this.calcStyle = '';
}

PerspectiveTransform.useDPRFix = false;
PerspectiveTransform.dpr = 1;

PerspectiveTransform.prototype = (function(){

    var app = {
        stylePrefix: ''
    };

    var aM = [[0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0]];
    var bM = [0, 0, 0, 0, 0, 0, 0, 0];

    function _setTransformStyleName(){
        var testStyle = document.createElement('div').style;
        app.stylePrefix =
            'webkitTransform' in testStyle ? 'webkit' :
            'MozTransform' in testStyle ? 'Moz' :
            'msTransform' in testStyle ? 'ms' :
            '';
        PerspectiveTransform.transformStyleName = app.stylePrefix + (app.stylePrefix.length>0?'Transform':'transform');
        PerspectiveTransform.transformDomStyleName = '-'+app.stylePrefix.toLowerCase()+'-transform';
        PerspectiveTransform.transformOriginStyleName = app.stylePrefix + (app.stylePrefix.length>0?'TransformOrigin':'transformOrigin');
        PerspectiveTransform.transformOriginDomStyleName = '-'+app.stylePrefix.toLowerCase()+'-transform-origin';
    }


    // Check the distances between each points and if there is some points with the distance lequal to or less than 1 pixel, then return true. Otherwise return false;
    function _hasDistancesError(){
        var lenX = this.topLeft.x - this.topRight.x;
        var lenY = this.topLeft.y - this.topRight.y;
        if(Math.sqrt(lenX * lenX +  lenY * lenY)<=1) return true;
        lenX = this.bottomLeft.x - this.bottomRight.x;
        lenY = this.bottomLeft.y - this.bottomRight.y;
        if(Math.sqrt(lenX * lenX +  lenY * lenY)<=1) return true;
        lenX = this.topLeft.x - this.bottomLeft.x;
        lenY = this.topLeft.y - this.bottomLeft.y;
        if(Math.sqrt(lenX * lenX +  lenY * lenY)<=1) return true;
        lenX = this.topRight.x - this.bottomRight.x;
        lenY = this.topRight.y - this.bottomRight.y;
        if( Math.sqrt(lenX * lenX +  lenY * lenY)<=1) return true;
        lenX = this.topLeft.x - this.bottomRight.x;
        lenY = this.topLeft.y - this.bottomRight.y;
        if( Math.sqrt(lenX * lenX +  lenY * lenY)<=1) return true;
        lenX = this.topRight.x - this.bottomLeft.x;
        lenY = this.topRight.y - this.bottomLeft.y;
        if( Math.sqrt(lenX * lenX +  lenY * lenY)<=1) return true;

        return false;
    }

    // Get the determinant of given 3 points
    function _getDeterminant(p0, p1, p2){
        return p0.x * p1.y + p1.x * p2.y + p2.x * p0.y - p0.y * p1.x - p1.y * p2.x - p2.y * p0.x;
    }

    // Return true if it is a concave polygon or if it is backfacing when the useBackFacing property is false. Otehrwise return true;
    function _hasPolyonError(){
        var det1 = _getDeterminant(this.topLeft, this.topRight, this.bottomRight);
        var det2 = _getDeterminant(this.bottomRight, this.bottomLeft, this.topLeft);
        if(this.useBackFacing){
            if(det1*det2<=0) return true;
        }else{
            if(det1<=0||det2<=0) return true;
        }
        var det1 = _getDeterminant(this.topRight, this.bottomRight, this.bottomLeft);
        var det2 = _getDeterminant(this.bottomLeft, this.topLeft, this.topRight);
        if(this.useBackFacing){
            if(det1*det2<=0) return true;
        }else{
            if(det1<=0||det2<=0) return true;
        }
        return false;
    }

    function checkError(){
        if(_hasDistancesError.apply(this)) return 1; // Points are too close to each other.
        if(_hasPolyonError.apply(this)) return 2; // Concave or backfacing if the useBackFacing property is false
        return 0; // no error
    }

    function calc() {
        var width = this.width;
        var height = this.height;

        //  get the offset from the transfrom origin of the element
        var offsetX = 0;
        var offsetY = 0;
        var offset = this.computedStyle.getPropertyValue(PerspectiveTransform.transformOriginDomStyleName);
        if(offset.indexOf('px')>-1){
            offset = offset.split('px');
            offsetX = -parseFloat(offset[0]);
            offsetY = -parseFloat(offset[1]);
        }else if(offset.indexOf('%')>-1){
            offset = offset.split('%');
            offsetX = -parseFloat(offset[0]) * width / 100;
            offsetY = -parseFloat(offset[1]) * height / 100;
        }

        //  magic here:
        var dst = [this.topLeft, this.topRight, this.bottomLeft, this.bottomRight];
        var arr = [0, 1, 2, 3, 4, 5, 6, 7];
        for(var i = 0; i < 4; i++) {
            aM[i][0] = aM[i+4][3] = i & 1 ? width + offsetX : offsetX;
            aM[i][1] = aM[i+4][4] = (i > 1 ? height + offsetY : offsetY);
            aM[i][6] = (i & 1 ? -offsetX-width : -offsetX) * (dst[i].x + offsetX);
            aM[i][7] = (i > 1 ? -offsetY-height : -offsetY) * (dst[i].x + offsetX);
            aM[i+4][6] = (i & 1 ? -offsetX-width : -offsetX) * (dst[i].y + offsetY);
            aM[i+4][7] = (i > 1 ? -offsetY-height : -offsetY) * (dst[i].y + offsetY);
            bM[i] = (dst[i].x + offsetX);
            bM[i + 4] = (dst[i].y + offsetY);
            aM[i][2] = aM[i+4][5] = 1;
            aM[i][3] = aM[i][4] = aM[i][5] = aM[i+4][0] = aM[i+4][1] = aM[i+4][2] = 0;
        }
        var kmax, sum;
        var row;
        var col = [];
        var i, j, k, tmp;
        for(var j = 0; j < 8; j++) {
            for(var i = 0; i < 8; i++)  col[i] = aM[i][j];
            for(i = 0; i < 8; i++) {
                row = aM[i];
                kmax = i<j?i:j;
                sum = 0.0;
                for(var k = 0; k < kmax; k++) sum += row[k] * col[k];
                row[j] = col[i] -= sum;
            }
            var p = j;
            for(i = j + 1; i < 8; i++) {
                if(Math.abs(col[i]) > Math.abs(col[p])) p = i;
            }
            if(p != j) {
                for(k = 0; k < 8; k++) {
                    tmp = aM[p][k];
                    aM[p][k] = aM[j][k];
                    aM[j][k] = tmp;
                }
                tmp = arr[p];
                arr[p] = arr[j];
                arr[j] = tmp;
            }
            if(aM[j][j] != 0.0) for(i = j + 1; i < 8; i++) aM[i][j] /= aM[j][j];
        }
        for(i = 0; i < 8; i++) arr[i] = bM[arr[i]];
        for(k = 0; k < 8; k++) {
            for(i = k + 1; i < 8; i++) arr[i] -= arr[k] * aM[i][k];
        }
        for(k = 7; k > -1; k--) {
            arr[k] /= aM[k][k];
            for(i = 0; i < k; i++) arr[i] -= arr[k] * aM[i][k];
        }

         return this.calcStyle = 'matrix3d(' + arr[0].toFixed(9) + ',' + arr[3].toFixed(9) + ', 0,' + arr[6].toFixed(9) + ',' + arr[1].toFixed(9) + ',' + arr[4].toFixed(9) + ', 0,' + arr[7].toFixed(9) + ',0, 0, 1, 0,' + arr[2].toFixed(9) + ',' + arr[5].toFixed(9) + ', 0, 1)';

    }

    function update(style) {

        style = style || this.calcStyle;

        if(PerspectiveTransform.useDPRFix) {
            var dpr = PerspectiveTransform.dpr;
            style = 'scale(' + dpr + ',' + dpr + ')perspective(1000px)' + style +.........完整代码请登录后点击上方下载按钮下载查看

网友评论0