Consider, I have an SVG vector graphics file (logotype), which I want to load and display in three.js (with WebGL renderer).
What would be the recommended way to approach this?
It seems like I need to load the image and to create a geometry and a mesh from it.
I've managed to load the SVG document using the THREE.SVGLoader, but I can't find any relevant information on how to create a geometry/mesh from it further down the line.
function preload () {
const svgLoader = new THREE.SVGLoader();
svgLoader.load('images/logo.svg', svgDocument => {
// @todo: create a geometry/mesh from svgDocument?
// @todo: scene.add(logoMesh);
});
}
If you need svg only for texture purposes:
Disclaimer I'm not the author of this code, I just fixed jsfiddle that I've found
window.onload = () => {
var mesh;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(50, 500 / 400, 0.1, 1000);
camera.position.z = 10;
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(500, 400);
document.body.appendChild(renderer.domElement);
var svg = document.getElementById("svgContainer").querySelector("svg");
var svgData = (new XMLSerializer()).serializeToString(svg);
var canvas = document.createElement("canvas");
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
var ctx = canvas.getContext("2d");
var img = document.createElement("img");
img.setAttribute("src", "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(svgData))) );
img.onload = function() {
ctx.drawImage(img, 0, 0);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var geometry = new THREE.SphereGeometry(3, 50, 50, 0, Math.PI * 2, 0, Math.PI * 2);
var material = new THREE.MeshBasicMaterial({ map: texture });
material.map.minFilter = THREE.LinearFilter;
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
};
var render = function () {
requestAnimationFrame(render);
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
};
render();
}
<script src="https://threejs.org/build/three.min.js"></script>
<div id="svgContainer" style="width: 222px; height: 222px;">
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect width="200" height="200" fill="lime" stroke-width="4" stroke="pink" />
<circle cx="125" cy="125" r="75" fill="orange" />
<polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" />
<line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" />
</svg>
</div>
If you would like to render svg as geometry I'll would suggest use of some libraries e.g. svg-mesh-3d
Example from docs of svg-mesh-3d
var loadSvg = require('load-svg')
var parsePath = require('extract-svg-path').parse
var svgMesh3d = require('svg-mesh-3d')
loadSvg('svg/logo.svg', function (err, svg) {
if (err) throw err
var svgPath = parsePath(svg)
var mesh = svgMesh3d(svgPath, {
delaunay: false,
scale: 4
})
})
Alternative options is to use blender to import svg, (optionally) tune geometry and export it to Three.js using Three.js Blender Export
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With