- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
如何根据容器计算 Canvas 大小?避免滚动。
如果我根据窗口设置大小,则 Canvas 太大。
最佳答案
可以说,调整three.js 大小的最佳方法是对其进行编码,因此它只接受CSS 设置的 Canvas 大小。这样,无论您如何使用 Canvas ,您的代码都可以正常工作,无需针对不同情况进行更改。
首先,在设置初始纵横比时,没有理由设置它,因为我们将根据 Canvas 的大小进行设置,因此设置两次只是浪费代码
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
然后我们需要一些代码来调整 Canvas 的大小以匹配它的显示大小
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
// look up the size the canvas is being displayed
const width = canvas.clientWidth;
const height = canvas.clientHeight;
// adjust displayBuffer size to match
if (canvas.width !== width || canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// update any render target sizes here
}
}
在渲染之前在渲染循环中调用它
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
这里有 3 个示例,这 3 个示例之间的唯一区别是 CSS 以及我们制作 Canvas 还是 three.js 制作 Canvas
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
"use strict";
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector(".diagram canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
body { font-size: x-large; }
.diagram { width: 150px; height: 150px; float: left; margin: 1em; }
canvas { width: 100%; height: 100%; }
<p>
Pretend this is a diagram in a physics lesson and it's inline. Notice we didn't have to change the code to handle this case.
<span class="diagram"><canvas></canvas></span>
The same code that handles fullscreen handles this case as well. The only difference is the CSS and how we look up the canvas. Otherwise it just works. We didn't have to change the code because we cooperated with the browser instead of fighting it.
</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body { margin: 0; }
.outer {
}
.frame {
display: flex;
width: 100vw;
height: 100vh;
}
.frame>* {
flex: 1 1 50%;
}
#editor {
font-family: monospace;
padding: .5em;
background: #444;
color: white;
}
canvas {
width: 100%;
height: 100%;
}
<div class="frame">
<div id="result">
<canvas></canvas>
</div>
<div id="editor">
explaintion of example on left or the code for it would go here
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
window.innerWidth
和
window.innerHeight
上面的代码中从未引用过,但它适用于所有情况。
window.addEventListener('resize', ...)
但没有注意到它不处理 Canvas 改变大小但窗口本身不改变的情况(上面的示例 4)。
ResizeObserver
而不是
window.addEventListener('resize', ...)
对于那些认为每帧检查 2 个变量是性能开销的人。
ResizeObserver
当 Canvas 改变大小时会触发,即使窗口本身没有改变大小。
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
// look up the size the canvas is being displayed
const width = canvas.clientWidth;
const height = canvas.clientHeight;
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// update any render target sizes here
}
const resizeObserver = new ResizeObserver(resizeCanvasToDisplaySize);
resizeObserver.observe(canvas, {box: 'content-box'});
示例 1:全屏,我们制作 Canvas
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/build/three.module.js';
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
function animate(time) {
time *= 0.001; // seconds
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
const resizeObserver = new ResizeObserver(resizeCanvasToDisplaySize);
resizeObserver.observe(renderer.domElement, {box: 'content-box'});
</script>
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body { margin: 0; }
.outer {
}
.frame {
display: flex;
width: 100vw;
height: 100vh;
}
.frame>* {
flex: 1 1 50%;
}
#ui {
position: absolute;
right: 0;
bottom: 0;
padding: 0.5em;
}
#editor {
font-family: monospace;
padding: .5em;
background: #444;
color: white;
}
canvas {
width: 100%;
height: 100%;
}
<div class="frame">
<div id="result">
<canvas></canvas>
</div>
<div id="editor">
<p>no window resize</p>
<p>For example level editor might have the level
displayed on the left and a control panel on the right.</p>
<p>Click the buttons below. The only thing changing is CSS. The window size is not changing so using <code>window.addEventListener('resize', ...)</code> would fail</p>
<div id="ui">
<button type="button" data-size="25%">small</button>
<button type="button" data-size="50%">medium</button>
<button type="button" data-size="75%">large</button>
</div>
</div>
</div>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/build/three.module.js';
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
function animate(time) {
time *= 0.001; // seconds
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
const editorElem = document.querySelector("#editor");
document.querySelectorAll('button').forEach(elem => {
elem.addEventListener('click', () => {
editorElem.style.flexBasis = elem.dataset.size;
});
});
const resizeObserver = new ResizeObserver(resizeCanvasToDisplaySize);
resizeObserver.observe(renderer.domElement, {box: 'content-box'});
</script>
ResizeObserver
?
ResizeObserver
只是说它最终会给你一个事件。在您的内容实际需要调整大小之后,这可能会出现 5-10 帧。关于javascript - Threejs Canvas 大小基于容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29884485/
我们想要创建一个 3D 鞋子设计工具,您可以在其中设计图案并将其上传到鞋子上。 我正在尝试将图像放置在 Threejs Material 上。我可以更新 map ,但纹理很模糊。我是 Threejs
我正在尝试在 ThreeJS 中加载 FBX 模型。如果我加载模型,它只会从底部显示,而不是从顶部显示。似乎只渲染了一侧。 有没有人想解决这个问题? 我的加载函数: _LoadAnimatedMode
使用 Three.js,(虽然我相信这与数学更相关)我有一组可以创建二维几何体的二维点。例如正方形、矩形、五边形或自定义 2D 形状。基于原始的 2D 形状,我想创建一种方法来像附图那样均匀地向内或向
我正在尝试创建一个在所有方面都镜像的对象。它几乎可以正常工作,但我不确定我在这里做错了什么。我只能看到某些 Angular 部分反射,并且反射的范围比被反射的物体(大象)大得多。这是代码:
无论导入场景,还是通过代码创建每个网格和灯光,都会出现以下问题。 我的场景由一个平面、一个立方体和一个聚光灯组成。聚光灯在 y 轴上旋转 45 度。在示例 1 中,它位于点 (4, 0, 4)。在示例
上下文: 我正在开发一个非常简单的 THREE.JS 项目,我相信它已经以非常好的方式进行了优化。我正在使用 WebGLRenderer 来显示每 50 毫秒从音频信号中提取的大量波特图。这非常酷,但
我正在编写一个全景查看器。图像显示在具有可变数量面的球体中。我希望它只在相机方向渲染脸部(以获得更好的性能)。 ThreeJS 会自动执行此操作吗?或者我可以声明不渲染的混搭的特定面吗? 像mash.
我使用十六进制值设置几何颜色 RichGeometry.prototype = new THREE.Geometry(); RichGeometry.prototype.constructor = R
因此,我查看了此处的所有其他影子问题,但似乎没有一个与我的相关,或者我只是忽略了它大约 10 次。 https://gist.github.com/Sinistralis/58249d2f9aefa8
所以我有一个 ThreeJS 场景,并且添加了一些球体(多 Material )。我还添加了定向光: this.light = new THREE.DirectionalLight( 0xFFFFFF
我在“two.js”中创建了一个立方体,但我想创建同一个立方体 3 次,然后将它们作为目标,以便可以使用“Tweenmax”单独对它们进行动画处理 我是 Three.js 的新手,因此我们将不胜感激
我想要实现的是让特定的网格体向特定的向量移动,直到它最终被玩家停止。 到目前为止,我已经成功获取了单击 Canvas 的 XY 坐标,并使用以下代码将它们投影到 3D 中。不幸的是,我不确定采取什么方
我遇到了 Object3D 组中的面上未接收到阴影的问题。 阴影从物体转换并被地面接收,但阴影在应该被接收的时候却没有被彼此接收。 我四处搜寻,但似乎找不到类似的问题,这让我相信我的设置不正确。 有人
我正在尝试为我的类(class)创建一个场景,其中必须克隆一组对象(模型)并将其显示在随机位置。我为此创建了一个函数,但不幸的是,它只能将同一个对象从一个地方传输到另一个地方。我需要添加更多对象而不是
我正在尝试动态更改选定顶点的颜色。引用https://jsfiddle.net/pmankar/m70cpxes/ ,我创建了一个二十面体几何点云几何体,并且在单击事件时我想更改顶点 100 的颜色。
我已将球体添加到场景中,并在场景中添加了一些平面几何图形,当我放大时,我希望平面几何图形看起来更小,当我缩小时,平面几何图形应该显得更大,我不知道如何解决这个问题有人可以帮我解决这个问题吗? 最佳答案
我开始学习使用 Threejs 创建旋转 3D 立方体。我关注了this教程,但为对象的旋转设置动画不起作用。 在此之前,我收到旋转未定义的错误。我在 animate() 中使用以下代码解决了这个问题
当我执行某些几何体的渲染时,我可以在控制台中看到此警告: THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter sho
您好,我有一个疑问: 我已经实现了光线投射器,并且已经进行了手动测试,但是我不知道为什么在3D模型上进行的大多数点击都没有得到交点。 首先,我将向您展示我单击的点,然后向您显示在Web控制台中记录的点
您好,我有一个疑问: 我研究过: https://threejs.org/docs/#api/materials/PointsMaterial 我已经调整了该示例以与我现有的代码一起使用。 目的是在我
我是一名优秀的程序员,十分优秀!