fullstack.web/swa/html/vr.html
2022-12-22 14:57:51 +08:00

520 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="full-screen" content="yes">
<meta name="browsermode" content="application">
<meta name="x5-orientation" content="portrait">
<meta name="x5-fullscreen" content="true">
<meta name="x5-page-mode" content="app">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="应用标题">
<meta content="telephone=no" name="format-detection" />
<meta content="email=no" name="format-detection" />
<title>VR 亿企云平台</title>
</head>
<body onload="draw();">
<div style="position: fixed;">
<div id="moAccel"></div>
<div id="moCalcTiltLR"></div>
<div id="moCalcTiltFB"></div>
<div id="imgLogo">-----------------</div>
<div id="arrow"></div>
<div id="acceleration"></div>
</div>
<script type="application/javascript">
(function () {
var arrow = document.getElementById("arrow");
try {
var text = "";
window.addEventListener("deviceorientation", orientationHandler, false);
function orientationHandler(event) {
text = ""
text += "左右旋转rotate alpha{" + Math.round(event.alpha) + "deg)<br>";
text += "前后旋转rotate beta{" + Math.round(event.beta) + "deg)<br>";
text += "扭转设备rotate gamma{" + Math.round(event.gamma) + "deg)<br>";
arrow.innerHTML = text;
}
}
catch (e) {
arrow.innerHTML = e.message
}
})()
</script>
<script type="application/javascript">
var vx = vy = vz = 0; //用以获取xyz轴当前的数据
var sx = sy = sz = 0;
var startTime = new Date().getTime(); // 最初的开始时间,单位:毫秒
function deviceMotionHandler2(eventData) {
// 捕捉重力加速度
var acceleration = eventData.accelerationIncludingGravity;
// 打印加速数据
var rawAcceleration = "[" + Math.round(acceleration.x) + ", " +Math.round(acceleration.y) + ", " + Math.round(acceleration.z) + "]";
// Z轴,可知设备朝上或者朝下
var facingUp = -1;
if (acceleration.z > 0) {
facingUp = +1;
}
// 根据重力通过 acceleration.x|y 转换得到加速值,
// 运用重力加速度9.81来计算得到一个百分比然后乘以转换角度90
var tiltLR = Math.round(((acceleration.x) / 9.81) * -90);
var tiltFB = Math.round(((acceleration.y + 9.81) / 9.81) * 90 * facingUp);
// 打印加速度的计算结果
document.getElementById("moAccel").innerHTML = rawAcceleration;
document.getElementById("moCalcTiltLR").innerHTML = tiltLR;
document.getElementById("moCalcTiltFB").innerHTML = tiltFB;
// 将2D和3D的转换应用到图片上
var rotation = "rotate(" + tiltLR + "deg) (1,0,0, " + (tiltFB) + "deg)";
document.getElementById("imgLogo").innerHTML = rotation;
}
if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', function deviceMotionHandler(eventData){
deviceMotionHandler2(eventData)
// document.getElementById("acceleration").innerText = "dz = " + eventData.acceleration.x.toFixed(2) + " " + eventData.accelerationIncludingGravity.x.toFixed(2)
var currTime = new Date().getTime(); //当前时间
var diffTime = currTime - startTime;//当前时间减最初时间,得到当前时间差
var acceleration = eventData.acceleration; //获得加速器对象
var x = acceleration.x
var y = acceleration.y
var z = acceleration.z
vx += x; //获取x轴当前加速度
vy += y; //获取y轴当前加速度
vz += z; //获取z轴当前加速度
sx += diffTime * vx
sy += diffTime * vy
sz += diffTime * vz
document.getElementById("acceleration").innerText = "\r\n" +
"x = " + x.toFixed(2) + "\n" +
"y = " + y.toFixed(2) + "\n" +
"z = " + z.toFixed(2) + "\n" +
"vx = " + vx.toFixed(2) + "\n" +
"vy = " + vy.toFixed(2) + "\n" +
"vz = " + vz.toFixed(2) + "\n" +
"sx = " + sx.toFixed(2) + "\n" +
"sy = " + sy.toFixed(2) + "\n" +
"sz = " + sz.toFixed(2) + "\n" +
"\n";
}, false);
}
</script>
<script src="./three.js"></script>
<script src="./lib/OrbitControls.js"></script>
<script src="./stats.min.js"></script>
<script src="./lib/dat.gui.min.js"></script>
<script src="./lib/Detector.js"></script>
<script src="./lib/tween.min.js"></script>
<script>
var renderer, camera, scene, gui, light, stats, controls;
//字体的点集
var originParticleField,pointsMaterial,geo_ver,geo_ver2,tween,hearts=[];
//初始点
var baseLens =10000,basePoint=[],baseArea=160;
for(var i=0;i<baseLens;i++){
var x= Number(Math.random()*baseArea)-baseArea/2;
var y= Number(Math.random()*baseArea)-baseArea/2;
var z= Number(Math.random()*baseArea)-baseArea/2;
var obj = {
x:x,
y:y,
z:z
}
basePoint.push(obj);
}
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xeeeeee);
renderer.shadowMap.enabled = true;
//告诉渲染器需要阴影效果
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200);
camera.position.set(0, 20, 80 );
}
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa0a0a0 );
scene.fog = new THREE.Fog( 0xa0a0a0, 5, 250 );
}
//初始化dat.GUI简化试验流程
function initGui() {
// //声明一个保存需求修改的相关数据的对象
// gui = {
// bump:0.03,
// animation:false
// };
// var datGui = new dat.GUI();
// //将设置属性添加到gui当中gui.add(对象,属性,最小值,最大值)
// datGui.add(gui, "bump", -1, 1).onChange(function (e) {
// cube1.material.bumpScale = e;
// });
//
// datGui.add(gui, "animation");
}
function initLight() {
scene.add(new THREE.AmbientLight(0x444444));
light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 600, 240 );
light.castShadow = true;
light.shadow.camera.top = 10;
light.shadow.camera.bottom = -10;
light.shadow.camera.left = -10;
light.shadow.camera.right = 10;
//告诉平行光需要开启阴影投射
light.castShadow = true;
// scene.add(light);
}
function initModel() {
//辅助工具
var helper = new THREE.AxesHelper(50);
scene.add(helper);
// 地板
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 400, 400 ), new THREE.MeshPhongMaterial( { color: 0xffffff, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
//添加地板割线
var grid = new THREE.GridHelper( 400, 50, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
{
var loader = new THREE.FontLoader();
//导入字体设定字体这里的话你们找对自己的字体路径可能和我的不一样的下载的three.js包里面examples/fonts里面有字体
loader.load('./yahei.json', function(font) {
// 文字
var text = "Watting...";
var g = new THREE.TextGeometry(text, {
// 设定文字字体,
font: font,
//尺寸
size: 2,
//厚度
height: 1,
});
//计算边界,暂时不用管
g.computeBoundingBox();
g = new THREE.EdgesGeometry(g); //或WireframeGeometry(几何)
var mat = new THREE.LineBasicMaterial({color : 0xffffff, linewidth : 2});
var wireframe = new THREE.LineSegments( g , mat );
scene.add(wireframe);
})
}
//获取点集
getFontPoints('白狗','geo_ver',-23,0,0);
getFontPoints('云平台','geo_ver2',-35,0,0)
//用点画字
pointsMaterial = new THREE.PointsMaterial({
color:0xffffff,
size:0.5,
transparent:true,//使材质透明
blending:THREE.AdditiveBlending,
depthTest:false,//深度测试关闭,不消去场景的不可见面
map:createLightMateria()//刚刚创建的粒子贴图就在这里用上
});
var originGeo = new THREE.Geometry();
for (var i = 0; i <baseLens; i++){//循环创建Geo
var x = basePoint[i].x;
var y = basePoint[i].y;
var z = basePoint[i].z;
originGeo.vertices.push(new THREE.Vector3(x,y,z));
}
originParticleField = new THREE.Points(originGeo,pointsMaterial);
// originParticleField.position.set(-20,10,0);
scene.add(originParticleField);
}
//获取 文字的点集
function getFontPoints(txt,type,x,y,z){
if(!x){var x=0;}
if(!y){var y=0;}
if(!z){var z=0;}
var move =true;
if(x==0&&y==0&&z==0){move = false;}
var res = [];
var loader = new THREE.FontLoader();
loader.load("./yahei.json",function(font){
// var gem2 = new THREE.TextGeometry(txt, {
// size: 16, //字号大小,一般为大写字母的高度
// height: 0.5, //文字的厚度
// weight: 'bold', //值为'normal'或'bold',表示是否加粗
// font: font, //字体,默认是'helvetiker',需对应引用的字体文件
// style: 'normal', //值为'normal'或'italics',表示是否斜体
// bevelThickness: 0.5, //倒角厚度
// bevelSize: 0.5, //倒角宽度
// curveSegments: 8,//弧线分段数,使得文字的曲线更加光滑
// bevelEnabled: true, //布尔值,是否使用倒角,意为在边缘处斜切
// });
//
// //计算边界
// gem2.computeBoundingBox();
// var gem2 = new THREE.TextGeometry(txt, {
// // 设定文字字体,
// font: font,
// //尺寸
// size: 2,
// //厚度
// height: 1,
// });
var shapes = font.generateShapes( txt, 2 );
var geometry = new THREE.ShapeBufferGeometry( shapes );
geometry.computeBoundingBox();
// 取线框图
// EdgesGeometry
var g = new THREE.WireframeGeometry(geometry);
// console.log("res = g.position", g.position)
res = g.attributes.position.array;
console.log("res", res.length)
//字体一般不是居中的,需要手动调下
if(move){
var lens= res.length;
var attrs = [];
for(var i=0;i<lens;i++){
var obj = {
x:res[i].x+x,
y:res[i].y+y,
z:res[i].z+z,
}
attrs.push(obj);
}
res = attrs;
}
switch(type){
case 'geo_ver':
geo_ver = res;
break;
case 'geo_ver2':
geo_ver2 = res;
break;
}
});
}
function pointMove(position1){
//移除粒子浮动动画
// TWEEN.removeAll();
var pointNow = originParticleField.geometry.vertices;
var lens0 = position1.length;
var pos = {val:1};
var callback=function(){
var val = this.val;
var particles = originParticleField.geometry.vertices;
// return console.log(particles);
for(var i = 0; i < baseLens; i++) {
var pos = particles[i];
if(i<lens0){
pos.x = pointNow[i].x * val + position1[i].x * (1-val);
pos.y = pointNow[i].y * val + position1[i].y * (1-val);
pos.z = pointNow[i].z * val + position1[i].z * (1-val);
}else{
pos.x = pointNow[i].x * val + basePoint[i].x * (1-val);
pos.y = pointNow[i].y * val + basePoint[i].y * (1-val);
pos.z = pointNow[i].z * val + basePoint[i].z * (1-val);
}
}
originParticleField.geometry.verticesNeedUpdate = true;
}
tween = new TWEEN.Tween(pos).to({val: 0}, 2000).easing(TWEEN.Easing.Quadratic.InOut).delay(500).onUpdate(callback);
tween.start();
}
//粒子浮动动画
//绘制粒子贴图,
function createLightMateria() {
var canvasDom = document.createElement('canvas');
canvasDom.width = 16;
canvasDom.height = 16;
var ctx = canvasDom.getContext('2d');
//根据参数确定两个圆的坐标,绘制放射性渐变的方法,一个圆在里面,一个圆在外面
var gradient = ctx.createRadialGradient(
canvasDom.width/2,
canvasDom.height/2,
0,
canvasDom.width/2,
canvasDom.height/2,
canvasDom.width/2);
gradient.addColorStop(0,'rgba(255,255,255,1)');
gradient.addColorStop(0.005,'rgba(139,69,19,1)');
gradient.addColorStop(0.4,'rgba(139,69,19,1)');
gradient.addColorStop(1,'rgba(0,0,0,1)');
//设置颜色为渐变
ctx.fillStyle = gradient;
//绘图
ctx.fillRect(0,0,canvasDom.width,canvasDom.height);
//贴图使用
let texture = new THREE.Texture(canvasDom);
texture.needsUpdate = true;//使用贴图时进行更新
return texture;
}
//初始化性能插件
function initStats() {
stats = new Stats();
document.body.appendChild(stats.domElement);
}
function initControls() {
controls = new THREE.OrbitControls(camera, renderer.domElement);
//设置控制器的中心点
controls.target.set( 0, 5, 0 );
// 如果使用animate方法时将此函数删除
//controls.addEventListener( 'change', render );
// 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
controls.enableZoom = true;
//是否自动旋转
controls.autoRotate = false;
controls.autoRotateSpeed = 0.5;
//设置相机距离原点的最远距离
controls.minDistance = 1;
//设置相机距离原点的最远距离
controls.maxDistance = 2000;
//是否开启右键拖拽
controls.enablePan = true;
}
function render() {
controls.update();
}
//窗口变动触发的函数
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
//更新控制器
render();
//更新性能插件
stats.update();
TWEEN.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
function draw() {
//兼容性判断
if (!Detector.webgl) Detector.addGetWebGLMessage();
initGui();
initRender();
initScene();
initCamera();
initLight();
initModel();
initControls();
initStats();
animate();
window.onresize = onWindowResize;
}
var t = 0
setInterval(function () {
if ( 0 == t ){
pointMove(geo_ver);
t = 1
} else {
t = 0
pointMove(geo_ver2);
}
}, 3000 )
</script>
</body>
</html>