threejs利用svg拉伸形成立体图

不问归期 提交于 2020-03-03 05:56:06

1.效果

1.svg图片转化成threejs对象

这里我们用到了别人写好的函数transformSVGPathExposed(),这个函数传入的变量是svg图片的路径字符串,输出的是threejsshape对象。
https://johnson2heng.github.io/three.js-demo/lib/js/libs/d3-threeD.js
我们在vue中引入上述js文件需要做一点小小修改。
原文件如下:

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
var transformSVGPathExposed;

function d3threeD(exports) {

  const DEGS_TO_RADS = Math.PI / 180,
    UNIT_SIZE = 1;

  const DIGIT_0 = 48,
    DIGIT_9 = 57,
    COMMA = 44,
    SPACE = 32,
    PERIOD = 46,
    MINUS = 45;
  function transformSVGPath(pathStr) {
    // 函数实现方法
  }

  transformSVGPathExposed = transformSVGPath;

  function applySVGTransform(obj, tstr) {
	// 函数实现方法
  }
   applySVGTransformExposed = applySVGTransform
   // 还有一些函数
}

var $d3g = {};
d3threeD($d3g);
(一)引入THREE

在文件前面引入threejs

var THREE = require('three')
(二)定义applySVGTransformExposed

要不然会出现applySVGTransformExposed变量未定义的错误

var applySVGTransformExposed;
(三)导出transformSVGPathExposed

在文件结尾的地方导出transformSVGPathExposed

export {
  transformSVGPathExposed
}
(四)调试的错误


发现报错的来源是函数中一段代码:

case ' ':
          // if it's an empty space, just skip it, and see if we can find a real command
     break;
 default:
     throw new Error("weird path command: " + activeCmd);

这段代码中throw Error会抛出这个错误,这里我们只需要把抛出错误那句话改成break就可以,主要原因是在html中svg的路径中我们用到了换行,但是这个判断中没有涉及换行符。

        case ' ':
          // if it's an empty space, just skip it, and see if we can find a real command
          break;
        default:
          break;

2.html代码

<template>
  <div>
    <div class="path">
      <svg>
        <g>
          <path id="heart-path" d="M20.5,9.5
          c-1.955,0,-3.83,1.268,-4.5,3
          c-0.67,-1.732,-2.547,-3,-4.5,-3
          C8.957,9.5,7,11.432,7,14
          c0,3.53,3.793,6.257,9,11.5
          c5.207,-5.242,9,-7.97,9,-11.5
          C25,11.432,23.043,9.5,20.5,9.5z"/>
        </g>
      </svg>
    </div>
    <div id="container">
    </div>
  </div>
</template>

<style lang="scss">
html,body{
  padding: 0;
  margin: 0;
}
.path{
  display: none;
}
</style>

3.thrssjs中拉伸代码

import { transformSVGPathExposed } from './assets/js/SVGtoThreejs.js'
export default {
    name: 'ThreeTest',
    data () {
      return {
        camera: null,
        scene: null,
        renderer: null,
        options: {
          depth: 1,
          bevelThinkness: 4,
          bevelSize: 2,
          bevelSegments: 6,
          bevelEnabled: true,
          curveSegments: 6,
          steps: 1
        }
      }
    },
    methods: {
      drawShape: function () {
    	let svgString = document.getElementById('heart-path').getAttribute('d')
    	let shape = transformSVGPathExposed(svgString)
   	 	let svgGeometry = new this.THREE.ExtrudeGeometry(shape, this.options);
    	let svgMaterial = new this.THREE.MeshPhongMaterial({color: 0x7777ff, shininess: 60});
    	let svg = new this.THREE.Mesh(svgGeometry, svgMaterial)
    	svg.rotation.x = Math.PI/2
    	svg.castShadow = true
    	return svg
  }
}

对于options参数说明:
depth拉伸的高度。
bevelThinkness斜角厚度,指的是svg图像拉伸过程中,由小变大部位的厚度,我发现这个厚度要是设置的比depth还要大的时候,depth不起作用。
bevelSize表示svg拉伸过程中由小变大部位,小和大的对比,要是为1,那么小和大的地方差不多,要是为2那么可以看出来上由小变大还是比较明显的。

注意上面表中的amount就是我们用到的depth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!