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. 1月22日第二轮空投来袭,SPC算力福利币究竟能带来什么?

    行情数据显示,比特币于14日23时30分再次突破40000美元,市值回升至7400亿美元.根据行情频道数据,比特币于14日2时展露上行态势,价格于34000美元附近起跳,至12时站上37000美元.此 ...

  2. re模块之简单计算器的实现

    本节大纲: 表达式的输入及检查.格式化 怎么样进行匹配最里面的括号以及操作数的匹配 如何实现表达式的四则运算 完整代码展示 在我们学习re模块之后,通常的练习就是利用所学相关知识来写一个计算器 那么, ...

  3. ASP.NET Core WebApi版本控制

    前言: 在日常项目开发中,随着项目需求不断的累加.不断的迭代:项目服务接口需要向下兼容历史版本:前些时候就因为Api接口为做版本管理导致接口对低版本兼容处理不友好. 最近就像了解下如何实现WebApi ...

  4. MPAndroidChart实现LineChart(折线图)

    一.参照油管视频做法 1.引入依赖 新建Android工程,然后分别在build.gradle(Project:...)添加 maven { url 'https://jitpack.io' } 在b ...

  5. Spring-02 第一个Spring程序

    Spring-02 第一个Spring程序 第一个Spring程序 1.导入依赖 <dependency> <groupId>org.springframework</g ...

  6. 开工大吉:TcaplusDB将持续为您提供可靠的数据服务

    开工大吉 新的一年 新的开始 我们也带着新的心意 向您奔赴而来    在此,TcaplusDB祝广大客户朋友,开工大吉,2021,我们将一如既往地守护您的数据,继续做您最坚实的后盾.    作为专为游 ...

  7. 一文读懂clickhouse集群监控

    更多精彩内容,请关注微信公众号:后端技术小屋 一文读懂clickhouse集群监控 常言道,兵马未至,粮草先行,在clickhouse上生产环境之前,我们就得制定好相关的监控方案,包括metric采集 ...

  8. 全局解决Vue跳转相同路由导致报错的问题

    大家使用Vue做开发的时候应该都遇到过这个问题,就是某个页面下调用this.$router.push(path),而path指向的页面和当前页面是同一页面时,就会发生报错,vue-router会提示你 ...

  9. OpenGL中的简单坐标系初看+VAO/VBO/EBO

    你好,三角形 一: 关于坐标的问题 标准化设备坐标:输入的顶点数据就应该在标准化设备坐标范围里面即:x,y,z的值都在(-1-1)之间.在这个区间之外的坐标都会被丢弃. 1.1一旦顶点数据传入顶点着色 ...

  10. 原生js日历选择器,学习js面向对象开发日历插件

    在web开发过程中经常会碰到需要选择日期的功能,一般的操作都是在文本框点击,然后弹出日历选择框,直接选择日期就可以在文本框显示选择的日期.开发好之后给用户使用是很方便,但如果每一个日历选择器都要临时开 ...