15 - three.js 笔记 - 使用 ShapeGeometry 创建二维字体模型

ShapeGeometry

通过THREE.ShapeGeometry,你可以调用几个函数来创建自己的图形。我们可以使用线条(line)、曲线(curve)和样条曲线(spline)创建图形的轮廓。还可以使用THREE.Shape对象的holes属性给这个图形打几个孔。

效果图

这里写图片描述
示例浏览地址:http://ithanmang.com/threejshome/textShapes.html

构造函数

ShapeGeometry(shapes, curveSegments)

shapes – shapes数组或者是单一的shape
curveSegments – [可选的] 形状的分段数,默认值是 12
其父类是Geometry

示例

创建一个心的形状

var x = 0, y = 0;

var heartShape = new THREE.Shape();

heartShape.moveTo( x + 5, y + 5 );
heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );

传给ShapeGeometry

var geometry = new THREE.ShapeGeometry( heartShape );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );

效果

这里写图片描述

创建二维字体

主要代码
var text = "three.js";
    var loader = new THREE.FontLoader();
    loader.load('../../libs/examples/fonts/gentilis_regular.typeface.json', function (font) {
        // 材质
        var fontMaterial = new THREE.MeshLambertMaterial({
            color: 0x912CEE,
            side: THREE.DoubleSide
        });
        var planeMaterial = new THREE.MeshLambertMaterial({
            color: 0x545454,
            transparent: true,
            opacity: 0.6,
            side: THREE.DoubleSide
        });

        var planeGeometry = new THREE.PlaneGeometry(600, 300);
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.position.y += 40;
        scene.add(plane);

        // 生成二维字体模型
        var shapes = font.generateShapes(text, 100, 1);
        var fontGeometry = new THREE.ShapeGeometry(shapes);

        // 绑定盒子模型
        fontGeometry.computeBoundingBox();
        var font = new THREE.Mesh(fontGeometry, fontMaterial);
        // x = 0,位置
        font.position.x = -0.5 * (fontGeometry.boundingBox.max.x - fontGeometry.boundingBox.min.x);
        font.position.z += 1;
        scene.add(font);
    });
}

r94 –>generateShapes构造函数

取消了第三个参数
这里写图片描述

  1. 依据回调函数返回的 font生成字体形状数组( shapes ),将shapes加入到
// 创建一个表示字体文本的形状数组--->r94 版本 取消了 第三个参数(divisions :线条的细度)
var shapes = font.generateShapes(text, 100, 1);
r94 ---> var shapes = font.generateShapes(text, 100);
  1. shapes加入ShapeGeometry(shapes)创建多边几何体
var fontGeometry = new THREE.ShapeGeometry(shapes);
  1. 绑定盒子模型便于计算位置
 // 绑定盒子模型
fontGeometry.computeBoundingBox();

完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>二维字体</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
    <script src="../../libs/build/three.js"></script>
    <script src="../../libs/examples/js/Detector.js"></script>
    <script src="../../libs/examples/js/controls/TrackballControls.js"></script>
    <script src="../../libs/examples/js/libs/dat.gui.min.js"></script>
    <script src="../../libs/examples/js/libs/stats.min.js"></script>
</head>
<body>
<div id="WebGL-output"></div>
<div id="Stats-output"></div>
<script>

    var stats = initStats();
    var scene, camera, renderer, controls, light;

    function initScene() {
        scene = new THREE.Scene();
    }

    function initCamera() {
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
        camera.position.set(0, 60, 600);
        camera.lookAt(new THREE.Vector3(0, 0, 0));
    }

    function initRenderer() {
        if (Detector.webgl) {
            renderer = new THREE.WebGLRenderer({antialias: true});
        } else {
            renderer = new THREE.CanvasRenderer();
        }
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x050505);
        document.body.appendChild(renderer.domElement);
    }

    function initContent() {
        var helper = new THREE.GridHelper(1200, 50, 0xCD3700, 0x4A4A4A);
        scene.add(helper);

        var text = "three.js";
        var loader = new THREE.FontLoader();
        loader.load('../../libs/examples/fonts/gentilis_regular.typeface.json', function (font) {
            // 材质
            var fontMaterial = new THREE.MeshLambertMaterial({
                color: 0x912CEE,
                side: THREE.DoubleSide
            });
            var planeMaterial = new THREE.MeshLambertMaterial({
                color: 0x545454,
                transparent: true,
                opacity: 0.6,
                side: THREE.DoubleSide
            });

            var planeGeometry = new THREE.PlaneGeometry(600, 300);
            var plane = new THREE.Mesh(planeGeometry, planeMaterial);
            plane.position.y += 40;
            scene.add(plane);

            // 生成二维字体模型
            var shapes = font.generateShapes(text, 100, 1);
            var fontGeometry = new THREE.ShapeGeometry(shapes);

            // 绑定盒子模型
            fontGeometry.computeBoundingBox();
            var font = new THREE.Mesh(fontGeometry, fontMaterial);
            // x = 0,位置
            font.position.x = -0.5 * (fontGeometry.boundingBox.max.x - fontGeometry.boundingBox.min.x);
            font.position.z += 1;
            scene.add(font);
        });
    }

    function initControls() {
        controls = new THREE.TrackballControls(camera, renderer.domElement);
        controls.noPan = true;
    }

    function initLight() {
        light = new THREE.SpotLight(0xffffff);
        light.position.set(-300, 600, -400);
        light.castShadow = true;

        scene.add(light);
        scene.add(new THREE.AmbientLight(0xC1C1C1));
    }

    function initGui() {
        gui = new function () {

        }

        var guiControls = new dat.GUI();
    }

    // 初始化性能插件
    function initStats() {
        var stats = new Stats();

        stats.domElement.style.position = 'absolute';
        stats.domElement.style.left = '0px';
        stats.domElement.style.top = '0px';

        document.body.appendChild(stats.domElement);
        return stats;
    }

    function update() {
        stats.update();
        controls.update();
        controls.handleResize();
    }

    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function init() {
        initScene();
        initCamera();
        initRenderer();
        initContent();
        initLight();
        initControls();
        initGui();
        addEventListener('resize', onWindowResize, false);
    }

    function animate() {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
        update();
    }

    init();
    animate();

</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/ithanmang/article/details/80905436