Converting a three.js scene into SVG or alternative vector format for export

Can an SVG- or other vector-formatted image be exported from a scene rendered using three.js's WebGLRenderer? What about from a scene derived from CanvasRenderer?

If not, how can one set up SVGRenderer with three.js? Creating a new THREE.SVGRenderer() in v69 seems to result in an error in the console, suggesting that the constructor is unavailable. The documentation for three.js lacks information on SVGRenderer. Once configured, is it feasible to utilize textures and particles with SVGRenderer similar to WebGLRenderer?

Answer №1

If you have a task of exporting an svg from three.js, I have a working solution for you. This solution makes use of the SVGRenderer:

var controls;
var camera, scene, renderer;
var geometry, material, mesh;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.x = 2;
  camera.position.y = 1;
  camera.position.z = 3;
  camera.zoom = 3.6;
  camera.updateProjectionMatrix();

  scene = new THREE.Scene();

  geometry = new THREE.BoxGeometry(0.4, 0.2, 0.2);
  material = new THREE.MeshNormalMaterial();

  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({
    antialias: true,
    preserveDrawingBuffer: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight - 70);

  controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.update();

  document.body.appendChild(renderer.domElement);
  
}

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

function btnSVGExportClick() {
  var rendererSVG = new THREE.SVGRenderer();
  
  rendererSVG.setSize(window.innerWidth, window.innerHeight);
  rendererSVG.render(scene, camera);
  ExportToSVG(rendererSVG, "test.svg");
}

function ExportToSVG(rendererSVG, filename) {
  var XMLS = new XMLSerializer();
  var svgfile = XMLS.serializeToString(rendererSVG.domElement);
  var svgData = svgfile;
  var preface = '<?xml version="1.0" standalone="no"?>\r\n';
  var svgBlob = new Blob([preface, svgData], {
    type: "image/svg+xml;charset=utf-8"
  });
  var svgUrl = URL.createObjectURL(svgBlob);
  var downloadLink = document.createElement("a");
  
  downloadLink.href = svgUrl;
  downloadLink.download = filename;
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/renderers/SVGRenderer.js"></script>
<script src="https://threejs.org/examples/js/renderers/Projector.js"></script>

<input id="btnSVGExport" type="button" value="Get as SVG" onclick="btnSVGExportClick()" style="margin-bottom:3px">

To make use of this code, save it in a file named some.html and click on the Get as SVG button to export to an svg file. You can also view the jsfiddle link for reference: https://jsfiddle.net/9y0b3wet/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Prevent Click Event on Angular Mat-Button

One of the challenges I'm facing involves a column with buttons within a mat-table. These buttons need to be enabled or disabled based on a value, which is working as intended. However, a new issue arises when a user clicks on a disabled button, resul ...

Enhancing ajax requests with headers in Ember.js

My goal is to configure request headers for my emberjs application. However, when setting it up in the initializer, the client_id appears as [object Object] instead of the actual value. This is the initializer that runs when the application starts. Apikey ...

Does this Loop run synchronously?

Recently, I crafted this Loop to iterate through data retrieved from my CouchDB database. I am curious whether this Loop operates synchronously or if async/await is necessary for proper execution. database.view('test', 'getAllowedTracker&ap ...

Angular state correctly maps to the controller but is not reflected in the HTML

I'm currently in the process of setting up a basic Angular application, something I've done many times before. I have defined a home state and another state for a note-taking app, but I am facing an issue where neither state is displaying or inje ...

Finding the tiniest match within a regex pattern

Looking for a way to match the fourth element in this expression: var string = [a][1] [b][2] [c][3] [d .-][] [e][4] The element we're trying to target is [d .-][]. This specific element can contain any character within the first set of brackets, whi ...

Generating numerous circular elements for each item in the dataset using D3

My dataset consists of various years and corresponding numerical values for each year as shown below: "data":[ ["1951","306","27","159","34","82","4"], ["1956","426","41","203","47","119","16"], ["1959","562","67"," ...

cheerio scraping results in an array that is devoid of any data

Struggling to extract data from a website with the URL https://buff.163.com/market/csgo#tab=buying&page_num=1 using request-promise and cheerio. Check out my code snippet below: const request = require('request-promise'); const cheerio = requ ...

Executing a Python function on a server from a local machine with the help of AngularJS

I am encountering an issue with calling a python function using an angularjs $http request. The python function I have on the server looks like this: import cgi, cgitb data= cgi.FieldStorage() name = data.getvalue("name"); age = data.getvalue("age"); def ...

Leveraging ng-class with an Angular $scope attribute

My HTML structure includes: <div class="myDiv"> <div style="width:200px; height:200px;background-image:url('img/200x200/{{largeImg}}.png');" ng-class="{'magictime foolishIn': 1}"> <span> { ...

Guide to verifying all chosen options in a multiple select field using EJS

I am looking for the most effective way to check all selected options in my select dropdown when data is being edited. Here is an example of my select dropdown that supports multiple selections: <select name="tags[]" class="multi-select" multiple="" i ...

Is it possible to use getJSON to retrieve a value from an HTML tag ID that has already been displayed on a webpage? How about using json_decode

Is there a way to retrieve the value using the HTML tag ID after an HTML page has been rendered? For example, how can I access the date value using the td_date in my JavaScript function? Below is the code snippet that populates the data on the page: listS ...

The initial click does not trigger a state update in React

I attempted to create a straightforward system for displaying data with two sorting buttons (ascending & descending). My approach involved fetching and displaying data from an array using the map method. In a separate component file, I utilized useEffect ...

Executing asynchronous jQuery AJAX requests using the async/await syntax

Currently, I have a situation where I am using 3 ajax call methods in succession. However, there needs to be a delay between the second and third ajax calls. Initially, I used "async:false" in the second ajax call and everything worked smoothly. But later ...

Issue with vue-template-compiler in Vue.js 3 webpack configuration

I am currently working on integrating vuejs 3 into a project that already utilizes webpack. I have been looking into using vue-loader as part of this process. After consulting the official documentation, I came across the following information: Every new ...

Is there a way to automatically mount tabs without manually clicking on them?

Looking to optimize data fetches within a large tab container in React using material-ui. My goal is to have each Tab component handle its own data fetching, especially for Tabs with a greedyLoad prop that will be mounted upon the initial mounting of the T ...

Using TypeScript to determine the week number - the value on the right side of the math operation must be of data type 'any'

I've spent a lot of time searching for code to help me calculate the week number in my Angular app according to ISO standards. It's been challenging to find JavaScript-specific code, but I believe I may have found something - however, I encounter ...

What is the purpose of encasing the routes within the <Switch> element in react-router, when they seem to function perfectly fine without it

Currently utilizing react-router-dom version 5.2.0. As a practice, I typically enclose all my Route components within a Switch component. For instance: const MyRoutes = () => ( <Switch> <Route path='/route1' exact ...

The ng-change event is triggered for radio buttons that are generated using ng-repeat the first time they appear, but not for subsequent appearances

Is it possible to trigger the updateRow method on every change of a radio button selection? Currently, the updateRow method is only being called the first time the radio button changes. How can I make sure it executes each time there is a change? Html: ...

Leveraging the power of `.vue` files in modern web browsers that have native support for

Chrome 60 and the most recent version of Firefox, when used with certain flags enabled, have implemented support for import/export directives. I am interested in utilizing .vue files without relying on NodeJS, but I haven't been able to figure out how ...

NextJs not processing Bootstrap form submissions

I’m struggling to figure out why my form isn’t submitting when I click the submit button. The backend seems fine because Postman successfully sends the information to the database. However, nothing happens when I try to submit the form. My tech stack ...