threejs使⽤精灵Sprite模型给场景3D模型打标签实例
精灵图Sprite效果是不管场景如何旋转,标签总是对着屏幕,可以⽤作对模型打标记,显⽰模型信息作⽤
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="www.yanhuangxueyuan/3D/example/three.min.js"></script>
<script src="./js/dat.gui.js"></script>
<script src="./js/OrbitControls.js"></script>
<script src="./js/makeTextSprite.js"></script>
<title>sence</title>
<style>
*{margin:0;padding:0;}
body{overflow:hidden;}
</style>
</head>
<body>
</body>
<script>
const FRESH_TIME = 3000; // 数据刷新时间
// 创建场景
let Scene = new THREE.Scene();
// 创建相机
let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = -50;
camera.position.y = 30;
camera.position.z = 50;
camera.lookAt(Scene.position);  // 视⾓
// 创建渲染器
let renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0x000000));
abled = true;
document.body.appendChild(renderer.domElement);
// 创建平⾯
let planeGeometry = new THREE.PlaneGeometry(60, 60, 1, 1); // 平⾯⽹格  let textureLoader = new THREE.TextureLoader();
let texture = textureLoader.load('./img/3.jpg');
var textureNormal = textureLoader.load('./img/3.jpg');
// 加载⾼光贴图
let planeMaterial = new THREE.MeshPhongMaterial({
// specular: 0xff0000,//⾼光部分的颜⾊
shininess: 30,//⾼光部分的亮度,默认30
map: texture,// 普通纹理贴图
roughness:0.3,
lightMap:textureNormal,
// normalMap: textureNormal, //法线贴图
bumpScale: 3
}); //材质对象Material
// let planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});  let plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.x = 0;
plane.name = '平⾯物体ID=' + 1;
plane.position.y = 0;
plane.position.z = 0;
Scene.add(plane);
// 创建⽴⽅体
let boxGeometry = new THREE.BoxGeometry(10, 10, 10, 200);
let texture1 = textureLoader.load('./img/tim.jpg');
let boxGeometryMaterial = new THREE.MeshLambertMaterial({
// specular: 0xff0000,//⾼光部分的颜⾊
shininess: 30,//⾼光部分的亮度,默认30
normalScale: new THREE.Vector2(2.2, 2.2),
map: texture1,// 普通纹理贴图
normalMap: textureNormal, //法线贴图
bumpMap: textureNormal,
bumpScale: 0.3
});
let box = new THREE.Mesh(boxGeometry, boxGeometryMaterial);
box.name = '正⽅物体ID=' + 2;
position标签属性box.position.x = 10;
box.position.y = 5;
box.position.z = 0;
box.castShadow = true;
Scene.add(box);
// 点击事件
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
// 点击了哪个模型
function clickEvent () {
if (event.target.tagName == 'CANVAS') {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
Scene.updateMatrixWorld(true);
// 通过⿏标点的位置和当前相机的矩阵计算出raycaster
raycaster.setFromCamera(mouse, camera);
// 获取raycaster直线和所有模型相交的数组集合
let intersects = raycaster.intersectObjects(Scene.children, true);
if (intersects[0]) {
console.log(intersects[0]);
}
window.addEventListener('click', clickEvent, false);
// 创建灯光
// 点光源
let spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-60, 40, -20);
spotLight.castShadow = true;
Scene.add(spotLight);
// 平⾏光
let directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的⽅向:通过光源position属性和⽬标指向对象的position属性计算
directionalLight.position.set(-90, 80, -20);
// ⽅向光指向对象⽹格模型mesh2,可以不设置,默认的位置是0,0,0
directionalLight.target = box;
Scene.add(directionalLight);
// 环境光
let ambient = new THREE.AmbientLight(0x444444);
Scene.add(ambient);//环境光对象添加到scene场景中
let gui = {
bump:0.03,
animation:false
};
let datGui = new dat.GUI();
//将设置属性添加到gui当中,gui.add(对象,属性,最⼩值,最⼤值)
datGui.add(gui, "bump", -1, 1).onChange(function (e) {
box.material.bumpScale = e;
});
datGui.add(gui, "animation");
//创建控件对象
let controls = new THREE.OrbitControls(camera,renderer.domElement);
// 添加辅助坐标轴
let axisHelper = new THREE.AxisHelper(250);
Scene.add(axisHelper);
/
/ 清空雪碧图
function clearSprite (type = 'Sprite') {
const children = [];
(Scene.children || []).forEach((v, idx) => {
if (v.type !== type) {
children.push(v);
}
});
Scene.children = children;
}
// 循环数据,添加精灵标签
function loopData () {
clearSprite();
(Scene.children || []).forEach((v, idx) => {
if (v.type == 'Mesh') {
const text = v.name + new Date().getTime();
const color = new Date().getTime() % 2 == 1 ? 'rgba(234, 42, 6, 1)' : 'rgba(0, 0, 0, 1.0)'        let sprite = makeTextSprite(text, {
color: color
});
< = new THREE.Vector2(0, 0);
Scene.add(sprite);
sprite.position.set(v.position.x, v.position.y + 5, v.position.z);
}
const timeId = setInterval(_ => {
loopData();
}, FRESH_TIME);
loopData();
function render () {
requestAnimationFrame(render);
}
render();
</script>
</html>
makeTextSpritejs代码
/* 创建字体精灵 */
function makeTextSprite(message, parameters) {
if (parameters === undefined) parameters = {}
let fontface = parameters.hasOwnProperty("fontface") ?
parameters["fontface"] : "Arial"
/* 字体⼤⼩ */
let fontsize = parameters.hasOwnProperty("fontsize") ?
parameters["fontsize"] : 18
let color = parameters.hasOwnProperty("color") ?
parameters["color"]: 'rgba(0, 0, 0, 1.0)'
/* 边框厚度 */
let borderThickness = parameters.hasOwnProperty("borderThickness") ?
parameters["borderThickness"] : 4
/* 边框颜⾊ */
let borderColor = parameters.hasOwnProperty("borderColor") ?
parameters["borderColor"] : {
r: 0,
g: 0,
b: 0,
a: 1.0
}
/* 背景颜⾊ */
let backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
parameters["backgroundColor"] : {
r: 255,
g: 255,
b: 255,
a: 1.0
}
/* 创建画布 */
let canvas = ateElement('canvas');
let context = Context('2d')
/* 字体加粗 */
context.font = "Bold " + fontsize + "px " + fontface
/* 获取⽂字的⼤⼩数据,⾼度取决于⽂字的⼤⼩ */
let metrics = asureText(message);
let textWidth = metrics.width
/* 背景颜⾊ */
context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + "," +    backgroundColor.b + "," + backgroundColor.a + ")"
/* 边框的颜⾊ */
borderColor.b + "," + borderColor.a + ")";
context.lineWidth = borderThickness
/* 绘制圆⾓矩形 */
roundRect(context, borderThickness / 2, borderThickness / 2, textWidth + borderThickness, fontsize * 1.4 +    borderThickness,
6)
/* 字体颜⾊ */
context.fillStyle = color;
context.fillText(message, borderThickness, fontsize + borderThickness)
/* 画布内容⽤于纹理贴图 */
let texture = new THREE.Texture(canvas);
let spriteMaterial = new THREE.SpriteMaterial({
map: texture
});
let sprite = new THREE.Sprite(spriteMaterial)
console.log(sprite.spriteMaterial)
/* 缩放⽐例 */
sprite.scale.set(10, 5, 0)
return sprite
};
/* 绘制圆⾓矩形 */
function roundRect(ctx, x, y, w, h, r) {
ctx.beginPath();
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
ctx.fill();
ctx.stroke();
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。