JS实现环绕地球飞行的3D飞行线动画效果(JS+HTML)
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)的更多相关文章
- WOW.js – 在页面滚动时展现动感的元素动画效果
在一些网页上,当你滚动页面的时候会看到各式各样的元素动画效果,非常动感.WOW.js 就是一款帮助你实现这种 CSS 动画效果的插件,很容易定制,你可以改变动画设置喜欢的风格.延迟.长度.偏移和迭代等 ...
- 右上角鼠标滑过展开收缩动画效果js代码的演示页面
http://files.cnblogs.com/files/tanlingdangan/top_right.rar.gz 右上角鼠标滑过展开收缩动画效果js代码的演示页面http://www.51x ...
- CSS3动画效果——js调用css动画属性并回调处理详解
http://www.jb51.net/css/258407.html 这篇文章主要详细介绍了CSS3动画效果回调处理,需要的朋友可以参考下 我们在做js动画的时候,很多时候都需要做回调处理,如在一个 ...
- WOW.js——在页面滚动时展现动感的元素动画效果
插件描述:WOW.js 是一款可以实现滚动页面时触发CSS 动画效果的插件,动态效果可以使网站显示更有动感. 当页面在向下滚动的时候,使用WOW.js可以让页面元素产生细小的动画效果,从而引起浏览者注 ...
- WPF实现3D翻转的动画效果
1.前端代码实现 1.1 原理见代码注析 <Grid MouseDown="Grid_MouseDown"> <Viewport3D> <Viewpo ...
- loading加载动画效果js实现
<style>.box { width: 400px; padding: 20px; border: 40px solid #a0b3d6; background-color: #eee; ...
- jquery使用CSS3实现文字动画效果插件Textillate.js
Textillate是一款基于jquery的使用CSS3实现文字动画的小巧插件.Textillate.js集成了一些很棒的使用CSS3动画效果的 JavaScript 库,您可非常轻轻松地把这些动画效 ...
- 如何查看一个网页特定效果的js代码(动画效果可js和css)(页面可以看到js的源代码)
如何查看一个网页特定效果的js代码(动画效果可js和css)(页面可以看到js的源代码) 一.总结 1.动画效果可能是 CSS 实现的,也可能是 JS 实现的. 2.直接Chrome的F12调试即可, ...
- 滚动页面产生动画WOW.js的用法
简介 在一些网页上,当你滚动页面的时候会看到各式各样的元素动画效果,非常动感.WOW.js 就是一款帮助你实现这种 CSS 动画效果的插件.WOW.js 依赖 animate.css,所以它支持 an ...
随机推荐
- React Hooks +React Context vs Redux
React Hooks +React Context vs Redux https://blog.logrocket.com/use-hooks-and-context-not-react-and-r ...
- taro scroll tabs 滚动标签 切换
taro scroll tabs 滚动标签 切换 https://www.cnblogs.com/lml-lml/p/10954069.html https://developers.weixin.q ...
- VSCode & Node.js & debugger & inspector
VSCode & Node.js & debugger & inspector F5 ws 元信息 (UUID) ws://127.0.0.1:46912/efa91bda-1 ...
- H5 & animation
H5 & animation https://m.tb.cn/h.VYB7BAx?sm=51fda6 UA checker webp image & css animation CDN ...
- Chateau Renice酒庄 :忠于风味,尊重自然
Chateau Renice酒庄(公司编号:20151318780)凭借优良的葡萄栽培传统.卓越的酿酒技术以及独特风味的葡萄酒,近年来葡萄酒畅销至全球. Chateau Renice酒庄将葡萄酒出口至 ...
- DBA 的效率加速器——CloudQuery v1.3.2 上线!
嘿,兄弟,我们好久不见,你在哪里 嘿,朋友,如果真的是你,请打声招呼 我说好久不见,你去哪里 你却对我说,我去江湖 我去看 CloudQuery v1.3.2,看看新增了哪些好用的小功能! 一.自动/ ...
- 通过setMouseTracking实现用鼠标拖动控件
1 import sys 2 from PyQt5.Qt import * 3 4 class Mwindow(QWidget): 5 leftclick = False 6 7 def __init ...
- 死磕Spring之IoC篇 - 开启 Bean 的加载
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- 面试常备,字符串三剑客 String、StringBuffer、StringBuilder
尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...
- ASP.NET Core扩展库
亲爱的.Neter们,在我们日复一日的编码过程中是不是会遇到一些让人烦恼的事情: 日志配置太过复杂,各种模板.参数也搞不清楚,每次都要去查看日志库的文档,还需要复制粘贴一些重复代码,好无赖 当需要类型 ...