<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>使用CSS3 PerspectiveTransform实现的逼真3D地球自转动画</title>
<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>
<div class="info">
<div class="info-title">使用CSS3 PerspectiveTransform实现的逼真3D自转地球</div>
</div>
<script src='js/dat.gui.min.js'></script>
<script src='js/Stats.js'></script>
<script src='js/css_globe_PerspectiveTransform.js'></script>
<script src='js/TweenMax.min.js'></script>
<script>
var config = {
percent: 0,
lat: 0,
lng: 0,
segX: 14,
segY: 12,
isHaloVisible: true,
isPoleVisible: true,
autoSpin: true,
zoom: 0,
skipPreloaderAnimation: false,
goToBristol: function() {
goTo(51.4500, 2.5833);
}
};
var stats;
var imgs;
var preloader;
var preloadPercent;
var globeDoms;
var vertices;
var world;
var worldBg;
var globe;
var globeContainer;
var globePole;
var globeHalo;
var pixelExpandOffset = 1.5;
var rX = 0;
var rY = 0;
var rZ = 0;
var sinRX;
var sinRY;
var sinRZ;
var cosRX;
var cosRY;
var cosRZ;
var dragX;
var dragY;
var dragLat;
var dragLng;
var isMouseDown = false;
var isTweening = false;
var tick = 1;
var URLS = {
bg: 'img/css_globe_bg.jpg',
diffuse: 'img/css_globe_diffuse.jpg',
halo: 'img/css_globe_halo.png',
};
var transformStyleName = PerspectiveTransform.transformStyleName;
function init(ref) {
world = document.querySelector('.world');
worldBg = document.querySelector('.world-bg');
worldBg.style.backgroundImage = 'url(' + URLS.bg + ')';
globe = document.querySelector('.world-globe');
globeContainer = document.querySelector('.world-globe-doms-container');
globePole = document.querySelector('.world-globe-pole');
globeHalo = document.querySelector('.world-globe-halo');
globeHalo.style.backgroundImage = 'url(' + URLS.halo + ')';
regenerateGlobe();
var gui = new dat.GUI();
gui.add(config, 'lat', -90, 90).listen();
gui.add(config, 'lng', -180, 180).listen();
gui.add(config, 'isHaloVisible');
gui.add(config, 'isPoleVisible');
gui.add(config, 'autoSpin');
gui.add(config, 'goToBristol');
gui.add(config, 'zoom', 0, 1).listen();
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = 0;
stats.domElement.style.top = 0;
document.body.appendChild(stats.domElement);
// events
world.ondragstart = function() {
return false;
};
world.addEventListener('mousedown', onMouseDown);
world.addEventListener('mousemove', onMouseMove);
world.addEventListener('mouseup', onMouseUp);
world.addEventListener('touchstart', touchPass(onMouseDown));
world.addEventListener('touchmove', touchPass(onMouseMove));
world.addEventListener('touchend', touchPass(onMouseUp));
loop();
}
function touchPass(func) {
return function(evt) {
evt.preventDefault();
func.call(this, {
pageX: evt.changedTouches[0].pageX,
pageY: evt.changedTouches[0].pageY
});
};
}
function onMouseDown(evt) {
isMouseDown = true;
dragX = evt.pageX;
dragY = evt.pageY;
dragLat = config.lat;
dragLng = config.lng;
}
function onMouseMove(evt) {
if (isMouseDown) {
var dX = evt.pageX - dragX;
var dY = evt.pageY - dragY;
config.lat = clamp(dragLat + dY * 0.5, -90, 90);
config.lng = clampLng(dragLng - dX * 0.5, -180, 180);
}
}
function onMouseUp(evt) {
if (isMouseDown) {
isMouseDown = false;
}
}
function regenerateGlobe() {
var dom, domStyle;
var x, y;
globeDoms = [];
while (dom = globeContainer.firstChild) {
globeContainer.removeChild(dom);
}
var segX = config.segX;
var segY = config.segY;
var diffuseImgBackgroundStyle = 'url(' + URLS.diffuse + ')';
var segWidth = 1600 / segX | 0;
var segHeight = 800 / segY | 0;
vertices = [];
var verticesRow;
var radius = (536) / 2;
var phiStart = 0;
var phiLength = Math.PI * 2;
var thetaStart = 0;
var thetaLength = Math.PI;
for (y = 0; y <= segY; y++) {
verticesRow = [];
for (x = 0; x <= segX; x++) {
var u = x / segX;
var v = 0.05 + y / segY * (1 - 0.1);
var vertex = {
x: -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength),
y: -radius * Math.cos(thetaStart + v * thetaLength),
z: radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength),
phi: phiStart + u * phiLength,
theta: thetaStart + v * thetaLength
};
verticesRow.push(vertex);
}
vertices.push(verticesRow);
}
for (y = 0; y < segY; ++y) {
for (x = 0; x < segX; ++x) {
dom = document.createElement('div');
domStyle = dom.style;
domStyle.position = 'absolute';
domStyle.width = segWidth + 'px';
domStyle.height = segHeight + 'px';
domStyle.overflow = 'hidden';
domStyle[PerspectiveTransform.transformOriginStyleName] = '0 0';
domStyle.backgroundImage = diffuseImgBackgroundStyle;
dom.perspectiveTransform = new PerspectiveTransform(dom, segWidth, segHeight);
dom.topLeft = vertices[y][x];
dom.topRight = vertices[y][x + 1];
dom.bottomLeft = vertices[y + 1][x];
dom.bottomRight = vertices[y + 1][x + 1];
domStyle.backgroundPosition = (-segWidth * x) + 'px ' + (-segHeight * y) + 'px';
globeContainer.appendChild(dom);
globeDoms.push(dom);
}
}
}
function loop() {
requestAnimationFrame(loop);
stats.begin();
render();
stats.end();
}
function render() {
if (config.auto
HTML5+css3实现超逼真的3D地球自转动画场景特效源码.zip
版权申诉
54 浏览量
2022-11-03
23:41:12
上传
评论
收藏 1.73MB ZIP 举报
易小侠
- 粉丝: 6453
- 资源: 9万+
最新资源
- 论文(最终)_20240430235101.pdf
- 基于python编写的Keras深度学习框架开发,利用卷积神经网络CNN,快速识别图片并进行分类
- 最全空间计量实证方法(空间杜宾模型和检验以及结果解释文档).txt
- 5uonly.apk
- 蓝桥杯Python组的历年真题
- 2023-04-06-项目笔记 - 第一百十九阶段 - 4.4.2.117全局变量的作用域-117 -2024.04.30
- 2023-04-06-项目笔记 - 第一百十九阶段 - 4.4.2.117全局变量的作用域-117 -2024.04.30
- 前端开发技术实验报告:内含4四实验&实验报告
- Highlight Plus v20.0.1
- 林周瑜-论文.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈