Three.js 动态连接线的结点

效果图

干货

<template>
    <div id="container"></div>
</template>

<script>
    import * as THREE from 'three'
    import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'

    let textureTest = new THREE.TextureLoader().load('./static/img.png'); // 流动材质 找一个酷炫点的图~
    
    export default {
        name: 'lineAnimate',
        data() {
            return {}
        },
        mounted() {
            var container = document.getElementById('container');
            var scene = new THREE.Scene();
            var camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, .1, 1000);
            camera.position.set(10, 10, 10);
            
            var gridHelper = new THREE.GridHelper(20);
            scene.add(gridHelper);
            
            var renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setPixelRatio(window.devicePixelRatio);
            container.appendChild(renderer.domElement);
            var controls = new OrbitControls(camera, renderer.domElement);
    
            // 光源
            scene.add(new THREE.AmbientLight(0xffffff));
            
            // 渲染
            let arrs = [];
            arrs.push(new THREE.Vector3(-10, 0, 10));
            arrs.push(new THREE.Vector3(-5, 5, 5));
            arrs.push(new THREE.Vector3(0, 0, 0));
            arrs.push(new THREE.Vector3(5, -5, 5));
            arrs.push(new THREE.Vector3(10, 0, 0));
            
            createCurveShape(arrs);
            function createCurveShape(arrs) {
                let curve = new THREE.SplineCurve3(arrs);
                curve.autoClose = false;
                let points = curve.getPoints(50);
                let length = points.length;
                let val = 0;
    
                drawLine();
                function drawLine() {
                    if (val == length - 1) return;
                    
                    let subPoints1 = points[val];
                    let subPoints2 = points[(val + 1) % length];
                    
                    let subPoints = [];
                    subPoints.push(subPoints1);
                    subPoints.push(subPoints2);
                    
                    // 1、使用线连接
                    /*let geometryPoints = new THREE.BufferGeometry().setFromPoints(subPoints);
                    let line = new THREE.Line(geometryPoints, new THREE.LineBasicMaterial({color: 0xff0000}));
                    scene.add(line);*/
                    
                    // 2、使用贴图连接
                    let curve = new THREE.CatmullRomCurve3(subPoints, false); /* 是否闭合 */
                    let tubeGeometry = new THREE.TubeGeometry(curve, 1, 0.2, 3, false); // path, tubularSegments, radius, radiusSegments, closed
                    textureTest.wrapS = THREE.RepeatWrapping;
                    textureTest.wrapT = THREE.RepeatWrapping;
                    let tubeMaterial = new THREE.MeshPhongMaterial({
                        map: textureTest,
                        transparent: true
                    });
                    let tubeMesh = new THREE.Mesh(tubeGeometry, tubeMaterial);
                    scene.add(tubeMesh);
                    
                    val++;
                    setTimeout(drawLine, 16);
                }
            }
    
            render();
            function render() {
                controls.update();
                requestAnimationFrame(render);
                renderer.render(scene, camera);
            }
        }
    }
</script>

<style lang="less">
    * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }
    
    body {
        overflow: hidden;
        font-family: Lato, sans-serif;
        width: 100%;
        height: 100%;
        background-color: #dedede;
        color: #202020;
        padding: 20px;
        text-shadow: 0 1px 0 rgba(255, 255, 255, .5);
    }
    
    #container {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        height: 100%;
        border: 1px solid #ff0000;
    }
</style>

猜你喜欢

发表评论

最新发布