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. 如何正确的阅读 js 源码

    如何正确的阅读 js 源码 https://astexplorer.net/ AST Abstract Syntax Trees https://alligator.io/js/traversing- ...

  2. window.locationbar

    window.locationbar demo https://cdn.xgqfrms.xyz/#/operate-tool/select-seat-system/select-detail?temp ...

  3. html5 useful skills blogs

    html5 useful skills blogs preload & prefetch https://www.30secondsofcode.org/snippet/ary blogs h ...

  4. html2Canvas to Images

    <script> $(function () { var content = document.getElementById("shareImages"); conte ...

  5. Flutter: 获取本地json数据

    FutureBuilder( future: DefaultAssetBundle.of(context).loadString('data/data.json'), builder: (contex ...

  6. webpack + ts 配置路径别名无死角方法总结

    webpack + ts 配置路径别名总结 自我体验加总结:在配置脚手架时,定制别名很有必要,可以使得代码更优雅,可读性更强.但在使用ts的时候,即便项目能够运行,vscode 确时长会提示 can' ...

  7. 一文读懂Servlet

    1 Servlet简介 Servlet就是sun公司开发动态web的一门技术 Sun在这些API中提供一个接口叫做:Servlet. 开发一个Servlet程序,只需两步: 编写一个类,实现Servl ...

  8. List转String数组 collection.toArray(new String[0])中new String[0]的语法解释

    Collection的公有方法中,toArray()是比较重要的一个. 但是使用无参数的toArray()有一个缺点,就是转换后的数组类型是Object[]. 虽然Object数组也不是不能用,但当你 ...

  9. docker08容器监控工具-WeaveScope

    容器监控工具WeaveScope 一 背景 在生成环境中k8s应用部署众多,需要一款可视化工具方便日常获知集群的实时状态,并为故障排查提供及时和准确的数据支持. weavescope支持docker和 ...

  10. Markdown(2)基本语法

    ​ Markdown 是一种轻量级标记语言 , 通过简单的标记语法,使文本内容具有一定的格式 . 一.段落 1. 标题 语法格式: 符号 "#" 可以标记 1~6级标题.一级标题对 ...