如何实现three.js响应式设计(消除拉伸变形和锯齿)
我们先创建一个基本的three.js场景,里面有一个cube对象。
分三步,首先声明一个canvas的html元素并设置其样式:
<canvas id="c"></canvas>
#c { width: 100%; height: 100%; display: block; }
第二步,使用three.js创建场景、光照、相机和立方体模型(cube):
import * as THREE from '//techbrood.com/threejs/build/three.module.js'; function main() { const canvas = document.querySelector('#c'); const renderer = new THREE.WebGLRenderer({canvas}); const fov = 75; const aspect = 2; // the canvas default const near = 0.1; const far = 5; const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); camera.position.z = 2; const scene = new THREE.Scene(); { const color = 0xFFFFFF; const intensity = 1; const light = new THREE.DirectionalLight(color, intensity); light.position.set(-1, 2, 4); scene.add(light); } const boxWidth = 1; const boxHeight = 1; const boxDepth = 1; const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth); function makeInstance(geometry, color, x) { const material = new THREE.MeshPhongMaterial({color}); const cube = new THREE.Mesh(geometry, material); scene.add(cube); cube.position.x = x; return cube; } var cube = makeInstance(geometry, 0x44aa88, 0), //TODO: render the scene }
第三步,循环渲染该场景:
function render(time) { time *= 0.001; const speed = 1; const rot = time * speed; cube.rotation.x = rot; cube.rotation.y = rot; renderer.render(scene, camera); requestAnimationFrame(render); } requestAnimationFrame(render);
这样一个基本的3D场景就创建好了,其运行效果是一个旋转的立方体。
但是当我们调整网页大小时,会发现有2个问题:
立方体会发生拉伸变形,变成了长方体
立方体的边缘会出现明显的锯齿
要解决第1个问题,需要按照canvas的大小来调整camera的aspect和投影矩阵:
const canvas = renderer.domElement; camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix();
要解决第2个问题,我们得明白canvas元素有2个尺寸,一个是页面上呈现出来的尺寸(可以通过css来设置的样式),一个是canvas本身的像素值(分辨率),这和一般的图像元素类似。解决的方法也和防止图像拉伸一样,我们需要使显示尺寸和分辨率这两者匹配起来。
function resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement; const width = canvas.clientWidth; const height = canvas.clientHeight; const needResize = canvas.width !== width || canvas.height !== height; if (needResize) { renderer.setSize(width, height, false); } return needResize; }
这样我们就实现了3D场景的响应式设计。
可以在线查看实现效果:https://wow.techbrood.com/fiddle/54855
- 相关文章
微信公众号在线生成二维码带参数怎么搞?
带参数二维码是微信公众号渠道二维码的一种实现
微信的带参数二维码有两种,一种是临时二维码,一种是永久二维码,但是永久二维码的生成是有个数限制的,微...3D感知和建模关键硬件技术:双目、3D结构光和TOF
无论VR、AR和3D打印,其核心技术包含3D成像和建模。而3D建模属于劳动密集型的工作,耗时耗力,凡这类工作都会是被新技术革命的地方,自动3D建模技术就是为了解决...
Monaco Editor 编辑器拷贝粘贴功能调用和获取选中文本
有时候需要在monaco editor外部调用编辑器的内置功能比如希望在页面主工具栏实现一些快捷操作。button
踏得网精选2016年度10大最佳HTML5动画
踏得网精选2016年度最酷最新的HTML5动画集,评选标准为:创意新颖度+实现技术难度+趣味程度。使用一些在线H5生成工具的作品,因其主要使用图片和CSS3套路动画,...
CSS3特性查询(Feature Query: @supports)功能简介
这是2017年不能不了解和学习的一个CSS新特性,非常实用,考虑到现实世界浏览器的复杂性,该特性本应该先于其他新特性出来。我们已经知道使用媒体查询(Media Que...
函数式JavaScript编程基础概念:Curry和Partial Application
本文介绍JS函数式编程中的两个概念:柯里(Curry)和部分应用程序(Partial Application)。什么是应用程序(Application)将函数应用于其参数以产生返回值的过...
CSS3弹性布局内容对齐(justify-content)属性使用详解
内容对齐(justify-content)属性应用在弹性容器上,把弹性项沿着弹性容器的主轴线(main axis)对齐。该操作发生在弹性长度以及自动边距被确定后。 它用来在存...
CSS3弹性布局弹性流(flex-flow)属性详解和实例
弹性布局是CSS3引入的强大的布局方式,用来替代以前Web开发人员使用的一些复杂而易错hacks方法(如使用float进行类似流式布局)。其中flex-flow是flex-direction...
通过实例深入理解HTML5/CSS3/SVG/WebGL的技术本质
使用HTML5 FileReader和Canvas压缩用户上传的图片
手机用户拍的照片通常会有2M以上,这对服务器带宽产生较大压力。因此在某些应用下(对图片要求不那么高)我们可以在客户端来压缩图片,然后再提交给服务器。总体...
HTML5、Hybrid APP、Native APP对比和技术选型
HTML5和Native APP都很容易理解。为了获得HTML5的移植性和移动本地应用的高性能,搞出来一些混合APP的解决方案。比如Apache的Cordova(也就是以前的PhoneGap),...
浏览器控制台报JS脚本执行错误:Module is not defined
现在JS分成了两个分支,一部分在服务器端发展如NodeJS,一部分是传统的浏览器运行环境。
有些插件在编写JS代码时,是针对Node编写的,所以直接在浏览器中使...如何基于Canvas来模拟真实雨景Part2:重力掉落和雨滴融合
如何使用CSS3实现一个平滑的3D文本标题
要实现3D文本,基本上有3种方法:1. 使用CSS3的投影滤镜(filter: drop-shadow)2. 使用3d建模和CSS3 3d变换来实现(最真实)3. 使用CSS3 text-shadow属性来实现...
更多...