Three.js箭头指向路径特效-设置纹理offset偏移模拟箭头线性流动
1、效果
通过循环 texture的offset属性值,可以实现,类似字幕的运动,以及箭头的线性流动等效果
2、示例地址
https://demos.webglstudy.com/threejs-20210711-arrow-simulate/index.html
3、相关属性
该示例使用的是平面网格,然后加上材质贴图,设置纹理重复覆盖THREE.RepeatWrapping
然后循环渲染纹理的偏移量
3.1、wrapS/wrapT
纹理水平和垂直方向的平铺方式,分别对应 uv 贴图的uv属性,详细查看文档Texture 纹理常量:地址
offset 在U和V方向上,纹理在模型表面上重复绘制时的偏移。通常范围是0.0 到 1.0。注意: offset属性是一个便捷修饰符,仅影响Texture对模型上第一组UV的应用。如果纹理用作需要额外UV集的贴图(例如,大多数库存材料的aoMap或lightMap),则必须手动分配这些UV以获得所需的偏移量。
repeat 纹理在整个表面上重复多少次,在每个方向U和V上。如果在任一方向上repeat设置为大于1,则相应的Wrap参数也应设置为 THREE.RepeatWrapping或THREE.MirroredRepeatWrapping以实现所需的平铺影响。注意: repeat属性是一个便捷修饰符,仅影响Texture对模型上第一组UV的应用。如果纹理用作需要额外UV集的贴图(例如,大多数库存材料的aoMap或lightMap),则必须手动分配这些UV以实现所需的重复。
3.1.1、Wrapping Modes 模式
THREE.RepeatWrapping
THREE.ClampToEdgeWrapping
THREE.MirroredRepeatWrapping
THREE.RepeatWrapping
:重复包裹
THREE.ClampToEdgeWrapping
:纹理的最后一个像素延伸到网格的边缘,默认值
THREE.MirroredRepeatWrapping
:纹理镜像重复
3.1、offset
是一个 vector2变量,单个纹理的偏移量
3.2、repeat
一个Vector2变量,纹理在 uv 方向上的重复次数,若大于1则需要设置wrapS/wrapT属性值为THREE.RepeatWrapping / THREE.MirroredRepeatWrapping
4、实现方法
4.1、创建纹理
texture = new THREE.TextureLoader().load(‘../../textures/arrows/arrow-right.png’);
4.2、设置uv重复包裹方式
textur.wrapS = THREE.RepeatWrapping;
texture.wrapT=THREE.RepeatWrapping;
4.3、设置重复次数
texture.repeat.x = 10;
texture.repeat.y =1;
x
方向重复,10
次,y
方向默认值为1
4.4、创建 Mesh 并设置纹理贴图
var planeGeometry = new THREE.PlaneGeometry(200, 10);
var plane = new THREE.MeshBasicMaterial();
plane.color = new THREE.Color(0x00ff00);
plane.map = texture;
plane.transparent = true;
plane.side = THREE.DoubleSide;
4.5、循环设置纹理偏移量 offset
texture.offset.x += 0.001;
上面是x
方向,循环移动
4.6、效果
5、完整示例代码(可以右侧按钮点击下载)
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<link rel=”icon” href=”../../../three.png”>
<title>纹理offset偏移</title>
<style>
body {
margin: 0;
overflow: hidden; /* 溢出隐藏 */
}
#loading {
position: fixed;
top: 50%;
left: 50%;
color: #FFFFFF;
font-size: 20px;
margin-top: -30px;
margin-left: -40px;
}
</style>
<script src=”../../libs/build/three-r93.js”></script>
<script src=”../../libs/examples/js/Detector.js”></script>
<script src=”../../libs/examples/js/libs/dat.gui.min.js”></script>
<script src=”../../libs/examples/js/libs/stats.min.js”></script>
<script src=”../../libs/examples/js/controls/OrbitControls.js”></script>
</head>
<body>
<p id=”loading”>loading……</p>
<script>
var scene, camera, renderer, controls, guiControls;
var stats = initStats();
/* 场景 */
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x050505);
}
/* 相机 */
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, -300);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
/* 渲染器 */
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/* 灯光 */
function initLight() {
scene.add(new THREE.AmbientLight(0x0c0c0c));
var spotLight1 = new THREE.SpotLight(0xffffff);
spotLight1.position.set(-400, -400, -400);
var spotLight2 = new THREE.SpotLight(0xffffff);
spotLight2.position.set(400, 400, 400);
scene.add(spotLight1);
scene.add(spotLight2);
}
/* 控制器 */
function initControls() {
/* 地图控件 */
controls = new THREE.OrbitControls(camera, renderer.domElement);
/* 属性参数 */
}
/* 调试插件 */
function initGui() {
guiControls = new function () {
};
var gui = new dat.GUI();
}
/* 场景中的内容 */
var texture_left;
var texture_up;
function initContent() {
texture_left = new THREE.TextureLoader().load(‘../../textures/arrows/arrow-right.png’);
texture_up = new THREE.TextureLoader().load(‘../../textures/arrows/arrow-up.png’);
texture_left.wrapS = THREE.RepeatWrapping;
texture_left.wrapT=THREE.RepeatWrapping;
texture_up.wrapS = THREE.RepeatWrapping;
texture_up.wrapT = THREE.RepeatWrapping;
texture_left.repeat.x = 10;
texture_left.repeat.y =1;
texture_up.repeat.x = 20;
texture_up.repeat.y =2;
var planeGeometry = new THREE.PlaneGeometry(200, 10);
var plane_left = new THREE.MeshBasicMaterial();
plane_left.color = new THREE.Color(0x00ff00);
plane_left.map = texture_left;
plane_left.transparent = true;
plane_left.side = THREE.DoubleSide;
var plane_up = new THREE.MeshBasicMaterial();
plane_up.color = new THREE.Color(0x00ff00);
plane_up.map = texture_up;
plane_up.transparent = true;
plane_up.side = THREE.DoubleSide;
var plane_left = new THREE.Mesh(planeGeometry, plane_left);
plane_left.translateY(10);
scene.add(plane_left);
var plane_up = new THREE.Mesh(planeGeometry, plane_up);
plane_up.translateY(-10);
scene.add(plane_up);
removeLoading();
}
/* 移除加载元素 */
function removeLoading() {
document.getElementById(‘loading’).style.display = ‘none’;
}
/* 性能插件 */
function initStats() {
var stats = new Stats();
document.body.appendChild(stats.domElement);
return stats;
}
/* 窗口变动触发 */
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/* 数据更新 */
function update() {
stats.update();
controls.update();
// 设置纹理偏移
texture_left.offset.x -= 0.02;
texture_up.offset.y -= 0.02;
}
/* 初始化 */
function init() {
initScene();
initCamera();
initRender();
initLight();
initControls();
initContent();
initGui();
/* 监听事件 */
window.addEventListener(‘resize’, onWindowResize, false);
}
/* 循环渲染 */
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
update();
}
/* 初始加载 */
(function () {
init();
animate();
})();
</script>
</body>
</html>
WEBGL学习网 » Three.js箭头指向路径特效-设置纹理offset偏移模拟箭头线性流动