How to load SVG file into SVGRenderer in three.js

坚强是说给别人听的谎言 提交于 2021-02-07 03:48:41

问题


I'm trying to use SVGRenderer in three.js (http://threejs.org/examples/#svg_sandbox). The example shows you how to make an SVG element (a circle) on the fly. I want to import an SVG file that I already have in my computer. How would I do that?

The createElementNS command doesn't seem to support importing SVG files?

I essentially want my image.svg to be displayed on a three.js scene.


回答1:


You can use the THREE.SVGLoader() Library to achieve it :

var svgManager = new THREE.LegacySVGLoader();
var url = 'https://upload.wikimedia.org/wikipedia/commons/b/b0/NewTux.svg';

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

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

var camera, scene, renderer;

function init(svgObject) {
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000);
  camera.position.z = 1500;

  svgObject.position.x = Math.random() * innerWidth;
  svgObject.position.y = 200;
  svgObject.position.z = Math.random() * 10000 - 5000;
  svgObject.scale.x = svgObject.scale.y = svgObject.scale.z = 0.01;

  scene = new THREE.Scene();
  scene.add(svgObject);

  var ambient = new THREE.AmbientLight(0x80ffff);
  scene.add(ambient);
  var directional = new THREE.DirectionalLight(0xffff00);
  directional.position.set(-1, 0.5, 0);
  scene.add(directional);
  renderer = new THREE.SVGRenderer();
  renderer.setClearColor(0xf0f0f0);
  renderer.setSize(window.innerWidth, window.innerHeight - 5);
  document.body.appendChild(renderer.domElement);

  window.addEventListener('resize', onWindowResize, false);
}

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

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  var time = Date.now() * 0.0002;
  camera.position.x = Math.sin(time) * 200;
  camera.position.z = Math.cos(time) * 200;
  camera.lookAt(scene.position);
  renderer.render(scene, camera);
}
* {
  margin: 0
}
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/renderers/SVGRenderer.js"></script>
<script src="http://threejs.org/examples/js/renderers/Projector.js"></script>
<script src="http://threejs.org/examples/js/loaders/SVGLoader.js"></script>
<script>
  /**
   * @name LegacySVGLoader
   * @author mrdoob / http://mrdoob.com/
   * @author zz85 / http://joshuakoo.com/
   * @see https://github.com/mrdoob/three.js/issues/14387
   */

  THREE.LegacySVGLoader = function(manager) {

    this.manager = (manager !== undefined) ? manager : THREE.DefaultLoadingManager;

  };

  THREE.LegacySVGLoader.prototype = {

    constructor: THREE.LegacySVGLoader,

    load: function(url, onLoad, onProgress, onError) {

      var scope = this;

      var parser = new DOMParser();

      var loader = new THREE.FileLoader(scope.manager);
      loader.load(url, function(svgString) {

        var doc = parser.parseFromString(svgString, 'image/svg+xml'); // application/xml

        onLoad(doc.documentElement);

      }, onProgress, onError);

    }

  };
</script>



回答2:


This is current answer from latest three.js lib:

https://threejs.org/examples/?q=svg#webgl_loader_svg

but this code loads svg into geometry mesh, so it is not a DOM element, it zooms out just like any other 3d object. Its like a billboard in 3d scene. If someone needs this kind of behavior then its fine.

If you want to load SVG to be DOM element, to have it float over 3D scene, to be able to add mouse click and hover events... I asked for example and here it is:

https://github.com/mrdoob/three.js/issues/15528



来源:https://stackoverflow.com/questions/33140342/how-to-load-svg-file-into-svgrenderer-in-three-js

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