.svg资产在three.js 3d空间中

时间:2017-10-13 00:56:19

标签: svg three.js

我正在尝试将.svg资源加载到我的three.js场景中,作为平面矢量图层;我在其他帖子中找到了SVGLoaderSVGRenderer这个示例,但我无法使其正常工作。

加载的svg卡在2d空间而没有响应相机移动,我无法访问它的位置。 我试图切换到WebGLRenderer,但svg没有加载。

将它加载为精灵的选项会很好,但我希望精灵不要面对相机并保持静止在3d空间。

var svgManager = new THREE.SVGLoader();
var url = 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Europe_laea_location_map.svg';

function svg_loading_done_callback(doc) {
  init();
  svg(new THREE.SVGObject(doc));
  ico();
  animate();
};

svgManager.load(url,
  svg_loading_done_callback,
  function() {
    console.log("Loading SVG...");
  },
  function() {
    console.log("Error loading SVG!");
  });


var AMOUNT = 100;
var container, camera, scene, renderer;

function init() {
  scene = new THREE.Scene();
  renderer = new THREE.SVGRenderer();
  renderer.setClearColor(0x00ff00);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  var container = document.getElementById('container');
  container.appendChild(renderer.domElement);

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.z = 1100;
  controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.enableZoom = true;
  window.addEventListener('resize', onWindowResize, false);
}

function svg(svgObject) {
  svgObject.position.x = 510;
  svgObject.position.y = -110;
  svgObject.position.z = 0;
  scene.add(svgObject);
}

function ico() {
  geometry = new THREE.IcosahedronGeometry(100, 1)
  material = new THREE.MeshNormalMaterial({});
  ico = new THREE.Mesh(geometry, material);
  ico.position.y = -300;
  scene.add(ico);
  ico2 = new THREE.Mesh(geometry, material);
  ico2.position.y = 500;
  ico2.position.x = -500;
  ico2.position.z = -50;
  scene.add(ico2);
}

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

function animate() {
  requestAnimationFrame(animate);
  controls.update;
  render();
}

function render() {
  renderer.render(scene, camera);
}
body {
  margin: 0;
}

canvas {
  width: 100%;
  height: 100%
}
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

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

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/renderers/SVGRenderer.js"></script>
<script src="https://threejs.org/examples/js/renderers/Projector.js"></script>
<script src="https://threejs.org/examples/js/loaders/SVGLoader.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

1 个答案:

答案 0 :(得分:3)

SVGLoaderSVGRenderer是两回事。前者加载SVG文件并将其转换为three.js形状(尽管有一些限制,即可以读取非常简单的SVG,不呈现笔划,而仅填充对象等),而后者则使用SVG元素呈现three.js原语。而不是WebGL。从某种意义上说,它们是彼此对立的。

因此,首先,您需要在案件中使用WebGLRenderer

然后,您需要更改SVG加载回调。它接收到一个可用于渲染SVG的路径数组。

查看功能svg_loading_done_callbackinitsvg中的更改,并在JSFiddle中运行它:

var svgManager = new THREE.SVGLoader();
var url = 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Europe_laea_location_map.svg';

function svg_loading_done_callback(paths) {
  init();
  svg(paths);
  ico();
  animate();
};

svgManager.load(url,
  svg_loading_done_callback,
  function() {
    console.log("Loading SVG...");
  },
  function() {
    console.log("Error loading SVG!");
  });


var AMOUNT = 100;
var container, camera, scene, renderer;

function init() {
  scene = new THREE.Scene();
  renderer = new THREE.WebGLRenderer();
  renderer.setClearColor(0x00ff00);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  var container = document.getElementById('container');
  container.appendChild(renderer.domElement);

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.z = 1100;
  controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.enableZoom = true;
  window.addEventListener('resize', onWindowResize, false);
}

function svg(paths) {

  var group = new THREE.Group();
  group.position.x = 510;
  group.position.y = -110;
  group.position.z = 0;

  for ( var i = 0; i < paths.length; i ++ ) {

    var path = paths[ i ];

    var material = new THREE.MeshBasicMaterial( {
      color: path.color,
      side: THREE.DoubleSide,
      depthWrite: false
    } );

    var shapes = path.toShapes( true );

    for ( var j = 0; j < shapes.length; j ++ ) {

      var shape = shapes[ j ];

      var geometry = new THREE.ShapeBufferGeometry( shape );
      var mesh = new THREE.Mesh( geometry, material );

      group.add( mesh );

    }

  }

  scene.add( group );
}

function ico() {
  geometry = new THREE.IcosahedronGeometry(100, 1)
  material = new THREE.MeshNormalMaterial({});
  ico = new THREE.Mesh(geometry, material);
  ico.position.y = -300;
  scene.add(ico);
  ico2 = new THREE.Mesh(geometry, material);
  ico2.position.y = 500;
  ico2.position.x = -500;
  ico2.position.z = -50;
  scene.add(ico2);
}

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

function animate() {
  requestAnimationFrame(animate);
  controls.update;
  render();
}

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

PS:检查SVG Loader以查看其能够解析的内容