马黑黑 发表于 2025-6-14 23:19

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">
&lt;style&gt;
        #papa { margin: auto; width: 1000px; height: 600px; background: beige; position: relative; }
&lt;/style&gt;

&lt;div id='papa'&gt;&lt;/div&gt;

&lt;script type="module"&gt;
        // 导入 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 = () =&gt; {
                requestAnimationFrame(animate);
                const delta = clock.getDelta();
                cube.rotation.y += delta;
                renderer.render(scene, camera);
        };

        animate(); // 运行动画

        // 交互 :鼠标点击
        papa.onclick = (e) =&gt; {
                // click3(cube, e) 判断是否点击了cube,下同
                if (click3(cube, e)) clock.running ? clock.stop() : clock.start();
        }
        // 交互 :鼠标经过
        papa.onmousemove = (e) =&gt; {
                papa.title = click3(cube, e) ? '播放/暂停' : '';
                papa.style.cursor = click3(cube, e) ? 'pointer' : 'default';
        }
&lt;/script&gt;
        </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">
&lt;!-- ThreeJS库文档目录结构映射 --&gt;
&lt;script type="importmap"&gt;
{
"imports": {
    "three": "https://638183.freep.cn/638183/3dev/build/three.module.min.js",
    "three/addons/jsm/": "https://638183.freep.cn/638183/3dev/examples/jsm/"
}
}
&lt;/script&gt;

&lt;script type="module"&gt;
        // 导入 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); // 实例化轨道控制器

        //...其它代码
&lt;/script&gt;
        </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>

杨帆 发表于 2025-6-15 00:09

讲的真好,谢谢马老师经典分享{:4_191:}

马黑黑 发表于 2025-6-15 10:59

杨帆 发表于 2025-6-15 00:09
讲的真好,谢谢马老师经典分享

{:4_191:}

红影 发表于 2025-6-15 13:15

导入 basic3 后,就不需要去一一声明和定义ThreeJS 的基础变量了,这样的封装带来便利{:4_187:}

红影 发表于 2025-6-15 13:17

“函数 click3(图像, e) 用于判断鼠标指针是否在图像内,支持多个图形参数”
这个是ThreeJS 特有的还是所有的js都是这样{:4_204:}

樵歌 发表于 2025-6-15 13:49

{:5_116:}

马黑黑 发表于 2025-6-15 16:52

樵歌 发表于 2025-6-15 13:49


谢赞

马黑黑 发表于 2025-6-15 17:04

红影 发表于 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 17:06

红影 发表于 2025-6-15 13:15
导入 basic3 后,就不需要去一一声明和定义ThreeJS 的基础变量了,这样的封装带来便利

这个封装多多少少减轻一点用ThreeJS做帖的工作量

花飞飞 发表于 2025-6-15 17:43

本帖最后由 花飞飞 于 2025-6-15 17:49 编辑

启动basic3之后就直接绘制立方体了,做贴用好方便的

看到中间关于相机的那三个参数camera.fov封在里面了,
但需的更改立方体大小 和位置时候又可以灵活使用,
又做到了简洁加灵活。。
{:4_199:}

花飞飞 发表于 2025-6-15 17:55

马黑黑 发表于 2025-6-15 17:04
click3() 是自己编写的basic3模块辅助函数,利用 ThreeJS Raycast 类检测鼠标指针是否在指定图像的上方。 ...

看来这个函数只能跟basic3配套使用。
Raycast 射线类能提供相机射线与图像是否相交,感觉射线范围会大于图像,图像应该都是相交点集合。

花飞飞 发表于 2025-6-15 18:02

之前那些扩展库也适用,功能是一点没少。。{:4_173:}

马黑黑 发表于 2025-6-15 19:00

花飞飞 发表于 2025-6-15 17:43
启动basic3之后就直接绘制立方体了,做贴用好方便的

看到中间关于相机的那三个参数camera.fov封在里面了 ...

简单封装,十来分钟就弄好,测试呢多花了点时间

马黑黑 发表于 2025-6-15 19:01

花飞飞 发表于 2025-6-15 17:55
看来这个函数只能跟basic3配套使用。
Raycast 射线类能提供相机射线与图像是否相交,感觉射线范围会大于 ...

这个不是很精准的,大概

马黑黑 发表于 2025-6-15 19:02

花飞飞 发表于 2025-6-15 18:02
之前那些扩展库也适用,功能是一点没少。。

只要按说明添加即可

花飞飞 发表于 2025-6-15 19:24

马黑黑 发表于 2025-6-15 19:02
只要按说明添加即可

{:4_173:} 好哒。。。跟加醋加味精一样

花飞飞 发表于 2025-6-15 19:26

马黑黑 发表于 2025-6-15 19:01
这个不是很精准的,大概

设计这个的思路很妙{:4_187:}

花飞飞 发表于 2025-6-15 19:27

马黑黑 发表于 2025-6-15 19:00
简单封装,十来分钟就弄好,测试呢多花了点时间

十来分钟就封好了。。你就是黑神{:4_173:}
测试是指范例效果对吧

马黑黑 发表于 2025-6-15 20:09

花飞飞 发表于 2025-6-15 19:27
十来分钟就封好了。。你就是黑神
测试是指范例效果对吧

测试是多层面的,主要测试封装的东东的适应性

马黑黑 发表于 2025-6-15 20:10

花飞飞 发表于 2025-6-15 19:26
设计这个的思路很妙

ThreeJS提供有具体代码,二次开发者只要按规范和需求使用即可
页: [1] 2 3 4 5 6 7
查看完整版本: basic3文档