basic3文档
本帖最后由 马黑黑 于 2025-6-15 08:35 编辑 <br /><br /><style>.artBox { font-size: 18px; }
.artBox > p { margin: 10px 0; line-height: 30px; }
.artBox mark { padding: 4px 6px; background: lightblue; }
#prevBox { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: #eee; display: none; padding: 0; overflow: hidden; z-index: 1000; margin: 0; }
#prevBox::after { position: absolute; content: '关闭预览'; bottom: 10px; left: calc(50% - 40px); padding: 0 4px; width: 80px; height: 30px; line-height: 30px; text-align: center; border: 1px solid #efe; border-radius: 6px; background: #eee; font-size: 14px; box-shadow: 2px 2px 6px rgba(0,0,0,.25); cursor: pointer; }
iframe { position: relative; width: 100%; height: 100%; border: none; outline: none; box-sizing: border-box; margin: 0; }
</style>
<div id="prevBox"></div>
<div class="artBox">
<p>basic3 是基于 ThreeJS 核心库进行简单封装的 ES6 模块,旨在减少前台导入 ThreeJS 核心库以及做各类准备和相关处理等工作。下面是使用方法:</p>
<h2>一、导入 basic3 模块</h2>
<div class="hEdiv"><pre class="hEpre">import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';</pre></div>
<p>花括号中,前面 5 个变量是 ThreeJS 基础变量,其中 THREE 是 ThreeJS 核心类,scene 是场景,camera 是相机,renderer 是渲染器,clock 是时钟。这些都是绘制 ThreeJS 图像的基本变量,需要一一声明、定义,basic3 已经将它们封装好、开箱即用;后面的 basic3 和 click3 是函数,后续说明。</p>
<h2>二、启动 basic3</h2>
<p>即运行<mark> basic3() </mark>函数,该函数是 3basic.js 模块的主函数,需要一个参数,该参数为装载 ThreeJS 图像的父元素,例如 document.body 或 id="papa" 的 div 不要引号的 id 标识符: </p>
<div class="hEdiv"><pre class="hEpre">
basic3(); // 参数缺省,这将使用 document.body 作为 ThreeJS 图像的父元素
// 或
basic3(papa); // 使用 id="papa" 的 div 标签作为 ThreeJS 图像的父元素
</pre></div>
<p>上面两种启动 basic3 方法根据需要二选其一。</p>
<p>basic3 封装的相机是常用的透视相机,参数 fov(相机视锥体竖直方向视野角度)设为 60,position(位置)设为 (0, 0, 5),可以在使用时更改,例如,在启动 basic3 之后加入代码:</p>
<div class="hEdiv"><pre class="hEpre">
camera.fov = 45; // 视野角度
camera.updateProjectionMatrix(); // 更新相机投影矩阵
//修改相机位置可以直接修改,无需更新相机投影矩阵
camera.position.set(0, 1, 5); // 修改相机位置
</pre></div>
<h2>三、绘制 ThreeJS 图像</h2>
<p>下面给出一个完整的代码示例,它将绘制一个包含可控动画的立方体:</p>
<div class="hEdiv"><pre class="hEpre" id="preCode">
<style>
#papa { margin: auto; width: 1000px; height: 600px; background: beige; position: relative; }
</style>
<div id='papa'></div>
<script type="module">
// 导入 basic3
import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
basic3(papa); // 启动 basic3
// 绘制立方体
const cube = new THREE.Mesh(
new THREE.BoxGeometry(),
new THREE.MeshNormalMaterial()
);
cube.rotateX(Math.PI / 4)
scene.add(cube);
// 立方体动画
const animate = () => {
requestAnimationFrame(animate);
const delta = clock.getDelta();
cube.rotation.y += delta;
renderer.render(scene, camera);
};
animate(); // 运行动画
// 交互 :鼠标点击
papa.onclick = (e) => {
// click3(cube, e) 判断是否点击了cube,下同
if (click3(cube, e)) clock.running ? clock.stop() : clock.start();
}
// 交互 :鼠标经过
papa.onmousemove = (e) => {
papa.title = click3(cube, e) ? '播放/暂停' : '';
papa.style.cursor = click3(cube, e) ? 'pointer' : 'default';
}
</script>
</pre></div>
<blockquote><button id="btnPrev">运行代码</button></blockquote>
<p>函数 <mark>click3(图像, e) </mark>用于判断鼠标指针是否在图像内,支持多个图形参数,例如,假设还绘制了一个 ball,可以使用数组方式构建图像参数,<mark> </mark>,写成 <mark>click3(, e); </mark>。</p>
<h2>四、使用 ThreeJS 扩展库</h2>
<p>由于路径结构的限制,basic3 模块仅封装了 ThreeJS 核心库,要使用 ThreeJS 自带的扩展库,需要在 HTML 页面自行映射扩展库的路径并导入对应扩展库。以导入相机轨道扩展库为例,下面的代码演示其操作流程:</p>
<div class="hEdiv"><pre class="hEpre">
<!-- ThreeJS库文档目录结构映射 -->
<script type="importmap">
{
"imports": {
"three": "https://638183.freep.cn/638183/3dev/build/three.module.min.js",
"three/addons/jsm/": "https://638183.freep.cn/638183/3dev/examples/jsm/"
}
}
</script>
<script type="module">
// 导入 basic3 模块
import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
import { OrbitControls } from 'three/addons/jsm/controls/OrbitControls.js'; // 导入相机轨道扩展库
basic3(papa); // 启动 basic3(假设 ThreeJS 图像的父元素为 id="papa" 的 div)
const controls = new OrbitControls(camera, renderer.domElement); // 实例化轨道控制器
//...其它代码
</script>
</pre></div>
<p>如此,前面绘制的立方体就可以进行手动翻转等操作。</p>
<p>basic3 模块将来可能会有一些扩展,若此,届时会追加说明。</p>
</div>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
const pres = document.querySelectorAll('.hEpre');
const divs = document.querySelectorAll('.hEdiv');
divs.forEach( (div, key) => hlight.hl(div, pres));
const preView = (htmlCode, targetBox) => {
if (targetBox.innerHTML) return;
const iframe = document.createElement('iframe');
htmlCode = htmlCode + '<style>body {margin: 0; }</style>';
iframe.srcdoc = htmlCode;
targetBox.appendChild(iframe);
targetBox.style.display = 'block';
targetBox.onclick = () => {
targetBox.innerHTML = '';
targetBox.style.display = 'none';
}
};
const value = preCode.textContent;
btnPrev.onclick = () => preView(value, prevBox);
</script> 讲的真好,谢谢马老师经典分享{:4_191:} 杨帆 发表于 2025-6-15 00:09
讲的真好,谢谢马老师经典分享
{:4_191:} 导入 basic3 后,就不需要去一一声明和定义ThreeJS 的基础变量了,这样的封装带来便利{:4_187:} “函数 click3(图像, e) 用于判断鼠标指针是否在图像内,支持多个图形参数”
这个是ThreeJS 特有的还是所有的js都是这样{:4_204:} {:5_116:} 樵歌 发表于 2025-6-15 13:49
谢赞 红影 发表于 2025-6-15 13:17
“函数 click3(图像, e) 用于判断鼠标指针是否在图像内,支持多个图形参数”
这个是ThreeJS 特有的还是所 ...
click3() 是自己编写的basic3模块辅助函数,利用 ThreeJS Raycast 类检测鼠标指针是否在指定图像的上方。最初设计为直接点击操作,所以命名为 click3,其实应该命名为 inMesh 或其它类似的语义化命名方式。
JS有很多很多的东东,这些东东如果综合灵活运用,它们就可以帮你制作强大的东东,小到一个自定义函数,大到一个框架。ThreeJS就是利用JS的这些能耐创建出来的。
之前讲过,和svg不同,canvas绘制出来的对象不能像HTML元素那样可以去随意操纵,比如点击操作一个SVG元素是容易的,但是点击canvas画布上的图像JS只知道是点击了画布,要知道是不是点击了指定图像需要去计算,用canvas制作图像时可以做一些准备工作去俘获指定对象的位置,这样就可以通过计算判断点击点是不是在这个指定对象上面。ThreeJS 的 Raycast 射线类能提供相机射线与图像是否相交,鼠标指针点击的点如果在射线和图像相交点集合上,那就是点击了指定对象。 红影 发表于 2025-6-15 13:15
导入 basic3 后,就不需要去一一声明和定义ThreeJS 的基础变量了,这样的封装带来便利
这个封装多多少少减轻一点用ThreeJS做帖的工作量 本帖最后由 花飞飞 于 2025-6-15 17:49 编辑
启动basic3之后就直接绘制立方体了,做贴用好方便的
看到中间关于相机的那三个参数camera.fov封在里面了,
但需的更改立方体大小 和位置时候又可以灵活使用,
又做到了简洁加灵活。。
{:4_199:}
马黑黑 发表于 2025-6-15 17:04
click3() 是自己编写的basic3模块辅助函数,利用 ThreeJS Raycast 类检测鼠标指针是否在指定图像的上方。 ...
看来这个函数只能跟basic3配套使用。
Raycast 射线类能提供相机射线与图像是否相交,感觉射线范围会大于图像,图像应该都是相交点集合。
之前那些扩展库也适用,功能是一点没少。。{:4_173:} 花飞飞 发表于 2025-6-15 17:43
启动basic3之后就直接绘制立方体了,做贴用好方便的
看到中间关于相机的那三个参数camera.fov封在里面了 ...
简单封装,十来分钟就弄好,测试呢多花了点时间 花飞飞 发表于 2025-6-15 17:55
看来这个函数只能跟basic3配套使用。
Raycast 射线类能提供相机射线与图像是否相交,感觉射线范围会大于 ...
这个不是很精准的,大概 花飞飞 发表于 2025-6-15 18:02
之前那些扩展库也适用,功能是一点没少。。
只要按说明添加即可 马黑黑 发表于 2025-6-15 19:02
只要按说明添加即可
{:4_173:} 好哒。。。跟加醋加味精一样 马黑黑 发表于 2025-6-15 19:01
这个不是很精准的,大概
设计这个的思路很妙{:4_187:} 马黑黑 发表于 2025-6-15 19:00
简单封装,十来分钟就弄好,测试呢多花了点时间
十来分钟就封好了。。你就是黑神{:4_173:}
测试是指范例效果对吧 花飞飞 发表于 2025-6-15 19:27
十来分钟就封好了。。你就是黑神
测试是指范例效果对吧
测试是多层面的,主要测试封装的东东的适应性 花飞飞 发表于 2025-6-15 19:26
设计这个的思路很妙
ThreeJS提供有具体代码,二次开发者只要按规范和需求使用即可