Я собираюсь добавить еще один ответ. Я бы использовал
canvas {
width: 100vw;
height: 100vh;
display: block;
position: fixed;
top: 0;
left: 0;
z-index: -9999;
}
И вот почему:
Многие люди используют canvas { width: 100%; height: 100% }
, но это, возможно, не имеет большого смысла. Вы не хотите, чтобы холст составлял 100% тела. Вы хотите, чтобы это 100% экрана / окна. Вот что делает canvas { width: 100vw; height: 100vh; }
. Это 100% ширины области просмотра и высоты области просмотра.
Это означает, что вам не нужно устанавливать высоту тела: 100%, что также не имеет смысла, особенно если страница выше окна / экрана
display: block;
исправляет некоторые проблемы с полосами прокрутки в некоторых браузерах. Некоторые страницы используют html, body { overflow: none; }
, но опять же, это не имеет смысла, если ваша страница должна быть выше экрана / окна.
position: fixed;
устанавливает положение холста относительно верхней части окна, чтобы оно не прокручивалось вместе со страницей. Если вы используете position: absolute
, холст будет прокручиваться сверху, если страница выше экрана / окна. Например эта страница .
top: 0; left 0;
ставит его в верхнем левом углу. Без этого он по умолчанию будет иметь положение по умолчанию, которое находится внутри полей тела. Часто это решается установкой body { margin: 0; }
, но, как правило, это означает, что вам понадобится какой-то другой контейнер для добавления отступа, иначе ваш обычный контент будет расположен на краю окна.
z-index: -9999;
есть, чтобы попытаться заставить его отступить дальше, чем что-либо еще, на случай, если сама страница использует некоторые отрицательные значения для z-index
Вот пример как фрагмент
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
var canvas = document.querySelector("canvas");
var renderer = new THREE.WebGLRenderer({canvas: canvas});
renderer.setClearColor(0xF0F0F0);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
wireframe: true,
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 1;
function resize() {
var width = canvas.clientWidth;
var height = canvas.clientHeight;
if (width != canvas.width || height != canvas.height) {
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
}
}
function render(time) {
time *= 0.001;
resize();
cube.rotation.x = time;
cube.rotation.y = time * 0.31;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
canvas {
width: 100vw;
height: 100vh;
display: block;
position: fixed;
top: 0;
left: 0;
z-index: -9999;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.min.js"></script>
<canvas></canvas>
<div>
some content that is in front of the canvas
</div>
И вот пример вне SO , так что вы можете просмотреть его в полном размере.
iframe
с работы, а также
Обратите внимание, что существует проблема, заключающаяся в том, что если ваша анимация холста является интерактивной, элементы перед холстом будут поглощать события мыши / касания. Я не знаю простого решения для этого. Вы можете пометить все, кроме этого canvas / iframe, как pointer-events: none
и пометить canvas / iframe как pointer-events: auto
, но затем вы столкнетесь с проблемой, заключающейся в том, что текст на вашей странице не может быть выбран и ссылки не могут быть нажаты. Затем вы могли бы сказать, что для тегов <a>
должно быть pointer-events: auto
, чтобы ссылки работали, но я уверен, что здесь и там будут проблемы в зависимости от того, какая информация есть на вашей странице (попытка скопировать адрес электронной почты или адрес местоположения, и т.д ...)
Одно примечание: большинство примеров three.js структурированы по-разному (менее гибко), ссылаясь на window.innerWidth
и window.innerHeight
и по какой-то причине помещая холст в div с id="canvas"
.
Вот фрагмент, использующий эту структуру. Есть еще несколько строк кода, избыточные вызовы на renderer.setSize
и установка аспекта камеры в 2 местах (не очень СУХОЙ), но с точки зрения вопросов и ответов единственное отличие - #canvas
вместо canvas
в качестве CSS для размер div вместо холста.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
document.getElementById("canvas").appendChild(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xF0F0F0);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
wireframe: true,
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 1;
function onResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
window.addEventListener('resize', onResize);
function render(time) {
time *= 0.001;
cube.rotation.x = time;
cube.rotation.y = time * 0.31;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
#canvas {
width: 100vw;
height: 100vh;
display: block;
position: fixed;
top: 0;
left: 0;
z-index: -9999;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.min.js"></script>
<div id="canvas"></div>
<div>
some content that is in front of the canvas
</div>