· Create the world is committed to creating the first “cloud CAD” collaborative design platform integrating viewing, modeling, assembly and rendering in China.
At the request of readers, we hope to set up a professional WEBGL and Threejs industry QQ communication group for front-end developers in Chengdu-Chongqing area to facilitate discussion. There are webGL and Threejs in the group, welcome to join! — Click the link to join the group chat [three.js/ webGL Chongqing Union Group] : jq.qq.com/?_wv=1027&k…
screenshots
In the browser, there are two effective ways to capture the screen. The old Canvas.todataURL and the new Canvas.toblob
It’s easy to think of a way to take a screen shot
<canvas id="c"></canvas>
<button id="screenshot" type="button">Save...</button>
Copy the code
const elem = document.querySelector('#screenshot');
elem.addEventListener('click'.() = > {
canvas.toBlob((blob) = > {
saveBlob(blob, `screencapture-${canvas.width}x${canvas.height}.png`);
});
});
const saveBlob = (function() {
const a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
return function saveData(blob, fileName) {
const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; } ());Copy the code
The actual test came down to an all-black screenshot
The problem is that, for performance and compatibility reasons, the browser clears the drawing buffer of the WebGL canvas by default after you have drawn it.
The solution is to call the render code before capturing.
Something needs to be tweaked in the code. Let’s isolate the rendering code.
const state = {
time: 0};function render(time) {
time *= 0.001;
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
cubes.forEach((cube, ndx) = > {
const speed = 1 + ndx * 1.;
const rot = time * speed;
const rot = state.time * speed;
cube.rotation.x = rot;
cube.rotation.y = rot;
});
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function animate(time) {
state.time = time * 0.001;
render();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
Copy the code
Now Render only cares about the actual rendering, we can call it before capturing the canvas.
const elem = document.querySelector('#screenshot');
elem.addEventListener('click'.() = > {
render();
canvas.toBlob((blob) = > {
saveBlob(blob, `screencapture-${canvas.width}x${canvas.height}.png`);
});
});
Copy the code
The effect is normal
Please refer the case threejsfundamentals.org/threejs/thr…
Prevents the canvas from being cleared
Suppose you want the user to draw with an animated object. You need to pass preserveDrawingBuffer: true when creating the WebGLRenderer. This prevents the browser from clearing the canvas, otherwise three.js should not clear the canvas.
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const renderer = new THREE.WebGLRenderer({
canvas,
preserveDrawingBuffer: true.alpha: true}); renderer.autoClearColor =false;
Copy the code
Specific examples can reference: threejsfundamentals.org/threejs/thr…
This would not be a solution if we made a serious drawing program, because the browser would still clear the canvas when we changed the resolution. We are changing the resolution based on its display size. When a window changes size, its display size changes too. This includes the browser adding a status bar when a user downloads a file, even in a different TAB. It also includes how long it takes the user to turn the phone and browser from portrait to landscape.
Transparent canvas
By default, three.js makes the canvas opaque. If you want the canvas to be transparent to the WebGLRenderer when alpha: True is created
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const renderer = new THREE.WebGLRenderer({
canvas,
alpha: true});Copy the code
PremultipliedAlpha can be set to premultipliedAlpha
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({
canvas,
alpha: true.premultipliedAlpha: false});Copy the code
Three.js defaults to canvas using premultipliedAlpha: true but defaults to material output premultipliedAlpha: false.
If you want to get a better idea of when and when not to use pre-ride Alpha,
Set a simple example with a transparent canvas.
function makeInstance(geometry, color, x) {
const material = new THREE.MeshPhongMaterial({color});
const material = new THREE.MeshPhongMaterial({
color,
opacity: 0.5}); .Copy the code
Add some HTML content
<body>
<canvas id="c"></canvas>
<div id="content">
<div>
<h1>Cubes-R-Us!</h1>
<p>We make the best cubes!</p>
</div>
</div>
</body>
Copy the code
And some CSS to put the canvas in front
body {
margin: 0; {} # Cwidth: 100%;
height: 100%;
display: block;
position: fixed;
left: 0;
top: 0;
z-index: 2; pointer-events: none; } # content {font-size: 7vw; font-family: sans-serif; text-align: center; width:100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
Copy the code
The renderings are as follows
Animate your background to three.js
A common problem is how to make a three.js animation the background of a web page.
There are two obvious approaches.
- Will the canvas CSS
position
Set up thefixed
For the in
C # {position: fixed;
left: 0;
top: 0; . }Copy the code
You can basically see the exact solution in the previous example. Simply set the Z-index to -1 and the cube will appear after the text.
One minor drawback of this solution is that your JavaScript has to be integrated with the page, and if you have a complex page, then you need to make sure that the JavaScript in your three.js visualization doesn’t conflict with JavaScript doing other things in the page.
- use
iframe
For example, insert an iframe into your web page
<iframe id="background" src="threejs-responsive.html">
<div>
Your content goes here.
</div>
Copy the code
We then style the iframe to fill the window and be in the background, which is basically the same code we used for the canvas above, but we also need to set the border to None because iframe has a border by default.
{# backgroundposition: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: -1;
border: none;
pointer-events: none;
}
Copy the code
The renderings are as follows
Source: translation threejsfundamentals.org/threejs/les…
Write in the last
This article introduces the content related to screenshot of three. js. Screenshot is a very common requirement in daily work. I hope it will be helpful to you.
This article is published from the cloud Map 3D big front end team, the article is not authorized to be reproduced in any form.