用虚拟机做网站的心得体会,北京网讯百度科技有限公司,网站建设系统下载,南昌地宝网二手车出售信息不经意间看到了某个大佬做的网站~ 实在是太帅啦#xff01; 查了查实现该效果的技术 —— 原来是Three.js 如果你也感兴趣的话#xff0c;那就让我们来从零开始学习Three.js动态3D效果吧✨ 一、了解
Three.js是基于原生WebGL封装运行的三维引擎#xff0c;在所有WebGL引擎中… 不经意间看到了某个大佬做的网站~ 实在是太帅啦 查了查实现该效果的技术 —— 原来是Three.js 如果你也感兴趣的话那就让我们来从零开始学习Three.js动态3D效果吧✨ 一、了解
Three.js是基于原生WebGL封装运行的三维引擎在所有WebGL引擎中Three.js是国内文资料最多、使用最广泛的三维引擎。
Threejs是一款WebGL三维引擎它可以用来做许多许多地场景应用
示例 那么不热爱前端的你是否会因为这张图片而热爱呢 没错这张图片就是用Three.js框架实现的。 二、安装 本教程采用的安装方法是第一种所以需要大家将Three.js文件下载到本地添加到自己的项目中。 1.本地安装 创建Three.Js文件夹 创建index.html文件 创建js文件夹 将下载的three.js包放入js文件夹中 百度网盘链接 链接 https://pan.baidu.com/s/1pSA-txD1hA7SknK0_htTvg?pwdcad6 提取码cad6 网盘里有Three.js文件大家可以直接使用如果大家想使用Three.js框架的其他模块可自行去GitHub上下载地址在下面 官方GitHub地址: https://github.com/mrdoob/three.js/tree/master 2.使用 NPM 和构建工具进行安装 注这种方法对新手十分不友好新手建议使用第一种方法 由于项目需要的依赖越多就越有可能遇到静态托管无法轻易解决的问题。而使用构建工具导入本地 JavaScript 文件和 npm 软件包将会解决问题无需导入映射import maps。
安装 Node.js。我们需要它来管理依赖项和运行构建工具。在项目文件夹中通过 终端 安装 three.js 和构建工具 Vite。Vite将在开发过程中使用但不会被打包成为最终网页的一部分。当然除了 Vite 你也可以使用其他支持导入 ES Modules的现代构建工具。
# three.js
npm install --save three# vite
npm install --save-dev vite在终端运行
npx vite4.如果一切顺利你会在终端中看到一个类似 http://localhost:5173 的 URL打开该 URL 就能看到你的网络应用程序。
之后当你准备部署网络应用程序时只需要让 Vite 运行生产构建 - npx vite build。应用程序使用的所有内容都将被编译、优化并复制到 dist/ 文件夹中。该文件夹中的内容就可以托管到你的网站上了。
3.从CDN导入
在 index.html 中我们需要添加一个导入映射import map来定义从哪里获取软件包。将下面的代码放在 head/head 标签内、样式styles之后。
script typeimportmap{imports: {three: https://cdn.jsdelivr.net/npm/threeversion/build/three.module.js,three/addons/: https://cdn.jsdelivr.net/npm/threeversion/examples/jsm/}}
/script不要忘记将上述链接中的 替换为 three.js 的实际版本如 “v0.149.0”。最新版本可在 npm 版本列表中找到。
三、基础教程 这一部分将对 three.js 来做一个简要的介绍我们将开始搭建一个场景其中包含一个正在旋转的立方体。 创建一个场景
为了真正能够让你的场景借助 three.js 来进行显示我们需要以下几个对象场景scene、相机camera和渲染器renderer这样我们就能透过摄像机渲染出场景。
const scene new THREE.Scene();
const camera new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );const renderer new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );上面是一段js代码在上面的代码中我们建立了场景、相机和渲染器。
three.js 里有几种不同的相机在这里我们使用的是 PerspectiveCamera透视摄像机。
第一个参数是视野角度FOV。视野角度就是无论在什么时候你所能在显示器上看到的场景的范围它的单位是角度(与弧度区分开)。
第二个参数是长宽比aspect ratio。 也就是你用一个物体的宽除以它的高的值。比如说当你在一个宽屏电视上播放老电影时可以看到图像仿佛是被压扁的。
接下来的两个参数是近截面near和远截面far。 当物体某些部分比摄像机的远截面远或者比近截面近的时候这些部分将不会被渲染到场景中。或许现在你不用担心这个值的影响但未来为了获得更好的渲染性能你将可以在你的应用程序里去设置它。
接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的 WebGLRenderer 渲染器之外Three.js 同时提供了其他几种渲染器。
除了创建一个渲染器的实例之外我们还需要在我们的应用程序里设置一个渲染器的尺寸。比如说我们可以使用所需要的渲染区域的宽高来让渲染器渲染出的场景填充满我们的应用程序。因此我们可以将渲染器宽高设置为浏览器窗口宽高。
如果你希望保持你的应用程序的尺寸但是以较低的分辨率来渲染你可以在调用 setSize 时将 updateStyle第三个参数设为 false。例如假设你的 canvas 标签现在已经具有了 100% 的宽和高调用 setSize(window.innerWidth/2, window.innerHeight/2, false) 将使得你的应用程序以四分之一的大小来进行渲染。
最后一步很重要我们将 renderer渲染器的dom元素renderer.domElement添加到我们的 HTML 文档中。这就是渲染器用来显示场景给我们看的 canvas 元素。
“嗯看起来很不错那你说的那个立方体在哪儿”
接下来我们就来添加立方体。
const geometry new THREE.BoxGeometry( 1, 1, 1 );
const material new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube new THREE.Mesh( geometry, material );
scene.add( cube );camera.position.z 5;要创建一个立方体我们需要一个 BoxGeometry立方体对象. 这个对象包含了一个立方体中所有的顶点vertices和面faces。
接下来对于这个立方体我们需要给它一个材质来让它有颜色。Three.js 自带了几种材质在这里我们使用的是 MeshBasicMaterial。所有的材质都存有应用于他们的属性的对象。在这里为了简单起见我们只设置一个color属性值为 0x00ff00也就是绿色。这里所做的事情和在 CSS 或者 Photoshop 中使用十六进制hex colors颜色格式来设置颜色的方式一致。
第三步我们需要一个 Mesh网格。 网格包含一个几何体以及作用在此几何体上的材质我们可以直接将网格对象放入到我们的场景中并让它在场景中自由移动。
默认情况下当我们调用 scene.add() 的时候物体将会被添加到 (0,0,0) 坐标。但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生我们只需要将摄像机稍微向外移动一些即可。
渲染场景
现在如果将之前写好的代码复制到HTML文件中你不会在页面中看到任何东西。这是因为我们还没有对它进行真正的渲染。为此我们需要使用一个被叫做“**渲染循环”render loop**或者“动画循环”animate loop的东西。
function animate() {requestAnimationFrame( animate );renderer.render( scene, camera );
}
animate();在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环在大多数屏幕上刷新率一般是60次/秒。
使立方体动起来
在开始之前如果你已经将上面的代码写入到了你所创建的文件中你可以看到一个绿色的方块。让我们来做一些更加有趣的事 —— 让它旋转起来。
将下列代码添加到 animate() 函数中 renderer.render 调用的上方
cube.rotation.x 0.01;
cube.rotation.y 0.01;这段代码每帧都会执行正常情况下是60次/秒这就让立方体有了一个看起来很不错的旋转动画。基本上来说当应用程序运行时如果你想要移动或者改变任何场景中的东西都必须要经过这个动画循环。
结果
祝贺你你现在已经成功完成了你的第一个 three.js 应用程序。
!DOCTYPE html
html langenheadmeta charsetutf-8titleMy first three.js app/titlescript srcjs/three.js/scriptstylebody {margin: 0;}/style/headbodyscriptconst scene new THREE.Scene();const camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);const renderer new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);const geometry new THREE.BoxGeometry(1, 1, 1);const material new THREE.MeshBasicMaterial({color: 0x00ff00});const cube new THREE.Mesh(geometry, material);scene.add(cube);camera.position.z 5;function animate() {requestAnimationFrame(animate);cube.rotation.x 0.01;cube.rotation.y 0.01;renderer.render(scene, camera);}animate();/script/body
/html四、其他示例
示例1
!DOCTYPE html
htmlheadmeta charsetutf-8title/titlescript srcjs/three.js/scriptstyle typetext/cssbody {background-color: #222;}canvas {width: 100%;height: 100%;}/style/headbody/bodyscript typetext/javascriptvar scene new THREE.Scene();var camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);var renderer new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);var spotLight new THREE.SpotLight(0xffffff);spotLight.position.set(100, 100, 100);spotLight.castShadow true; spotLight.shadowMapWidth 1024;spotLight.shadowMapHeight 1024;spotLight.shadowCameraNear 500;spotLight.shadowCameraFar 4000;spotLight.shadowCameraFov 30;scene.add(spotLight);function Mat() {var material new THREE.MeshPhongMaterial({color: new THREE.Color(rgb(35,35,213)),emissive: new THREE.Color(rgb(64,128,255)),specular: new THREE.Color(rgb(93,195,255)),shininess: 1,shading: THREE.FlatShading,wireframe: 1,transparent: 1,opacity: 0.15});return material;}var geometry new THREE.SphereGeometry(50, 20, 20, 0, Math.PI * 2, 0, Math.PI);var earth new THREE.Mesh(geometry, Mat());scene.add(earth);camera.position.z 90;function render() {requestAnimationFrame(render);earth.rotation.x 0.01;earth.rotation.y 0.01;renderer.render(scene, camera);}render();/script
/html示例二JavaScript编写
!DOCTYPE html
htmlheadmeta charsetutf-8title/title/headbody/bodyscript typetext/javascriptuse strict; const body document.getElementsByTagName(body).item(0);body.style.background #000;const TP 2 * Math.PI;const CSIZE 400;const ctx (() {let d document.createElement(div);d.style.textAlign center;body.append(d);let c document.createElement(canvas);c.width c.height 2 * CSIZE;d.append(c);return c.getContext(2d);})();ctx.translate(CSIZE, CSIZE);ctx.lineCap round;onresize () {let D Math.min(window.innerWidth, window.innerHeight) - 40;ctx.canvas.style.width ctx.canvas.style.height D px;}const getRandomInt (min, max, low) {if (low) return Math.floor(Math.random() * Math.random() * (max - min)) min;else return Math.floor(Math.random() * (max - min)) min;}function Color() {const CBASE 144;const CT 255 - CBASE;this.getRGB (ct) {let red Math.round(CBASE CT * (Math.cos(this.RK2 ct / this.RK1)));let grn Math.round(CBASE CT * (Math.cos(this.GK2 ct / this.GK1)));let blu Math.round(CBASE CT * (Math.cos(this.BK2 ct / this.BK1)));return rgb( red , grn , blu );}this.randomize () {this.RK1 360 360 * Math.random();this.GK1 360 360 * Math.random();this.BK1 360 360 * Math.random();this.RK2 TP * Math.random();this.GK2 TP * Math.random();this.BK2 TP * Math.random();}this.randomize();}var color new Color();var stopped true;var start () {if (stopped) {stopped false;requestAnimationFrame(animate);} else {stopped true;}}body.addEventListener(click, start, false);var dur 2000;var tt getRandomInt(0, 1000);var pause 0;var trans false;var animate (ts) {if (stopped) return;tt;draw();requestAnimationFrame(animate);}var KF Math.random();var Circle function() {this.dir false;this.r 80;this.randomize () {this.ka 0; //TP*Math.random();this.ka2 200;}this.randomize();this.setRA () {this.a2 TP / 4 1.57 * (1 Math.sin(tt / this.ka2)) / 2;if (this.dir) this.a2 -this.a2;}this.setPath2 () {if (this.p) {if (this.cont) {this.a TP / 2 this.p.a - this.p.a2;this.x this.p.x (this.p.r - this.r) * Math.cos(this.p.a - this.p.a2);this.y this.p.y (this.p.r - this.r) * Math.sin(this.p.a - this.p.a2);} else {this.a this.p.a - this.p.a2;this.x this.p.x (this.p.r this.r) * Math.cos(this.p.a - this.p.a2);this.y this.p.y (this.p.r this.r) * Math.sin(this.p.a - this.p.a2);}} else {this.x this.r * Math.cos(this.a);this.y this.r * Math.sin(this.a);}this.path new Path2D();this.path.arc(this.x, this.y, this.r, TP / 2 this.a, this.a - this.a2, this.dir);}}onresize();var ca [];var reset () {ca [new Circle()];ca[0].p false;ca[0].a 0; //TP*Math.random();ca[0].setRA();ca[0].x ca[0].r * Math.cos(ca[0].a);ca[0].y ca[0].r * Math.sin(ca[0].a);}reset();var addCircle (c) {let c2 new Circle();c2.a c.a - c.a2;c2.dir !c.dir;c2.p c;c2.cont false;c2.r c.r * 0.8;if (Math.random() KF)c2.ka2 c.ka2 * 0.8;ca.push(c2);let c3 new Circle();c3.a TP / 2 c.a - c.a2;c3.dir c.dir;c3.p c;c3.cont true;c3.r c.r * 0.8;if (Math.random() 1 - KF)c3.ka2 c.ka2 * 0.8;ca.push(c3);}const dmx new DOMMatrix([-1, 0, 0, 1, 0, 0]);const dmy new DOMMatrix([1, 0, 0, -1, 0, 0]);const dmxy new DOMMatrix([-1, 0, 0, -1, 0, 0]);//const dmqnew DOMMatrix([0,1,-1,0,0,0]);const getXYPath (spath) {this.level 1;let p new Path2D(spath);p.addPath(p, dmxy);return p;}var draw () {ca[0].a tt / 1000;for (let i 0; i ca.length; i) ca[i].setRA();for (let i 0; i ca.length; i) ca[i].setPath2();let pa new Array(8);for (let i 0; i pa.length; i) pa[i] new Path2D();for (let i 0; i ca.length; i) {if (i 0) pa[0].addPath(ca[i].path);else if (i 3) pa[1].addPath(ca[i].path);else if (i 7) pa[2].addPath(ca[i].path);else if (i 15) pa[3].addPath(ca[i].path);else if (i 31) pa[4].addPath(ca[i].path);else if (i 63) pa[5].addPath(ca[i].path);else if (i 127) pa[6].addPath(ca[i].path);else pa[7].addPath(ca[i].path);}ctx.clearRect(-CSIZE, -CSIZE, 2 * CSIZE, 2 * CSIZE);for (let i 0; i pa.length; i) {let pth getXYPath(pa[i]);ctx.strokeStyle color.getRGB(tt - 180 * i);ctx.lineWidth Math.max(3, 24 - 3 * i);ctx.stroke(pth);}}for (let i 0; i 127; i) addCircle(ca[i]);start();/script
/html