lxc
2 years ago
10 changed files with 809 additions and 31 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,616 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<title></title> |
|||
<meta charset="utf-8"> |
|||
<meta name="generator" content="Three.js Editor"> |
|||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|||
<style> |
|||
body { |
|||
font-family: sans-serif; |
|||
font-size: 11px; |
|||
background-color: #000; |
|||
margin: 0px; |
|||
} |
|||
|
|||
canvas { |
|||
display: block; |
|||
} |
|||
|
|||
.info { |
|||
position: absolute; |
|||
top: 10px; |
|||
width: 100%; |
|||
text-align: center; |
|||
z-index: 100; |
|||
display: block; |
|||
color: brown; |
|||
font-size: 40px; |
|||
} |
|||
|
|||
.label { |
|||
color: #ff000f; |
|||
font-family: sans-serif; |
|||
padding: 40px; |
|||
background: rgba(149, 140, 140, 0.6); |
|||
} |
|||
|
|||
.btn { |
|||
color: #ff000f; |
|||
font-family: sans-serif; |
|||
padding: 20px; |
|||
background: rgba(149, 140, 140, 0.6); |
|||
} |
|||
|
|||
.label1 { |
|||
color: #ffffff; |
|||
font-family: sans-serif; |
|||
padding: 2px; |
|||
background: rgba(0, 0, 0, .6); |
|||
} |
|||
|
|||
.container { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
</style> |
|||
<script type="importmap"> |
|||
{ |
|||
"imports": { |
|||
"three": "./libs/three/three.module.js", |
|||
"jsm/": "./libs/three/jsm/" |
|||
} |
|||
} |
|||
</script> |
|||
<script async src="./libs/layui/layui.js"></script> |
|||
<script async src="./libs/mqtt/mqtt.min.js"></script> |
|||
</head> |
|||
|
|||
<body ontouchstart=""> |
|||
<div class="info">2D数据表格显示 不旋转 厌氧系统 <button onclick="btnclick()">全开</button></div> |
|||
|
|||
|
|||
<script type="module"> |
|||
|
|||
import * as THREE from 'three'; |
|||
import { APP } from './js/app.js'; |
|||
|
|||
|
|||
import { OrbitControls } from 'jsm/controls/OrbitControls.js'; |
|||
import { GLTFLoader } from 'jsm/loaders/GLTFLoader.js'; |
|||
|
|||
import { CSS3DRenderer, CSS3DObject } from 'jsm/renderers/CSS3DRenderer.js'; |
|||
import { Water } from 'jsm/objects/Water.js'; |
|||
import modellabel from './js/units/modellabel.js' |
|||
import css2dlabel from './js/units/css3dlabel.js' |
|||
|
|||
import config from './js/config.js' |
|||
|
|||
|
|||
window.THREE = THREE; // Used by APP Scripts. |
|||
var mqttclient = null; |
|||
|
|||
|
|||
var player = new APP.Player(); |
|||
//水泵列表 |
|||
var PUMP_MODEL_ARR = [] |
|||
var bigLabelArr = [] |
|||
|
|||
|
|||
//红色标签 |
|||
// const labArr = [{ name: "水泵M_1", text: "水泵1" }, { name: "水泵M_2", text: "水泵002" } |
|||
// , { name: "水泵M_3", text: "水泵003" }, { name: "水泵M_4", text: "水泵4" }, { name: "水泵M_5", text: "水泵5" } |
|||
// , { name: "OilTank001", text: "PT桶1" }, { name: "OilTank002", text: "PT桶2" }, { name: "OilTank003", text: "PT桶3" }, |
|||
|
|||
// ] |
|||
const labArr = [{ name: "水泵M_1", text: "水泵M_1", position: { x: 2.86, y: -0.34, z: -3.13 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_2", text: "水泵M_2", position: { x: 1.22, y: -0.59, z: -3.34 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_3", text: "水泵M_3", position: { x: -0.60, y: -0.31, z: -3.26 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_4", text: "水泵M_4", position: { x: -1.66, y: -0.62, z: -3.26 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "水泵M_5", text: "水泵M_51", position: { x: -2.55, y: -0.3, z: -3.36 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "OilTank001", text: "罐1", position: { x: 0.61, y: 2.44, z: 3.78 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "OilTank002", text: "罐2", position: { x: -0.57, y: 2.47, z: 3.78 }, rotation: { x: 0, y: Math.PI, z: 0 } }, |
|||
{ name: "OilTank003", text: "罐3", position: { x: 0.07, y: 2.58, z: 5.39 }, rotation: { x: 0, y: Math.PI, z: 0 } } |
|||
] |
|||
//模型标签 |
|||
const remarkLabArr = [{ name: "221", text: "USAB进水", x: 2.0501311208405713, y: -0.7778027560129786, z: -5.4, ry: 360 } |
|||
, { name: "211", text: "USAB进水", x: 0.1740166304621844, y: -0.7760432883855322, z: -5.4, ry: 360 }, |
|||
{ name: "491", text: "至污泥浓缩池", x: -2.105188770141037, y: -0.7901334936138524, z: -5.4, ry: 360 }] |
|||
//大标签 |
|||
const bigLabArr = [{ name: "建筑_11", text: "建筑_1", x: 0.10, y: 0.16, z: -1.48, rx: 0, ry: 360, rz: 0 }] |
|||
init(); |
|||
function init() { |
|||
|
|||
player.play(); |
|||
player.setSize(window.innerWidth, window.innerHeight); |
|||
window.addEventListener('resize', function () { |
|||
|
|||
player.setSize(window.innerWidth, window.innerHeight); |
|||
|
|||
}); |
|||
//设置背景颜色 |
|||
player.setClearColor(0x34495E); |
|||
|
|||
initModel() |
|||
|
|||
addRemarkLabels(); |
|||
mqttInit(); |
|||
updateLabel(); |
|||
addLEDScreen(); |
|||
// for (var i = 0; i < 1; i++) { |
|||
// player.create3dPage( |
|||
// 1020, 680, |
|||
// new THREE.Vector3(-2 - i, 2 + i / 3, -4.2 + i), |
|||
// new THREE.Vector3(0, Math.PI, 0), |
|||
// 'https://zuoben.blog.csdn.net/'); |
|||
// } |
|||
} |
|||
|
|||
// document.body.appendChild(player.dom); |
|||
function initModel() { |
|||
var loader = new THREE.FileLoader(); |
|||
loader.load('uasb3.json', function (text) { |
|||
|
|||
let json = JSON.parse(text); |
|||
let objloader = new THREE.ObjectLoader(); |
|||
let scene = objloader.parse(json.scene) |
|||
|
|||
player.addModels(scene);//.children[3]); |
|||
|
|||
setModel(scene, player); |
|||
// AddWaters(player); |
|||
// addRemarkLabels(); |
|||
|
|||
}); |
|||
} |
|||
|
|||
function initModel1() { |
|||
var loader = new GLTFLoader(); |
|||
loader.load('assets/models/uasb2.glb', function (gltf) { |
|||
// gltf.scene.traverse(function (child) { |
|||
// switch (child.name) { |
|||
// case 'walls': |
|||
// initWalls(child) |
|||
// break |
|||
// case 'stairs': |
|||
// initStairs(child) |
|||
// break |
|||
// } |
|||
|
|||
// //设置展画边框贴图 |
|||
// if (child.name.includes('paint')) { |
|||
// initFrames(child) |
|||
// } |
|||
// //设置展画图片贴图 |
|||
// if (child.name.includes('draw')) { |
|||
// initDraws(child) |
|||
// } |
|||
// }) |
|||
|
|||
let tmpmodel = gltf.scene//.children[1]; |
|||
|
|||
tmpmodel.rotation.set(0, 2, -0.2) |
|||
|
|||
player.addModels(tmpmodel); |
|||
setModel(tmpmodel, player); |
|||
|
|||
}); |
|||
} |
|||
var x = 0; |
|||
// 设置标签 |
|||
function setModel(scene, player) { |
|||
|
|||
|
|||
scene.castShadow = true; // 开启阴影 |
|||
scene.receiveShadow = true; // 接受阴影 |
|||
|
|||
scene.children.forEach((item, index) => { |
|||
console.log("x=", x, "--------item ==", index, "name=", item.name, "type=", item.type); |
|||
if (item.name.indexOf('OilTank00') > -1) { |
|||
addLabel(item, 0, 0.4, 0) |
|||
} |
|||
else if (item.name.indexOf('水泵M_') > -1) { // 水泵 |
|||
x = x + 1; |
|||
PUMP_MODEL_ARR.push(item); |
|||
//debugger |
|||
if (item.name === '水泵001') { |
|||
item.material.color.set(0x00f); |
|||
} else { |
|||
item.material.color.set(0x006600); |
|||
|
|||
} |
|||
addStateLabel(item, x / 2, 2 + x / 2, x / 2) |
|||
} |
|||
|
|||
if (item.type === 'Object3D' || item.type === 'Group') { // 有下一级 |
|||
|
|||
setModel(item, player); |
|||
} |
|||
|
|||
|
|||
|
|||
}) |
|||
console.log('pumpModelArr=', PUMP_MODEL_ARR) |
|||
} |
|||
|
|||
// 设置标签 |
|||
function setModel1(scene, player) { |
|||
|
|||
|
|||
// scene.castShadow = true; // 开启阴影 |
|||
// scene.receiveShadow = true; // 接受阴影 |
|||
|
|||
scene.children.forEach((item, index) => { |
|||
|
|||
|
|||
console.log("--------item ==", index, "name=", item.name, "type=", item.type); |
|||
|
|||
if (item.name.indexOf('OilTank00') > -1) { |
|||
addLabel(item, 0, 0.4, 0) |
|||
} |
|||
else if (item.name == "水泵001") { |
|||
item.material.color.set(0xff0); |
|||
} |
|||
else if (item.name == "水泵_2") { |
|||
item.material.color.set(0xff0000); |
|||
} |
|||
else if (item.name.indexOf('水泵M_') > -1 && item.type == "Mesh") { // 水泵 |
|||
pumpModelArr.push(item); |
|||
|
|||
|
|||
// } |
|||
if (item.name === '水泵M_1') { |
|||
item.material.color.set(0xff0000); |
|||
|
|||
} else { |
|||
item.material.color.set(0x006600); |
|||
} |
|||
|
|||
addStateLabel(item, 0, 3, 0) |
|||
} |
|||
|
|||
if (item.type === 'Object3D' || item.type === 'Group') { // 有下一级 |
|||
|
|||
setModel(item, player); |
|||
} |
|||
|
|||
|
|||
}) |
|||
console.log('pumpModelArr=', pumpModelArr) |
|||
} |
|||
|
|||
//添加这个就可以用鼠标拖动 |
|||
|
|||
var raycaster = new THREE.Raycaster() |
|||
var mouse = new THREE.Vector2() |
|||
//点击模型 |
|||
// window.addEventListener('click', onMouseClick); |
|||
window.addEventListener('dblclick', onDBMouseClick); |
|||
function onMouseClick(event) { |
|||
|
|||
//将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标 |
|||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1 |
|||
mouse.y = -((event.clientY / window.innerHeight) * 2 - 1) |
|||
//console.log("mouse:"+mouse.x+","+mouse.y) |
|||
|
|||
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster |
|||
raycaster.setFromCamera(mouse, window.camera); |
|||
|
|||
// 获取raycaster直线和所有模型相交的数组集合 |
|||
var intersects = raycaster.intersectObjects(scene.children, true); |
|||
console.log(intersects); |
|||
//debugger |
|||
//将所有的相交的模型的颜色设置为红色 |
|||
for (var i = 0; i < intersects.length; i++) { |
|||
let obj = intersects[i]; |
|||
if (obj.object) { |
|||
|
|||
if (obj.object.name == "视频监控1") { |
|||
|
|||
obj.object.material.color.set(0xff6666); |
|||
alert("视频"); |
|||
} else { |
|||
obj.object.material.color.set(0xff0000); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
function onDBMouseClick(event) { |
|||
|
|||
//将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标 |
|||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1 |
|||
mouse.y = -((event.clientY / window.innerHeight) * 2 - 1) |
|||
//console.log("mouse:"+mouse.x+","+mouse.y) |
|||
|
|||
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster |
|||
raycaster.setFromCamera(mouse, window.camera); |
|||
|
|||
// 获取raycaster直线和所有模型相交的数组集合 |
|||
// debugger |
|||
var intersects = raycaster.intersectObjects(scene.children, true); |
|||
console.log("onclick ", intersects); |
|||
|
|||
//debugger |
|||
//将所有的相交的模型的颜色设置为红色 |
|||
for (var i = 0; i < intersects.length; i++) { |
|||
let obj = intersects[i]; |
|||
if (obj.object) { |
|||
let tmpobj = obj.object; |
|||
console.log(tmpobj) |
|||
//输出 增加标签 位置 |
|||
console.log('{name:"' + tmpobj.name + '",text:"' + tmpobj.name + '",position:{x:' + obj.point.x.toFixed(2) + ',y:' + obj.point.y.toFixed(2) + ',z:' + obj.point.z.toFixed(2) + '},rotation:{x:0,y: Math.PI,z:0}}'); |
|||
// console.log('{name:"' + tmpobj.name + '1",text:"' + tmpobj.name + '",x:' + obj.point.x.toFixed(2) + ',y:' + obj.point.y.toFixed(2) + ',z:' + obj.point.z.toFixed(2) + ',rx:0,ry:0,rz:0}'); |
|||
if (tmpobj.name.indexOf('水泵') > -1) { // 水泵 |
|||
|
|||
openDialog(tmpobj) |
|||
//alert(tmpobj.name, "双击"); |
|||
} |
|||
break; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
//添加 模型标签 |
|||
function addRemarkLabels() { |
|||
remarkLabArr.forEach((item, index) => { |
|||
|
|||
let labelMesh = modellabel.createRemarkLabel(item.text, item.x, item.y, item.z); |
|||
labelMesh.scale.set(0.005, 0.005, 0.005); |
|||
labelMesh.rotation.y = Math.PI * (item.ry / 360); |
|||
labelMesh.rotation.x = Math.PI * (30 / 360);; |
|||
// labelMesh.rotation.x= rz; |
|||
window.scene.add(labelMesh); |
|||
|
|||
}) |
|||
bigLabArr.forEach((item, index) => { |
|||
|
|||
let labelMesh = modellabel.createRemarkLabel(item.text, item.x, item.y, item.z); |
|||
labelMesh.scale.set(0.01, 0.01, 0.01); |
|||
labelMesh.rotation.y = Math.PI * (item.ry / 360); |
|||
// labelMesh.rotation.x = Math.PI * (30 / 360);; |
|||
// labelMesh.rotation.x= rz; |
|||
window.scene.add(labelMesh); |
|||
bigLabelArr.push(labelMesh); |
|||
|
|||
}) |
|||
} |
|||
|
|||
|
|||
|
|||
//通过 模型名称获取标签名称 |
|||
async function getlabel(name) { |
|||
let result; |
|||
labArr.forEach((item, index) => { |
|||
if (item.name === name) { |
|||
result = item; |
|||
return null; |
|||
} |
|||
}) |
|||
return result |
|||
} |
|||
//普通标签 |
|||
async function addLabel(parent, x = 0, y = 0, z = 0, className = 'label') { |
|||
|
|||
if (!parent.name) { |
|||
|
|||
return; |
|||
} |
|||
console.log("parent.name2=", parent.name) |
|||
let item = await getlabel(parent.name); |
|||
// debugger |
|||
if (item) { |
|||
|
|||
player.create3dLabel(parent, item.text, |
|||
1020, 680, |
|||
item.position, |
|||
item.rotation, |
|||
); |
|||
// player.create3dLabel(parent, item.text, |
|||
// 1020, 680, |
|||
// new THREE.Vector3(x, y, z), |
|||
// new THREE.Vector3(0, Math.PI, 0), |
|||
// ); |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
//状态标签 |
|||
async function addStateLabel(parent, x = 0, y = 0, z = 0, className = 'label') { |
|||
|
|||
if (!parent.name) { |
|||
|
|||
return; |
|||
} |
|||
console.log("parent.name2=", parent.name) |
|||
let item = await getlabel(parent.name); |
|||
if (item) { |
|||
|
|||
|
|||
player.create3dLabel(parent, item.text, |
|||
1020, 680, |
|||
item.position, |
|||
item.rotation, |
|||
); |
|||
// player.create3dButton(parent, item.text, |
|||
// 1020, 680, |
|||
// new THREE.Vector3(x, y, z), |
|||
// new THREE.Vector3(0, Math.PI, 0), |
|||
// updateLabel() |
|||
// ); |
|||
} |
|||
|
|||
} |
|||
//添加动态水 |
|||
function AddWaters(player) { |
|||
let water1 = {} |
|||
water1.position = { x: 0, y: 1, z: 0 } |
|||
water1.scale = { x: 4, y: 2.6 } |
|||
AddWater(water1, player) |
|||
let water2 = {} |
|||
water2.position = { x: 0, y: 1, z: 5 } |
|||
water2.scale = { x: 7.5, y: 8 } |
|||
AddWater(water2, player) |
|||
} |
|||
function AddWater(water, player) { |
|||
|
|||
const waterGeometry = new THREE.PlaneGeometry(water.scale.x, water.scale.y); |
|||
|
|||
let waterobj = new Water( |
|||
waterGeometry, |
|||
{ |
|||
textureWidth: 255, |
|||
textureHeight: 255, |
|||
waterNormals: new THREE.TextureLoader().load('./assets/textures/waternormals.jpg', function (texture) { |
|||
|
|||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; |
|||
|
|||
}), |
|||
sunDirection: new THREE.Vector3(), |
|||
sunColor: 0xffffff, |
|||
waterColor: 0x3498DB, |
|||
distortionScale: 0.5,//波浪大小 |
|||
fog: true// scene.fog !== undefined |
|||
} |
|||
); |
|||
waterobj.position.set(water.position.x, water.position.y, water.position.z) |
|||
waterobj.rotation.x = - Math.PI / 2; |
|||
|
|||
scene.add(waterobj); |
|||
player.addWater(waterobj); |
|||
|
|||
} |
|||
//测试用 |
|||
let clickindex = false; |
|||
//全开全关 测试 |
|||
window.btnclick = function () { |
|||
|
|||
pumpModelArr.forEach((item, index) => { |
|||
if (clickindex) { |
|||
item.material.color.set(0x00ff00); |
|||
|
|||
} else { |
|||
item.material.color.set(0x666666); |
|||
|
|||
} |
|||
clickindex = !clickindex; |
|||
|
|||
}) |
|||
} |
|||
|
|||
function mqttInit() { |
|||
var that = this; |
|||
// 连接选项 |
|||
// |
|||
const options = { |
|||
connectTimeout: 4000, // 超时时间 |
|||
// 认证信息 |
|||
clientId: 'brower_' + parseInt(Math.random() / 31.1 * 10000000000), |
|||
username: config.mqttUserName, |
|||
password: config.mqttPassword, |
|||
} |
|||
mqttclient = mqtt.connect('ws://127.0.0.1:8083/mqtt', options); |
|||
mqttclient.on('reconnect', function (error) { |
|||
console.log("reconnect"); |
|||
}) |
|||
mqttclient.on('error', function (error) { |
|||
console.log('连接失败:', error) |
|||
}) |
|||
mqttclient.on('message', function (topic, message, s) { |
|||
console.log(topic, message.toString()); |
|||
if (message.toString() == '1') { |
|||
// if (that.lastTime + 2 * 1000 < new Date().getTime()) { |
|||
// that.lastTime = new Date().getTime(); |
|||
|
|||
// } |
|||
} |
|||
}) |
|||
mqttclient.subscribe("/scene/update/*", (err) => { |
|||
if (!err) { |
|||
console.log(`订阅/scene/update/* 成功`); |
|||
} |
|||
}); |
|||
mqttclient.subscribe("RTData", (err) => { |
|||
if (!err) { |
|||
console.log(`订阅 RTData 成功`); |
|||
} |
|||
}); |
|||
mqttclient.publish('/sys/update/scene', 'scene'); |
|||
} |
|||
//打开对话框 |
|||
function openDialog(tmpobj) { |
|||
layer.open({ |
|||
type: 1 |
|||
, offset: 1 //具体配置参考:http://doc/modules/layer.html#offset |
|||
, id: 'layerDemo' + 1 //防止重复弹出 |
|||
, content: '<div style="padding: 20px 100px;">' + tmpobj.name + '</div>' |
|||
, btn: '关闭' |
|||
, btnAlign: 'c' //按钮居中 |
|||
, shade: 0 //不显示遮罩 |
|||
, yes: function () { |
|||
layer.closeAll(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function updateLabel() { |
|||
|
|||
setTimeout(updateLabel, 1000); //5秒后执行 |
|||
let date = new Date(); |
|||
let m = date.getSeconds(); |
|||
player.updateLabel("", m); |
|||
|
|||
} |
|||
|
|||
var canvasTexture |
|||
// 创建LED电子屏幕 |
|||
function addLEDScreen() { |
|||
var canvas = document.createElement("canvas"); |
|||
canvas.width = 512; |
|||
canvas.height = 64; |
|||
var c = canvas.getContext('2d'); |
|||
// c.fillStyle = "#aaaaff"; |
|||
c.fillStyle = "#000000"; |
|||
c.fillRect(0, 0, 512, 64); |
|||
// 文字 |
|||
c.beginPath(); |
|||
c.translate(256, 32); |
|||
c.fillStyle = "#FF0000"; //文本填充颜色 |
|||
c.font = "bold 28px 宋体"; //字体样式设置 |
|||
c.textBaseline = "middle"; //文本与fillText定义的纵坐标 |
|||
c.textAlign = "center"; //文本居中(以fillText定义的横坐标) |
|||
c.fillText("欢迎领导访问指导!!!", 0, 0); |
|||
|
|||
var cubeGeometry = new THREE.BoxGeometry(512, 64, 5); |
|||
canvasTexture = new THREE.CanvasTexture(canvas); |
|||
canvasTexture.wrapS = THREE.RepeatWrapping; |
|||
var material = new THREE.MeshPhongMaterial({ |
|||
map: canvasTexture, // 设置纹理贴图 |
|||
}); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.set(0.10, 0.56, -1.48); |
|||
cube.rotation.y += Math.PI; //-逆时针旋转,+顺时针 |
|||
cube.scale.set(0.006,0.006,0.01); |
|||
scene.add(cube); |
|||
player.addRefeshFunction(updatetext); |
|||
} |
|||
function updatetext() { |
|||
if (canvasTexture) { |
|||
canvasTexture.offset.x += 0.003; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
|
|||
|
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,145 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head> |
|||
<title>Threejs引入字体,实现3D文字,Canvas画布作为纹理贴图实现滚动字幕</title> |
|||
<meta charset="UTF-8"> |
|||
<script type="text/javascript" src="lib/statistics.js"></script> |
|||
<script type="text/javascript" src="lib/steak.js"></script> |
|||
<script type="text/javascript" src="lib/three.js"></script> |
|||
<script type="text/javascript" src="lib/OrbitControls.js"></script> |
|||
<script type="text/javascript" src="lib/ColladaLoader.js"></script> |
|||
<script type="text/javascript" src="lib/dat.gui.js"></script> |
|||
<script type="text/javascript" charset="UTF-8" src="lib/Tween.min.js"></script> |
|||
<style> |
|||
body { |
|||
margin: 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
</style> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="dom"></div> |
|||
<script type="text/javascript"> |
|||
var camera; |
|||
var renderer; |
|||
var fontMesh; |
|||
var canvasTexture; |
|||
|
|||
function init() { |
|||
// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。 |
|||
var scene = new THREE.Scene(); |
|||
scene.opacity = 0; |
|||
|
|||
// 创建一个摄像机,它定义了我们正在看的地方 |
|||
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000); |
|||
// 将摄像机对准场景的中心 |
|||
camera.position.z = 500; |
|||
camera.lookAt(scene.position); |
|||
var orbit = new THREE.OrbitControls(camera); |
|||
|
|||
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景 |
|||
renderer = new THREE.WebGLRenderer({ |
|||
antialias: true, |
|||
logarithmicDepthBuffer: true, |
|||
}); |
|||
renderer.setClearColor(new THREE.Color("#0e0934")); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
|
|||
var ambientLight = new THREE.AmbientLight("#ffffff", 1); |
|||
scene.add(ambientLight); |
|||
|
|||
// 将呈现器的输出添加到HTML元素 |
|||
document.getElementById("dom").appendChild(renderer.domElement); |
|||
|
|||
// 启动动画 |
|||
renderScene(); |
|||
add3DFont(); |
|||
addLEDScreen(); |
|||
|
|||
function add3DFont() { |
|||
new THREE.FontLoader().load('font/FZYaoTi_Regular.json', function(font) { |
|||
//加入立体文字 |
|||
var text = new THREE.TextGeometry("左本的博客,Three.js3D文字", { |
|||
// 设定文字字体 |
|||
font: font, |
|||
//尺寸 |
|||
size: 24, |
|||
//厚度 |
|||
height: 5 |
|||
}); |
|||
text.computeBoundingBox(); |
|||
// 设置偏移 |
|||
text.translate(-220, 0, 0); |
|||
//3D文字材质 |
|||
var m = new THREE.MeshStandardMaterial({ |
|||
color: "#FF0000" |
|||
}); |
|||
fontMesh = new THREE.Mesh(text, m) |
|||
fontMesh.position.y = 100; |
|||
scene.add(fontMesh); |
|||
}); |
|||
} |
|||
|
|||
// 创建LED电子屏幕 |
|||
function addLEDScreen() { |
|||
var canvas = document.createElement("canvas"); |
|||
canvas.width = 512; |
|||
canvas.height = 64; |
|||
var c = canvas.getContext('2d'); |
|||
c.fillStyle = "#aaaaff"; |
|||
c.fillRect(0, 0, 512, 64); |
|||
// 文字 |
|||
c.beginPath(); |
|||
c.translate(256, 32); |
|||
c.fillStyle = "#FF0000"; //文本填充颜色 |
|||
c.font = "bold 28px 宋体"; //字体样式设置 |
|||
c.textBaseline = "middle"; //文本与fillText定义的纵坐标 |
|||
c.textAlign = "center"; //文本居中(以fillText定义的横坐标) |
|||
c.fillText("左本的博客,Three.js3D文字", 0, 0); |
|||
|
|||
var cubeGeometry = new THREE.BoxGeometry(512, 64, 5); |
|||
canvasTexture = new THREE.CanvasTexture(canvas); |
|||
canvasTexture.wrapS = THREE.RepeatWrapping; |
|||
var material = new THREE.MeshPhongMaterial({ |
|||
map: canvasTexture, // 设置纹理贴图 |
|||
}); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.rotation.y += Math.PI; //-逆时针旋转,+顺时针 |
|||
scene.add(cube); |
|||
} |
|||
|
|||
var clock = new THREE.Clock(); //声明一个时钟对象 |
|||
function renderScene() { |
|||
orbit.update(); |
|||
|
|||
if (fontMesh) { |
|||
fontMesh.rotation.y -= 0.004; |
|||
} |
|||
if (canvasTexture) { |
|||
canvasTexture.offset.x += 0.005; |
|||
} |
|||
// 使用requestAnimationFrame函数进行渲染 |
|||
requestAnimationFrame(renderScene); |
|||
renderer.render(scene, camera); |
|||
} |
|||
|
|||
// 渲染的场景 |
|||
renderer.render(scene, camera); |
|||
} |
|||
window.onload = init; |
|||
|
|||
// 随着窗体的变化修改场景 |
|||
function onResize() { |
|||
camera.aspect = window.innerWidth / window.innerHeight; |
|||
camera.updateProjectionMatrix(); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
} |
|||
// 监听窗体调整大小事件 |
|||
window.addEventListener('resize', onResize, false); |
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
Loading…
Reference in new issue