1.项目介绍

JS+HTML实现绕地球飞行的3D飞行线动画效果,且3D地球可以随意拖动和滑动缩放,画面中心是蓝色地球,地球表面上的两点连线之间有光电随机出现沿着抛物线轨迹3D飞行,可使用较好的浏览器打开,如microsoft edge打开,效果如下图所示:

2.html源码如下所示

<!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>Threejs 实现环绕地球飞行的3D飞行线</title>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="js/three.103.min.js"></script>
<script src="js/OrbitControls.js"></script> <script id="vertex-shader" type="x-shader/x-vertex">
varying vec3 vPosition;
varying vec4 vColor;
void main() {
vPosition = position;
vColor = vec4(color, 1.0);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script> <script id="fragment-shader" type="x-shader/x-fragment">
uniform vec3 targetPos; // 目标位置
uniform float vLength; // 距离 uniform float time;
varying vec3 vPosition;
varying vec4 vColor;
void main() {
float dist = distance(vPosition, targetPos); vec4 color = vec4(vColor);
float p = dist/vLength * 6.0 + time * 1.0; if (p < 3.1415926/2.0){
p = 0.0;
}
if (p > 3.1415926*2.0){
p = 0.0;
} float a = sin(p);
color.a = a; gl_FragColor = color;
}
</script>
<script>
var container = document.getElementById('container');
var scene, camera, renderer;
var globeMesh = undefined;
var groupDots, groupLines, groupAnimDots;
var animateDots = []; // 小球运动点轨迹
var controls; // 配置参数
var params = {
pointsLength: 20, // 点数
globeRadius: 100 // 地球半径
}
var vertexShader = document.getElementById('vertex-shader').innerHTML;
var fragmentShader = document.getElementById('fragment-shader').innerHTML; const PI2 = Math.PI * 2; // 弧度的取值为0-2π
var timer = -PI2; // 预制件
var Prefab = {
Sphere: (function() {
var instance;
return function(clone = true) {
if (!instance) {
instance = new createSphere();
}
if (clone) return instance.clone();
else return instance;
}
})()
} init();
update(); function init() {
// 场景
scene = new THREE.Scene();
groupDots = new THREE.Group();
groupLines = new THREE.Group();
groupAnimDots = new THREE.Group();
scene.add(groupDots, groupLines, groupAnimDots); // 相机
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.x = -200;
camera.position.y = 200;
camera.position.z = -200;
camera.lookAt(scene.position); // 渲染器
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement); // 光
var light = new THREE.HemisphereLight(0xffffff, 0xffffff, 1);
scene.add(light); // 控制器
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.minDistance = 200;
controls.maxDistance = 400;
controls.rotateSpeed = 0.5;
controls.enableDamping = true;
controls.enablePan = false; initGlobe();
initLines(); window.addEventListener('resize', onWindowResize, false);
} function update() {
requestAnimationFrame(update);
renderer.render(scene, camera); timer += 0.02;
if (timer > Math.PI * 1.5) {
timer = -Math.PI * 1.5;
} groupLines.children.forEach(function(item) {
item.material.uniforms.time.value = timer;
}); // console.log(globeMesh.material.map.offset.x) controls.update();
} function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight);
} function initGlobe() {
// 地球
var geo = new THREE.SphereGeometry(params.globeRadius, 32, 32);
var texture = new THREE.TextureLoader().load('img/earth.jpg');
texture.minFilter = THREE.LinearFilter;
var material = new THREE.MeshPhongMaterial({
map: texture,
// wireframe: true
}); globeMesh = new THREE.Mesh(geo, material);
scene.add(globeMesh);
} // 地球飞线和点
function initLines() {
// 球面随机点
for (let i = 0; i < params.pointsLength; i++) {
addPoints(groupDots, params.globeRadius);
} // 曲线
groupDots.children.forEach(function(elem, index) {
// 从第一个点到其它点
if (elem != groupDots.children[0]) {
var line = addLines(groupDots.children[index - 1].position, elem.position);
animateDots.push(line.curve.getPoints(100));
}
});
} // 3d球面取点
function getEarthPos(radius, a, b) {
var x = radius * Math.sin(a) * Math.cos(b);
var y = radius * Math.sin(a) * Math.sin(b);
var z = radius * Math.cos(a);
return {
x, y, z
};
} // 添加随机点
function addPoints(group, radius) {
var mesh = new Prefab.Sphere();
var pos = getEarthPos(radius, PI2 * Math.random(), PI2 * Math.random());
mesh.position.set(pos.x, pos.y, pos.z);
group.add(mesh);
} function addLines(v0, v3) {
var angle = v0.angleTo(v3); var vtop = v0.clone().add(v3);
vtop = vtop.normalize().multiplyScalar(params.globeRadius); var n; if (angle <= 1) {
n = params.globeRadius / 5 * angle;
} else if (angle > 1 && angle < 2) {
n = params.globeRadius / 5 * Math.pow(angle, 2);
} else {
n = params.globeRadius / 5 * Math.pow(angle, 1.5);
} var v1 = v0.clone().add(vtop).normalize().multiplyScalar(params.globeRadius + n);
var v2 = v3.clone().add(vtop).normalize().multiplyScalar(params.globeRadius + n); // addLineHelper(globeMesh.position, v1);
// addLineHelper(globeMesh.position, v2);
// addLineHelper(globeMesh.position, vtop) // 三维三次贝塞尔曲线(v0起点,v1第一个控制点,v2第二个控制点,v3终点)
var curve = new THREE.CubicBezierCurve3(v0, v1, v2, v3);
var points = curve.getPoints(50);
var vertices = [],
colors = []; points.forEach(function(item, index) {
vertices.push(item.x, item.y, item.z);
colors.push(index / points.length, index / points.length, index / points.length);
});
var geometry = new THREE.BufferGeometry(); geometry.attributes.position = new THREE.Float32BufferAttribute(vertices, 3)
var material = createLineMaterial(v0, v3);
var lineMesh = new THREE.Line(geometry, material);
groupLines.add(lineMesh); return {
curve: curve,
lineMesh: lineMesh
};
} function createLineMaterial(myPos, targetPos) {
var uniforms = {
targetPos: {
value: targetPos
},
vLength: {
value: myPos.distanceTo(targetPos)
},
time: {
value: timer
}
}; var material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true,
vertexColors: THREE.VertexColors
}); return material;
} function createSphere() {
var geometry = new THREE.SphereBufferGeometry(1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ffff
});
var mesh = new THREE.Mesh(geometry, material);
return mesh;
} function addPointHelper(pos) {
var mesh = new Prefab.Sphere();
mesh.material = new THREE.MeshBasicMaterial({
color: 0xff0000
});
mesh.position.copy(pos);
scene.add(mesh);
} function addLineHelper(pos1, pos2) {
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
}); var geometry = new THREE.Geometry();
geometry.vertices.push(pos1, pos2);
var line = new THREE.Line(geometry, material);
scene.add(line);
}
</script>
</body>
</html>

3.JS部分代码由于代码量较大这里就不黏贴了

4.文件目录如下

5.浏览器要支持HTML5与CSS3才有效果。

 整个项目源码下载地址:https://download.csdn.net/download/xipengbozai/16595841

JS实现环绕地球飞行的3D飞行线动画效果(JS+HTML)的更多相关文章

  1. WOW.js – 在页面滚动时展现动感的元素动画效果

    在一些网页上,当你滚动页面的时候会看到各式各样的元素动画效果,非常动感.WOW.js 就是一款帮助你实现这种 CSS 动画效果的插件,很容易定制,你可以改变动画设置喜欢的风格.延迟.长度.偏移和迭代等 ...

  2. 右上角鼠标滑过展开收缩动画效果js代码的演示页面

    http://files.cnblogs.com/files/tanlingdangan/top_right.rar.gz 右上角鼠标滑过展开收缩动画效果js代码的演示页面http://www.51x ...

  3. CSS3动画效果——js调用css动画属性并回调处理详解

    http://www.jb51.net/css/258407.html 这篇文章主要详细介绍了CSS3动画效果回调处理,需要的朋友可以参考下 我们在做js动画的时候,很多时候都需要做回调处理,如在一个 ...

  4. WOW.js——在页面滚动时展现动感的元素动画效果

    插件描述:WOW.js 是一款可以实现滚动页面时触发CSS 动画效果的插件,动态效果可以使网站显示更有动感. 当页面在向下滚动的时候,使用WOW.js可以让页面元素产生细小的动画效果,从而引起浏览者注 ...

  5. WPF实现3D翻转的动画效果

    1.前端代码实现 1.1 原理见代码注析 <Grid MouseDown="Grid_MouseDown"> <Viewport3D> <Viewpo ...

  6. loading加载动画效果js实现

    <style>.box { width: 400px; padding: 20px; border: 40px solid #a0b3d6; background-color: #eee; ...

  7. jquery使用CSS3实现文字动画效果插件Textillate.js

    Textillate是一款基于jquery的使用CSS3实现文字动画的小巧插件.Textillate.js集成了一些很棒的使用CSS3动画效果的 JavaScript 库,您可非常轻轻松地把这些动画效 ...

  8. 如何查看一个网页特定效果的js代码(动画效果可js和css)(页面可以看到js的源代码)

    如何查看一个网页特定效果的js代码(动画效果可js和css)(页面可以看到js的源代码) 一.总结 1.动画效果可能是 CSS 实现的,也可能是 JS 实现的. 2.直接Chrome的F12调试即可, ...

  9. 滚动页面产生动画WOW.js的用法

    简介 在一些网页上,当你滚动页面的时候会看到各式各样的元素动画效果,非常动感.WOW.js 就是一款帮助你实现这种 CSS 动画效果的插件.WOW.js 依赖 animate.css,所以它支持 an ...

随机推荐

  1. DMCA Takedown Policy

    DMCA Takedown Policy https://github.com/xgqfrms/xgqfrms/issues/46 https://help.github.com/en/github/ ...

  2. iframe 父子互传消息,父页面滚动,子页面触发父页面高度

    https://blog.csdn.net/qq_38366657/article/details/81538145 // 父页面的js<iframe id='TopHeader' src=&q ...

  3. DAPHNE PATEL:有主见的人,才能活出精彩人生

    有主见的人,会活出什么样子呢?近日,NGK灵石团队技术副总裁DAPHNE 女士给出了答案. DAPHNE PATEL表示,有主见的人,才能活出精彩的人生.为什么这么说呢? DAPHNE PATEL用自 ...

  4. 未来,Baccarat将如何拓展生态版图?

    Baccarat最近几度冲上DeFi版面的热搜,一是因为BGV价格不断的上涨,二是因为生态建设者的不断涌入.可以说,当下的Baccarat,实在是太火爆了.那么在未来,Baccarat还将会持续火爆吗 ...

  5. Masterboxan INC是你靠近财富的最佳选择

    Masterboxan INC万事达资产管理有限公司(公司编号:20151264097)是一家国际性资产管理公司,主要提供外汇.证券.投资管理和财富管理等金融服务,其在投资方面一直倡导组合型投资构建稳 ...

  6. Markdown简单语法的使用

    Markdown简单语法的使用 目录 Markdown简单语法的使用 前言 标题的设置 字体的设置 1.字体加粗 2.斜体 3.字体加粗斜体 3.删除线 引用 列表的使用 插入图片 分割线 代码的书写 ...

  7. 死磕以太坊源码分析之EVM指令集

    死磕以太坊源码分析之EVM指令集 配合以下代码进行阅读:https://github.com/blockchainGuide/ 写文不易,给个小关注,有什么问题可以指出,便于大家交流学习. 以下指令集 ...

  8. JAVA 批量下载服务器文件到本地指定文件夹并重命名

    /** * @功能 下载文件到指定文件夹并重命名 * @param url 请求的路径 * @param filePath 文件将要保存的目录 * @param filename 保存到本地的文件名 ...

  9. Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)

    五  Vue学习-vue-cli脚手架学习(创建只选一个选项:Babel) 1. 项目目录说明 node_modules : 包管理文件夹 public : 静态资源 src : 源代码 gitign ...

  10. Vue学习笔记-VSCode安装与配置

    一  使用环境: windows 7 64位操作系统 二  VSCode安装与配置  1.下载: https://code.visualstudio.com 直接点击即可. 2. 点击按装程序,默认安 ...