@realsee/five
Version:
Realsee Renderer SDK
122 lines (114 loc) • 30.5 kB
HTML
<html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>features/gesture | 如视 Five SDK</title><meta name="description" content="Documentation for 如视 Five SDK"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">如视 Five SDK</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">features/gesture</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="gesture-手势与事件" class="tsd-anchor-link">Gesture (手势与事件)<a href="#gesture-手势与事件" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1>
<ul>
<li><strong>Summary</strong>: Five 提供了一套跨平台的手势事件系统,抹平了 PC 与移动端的差异,并针对不同 Mode 提供了默认的交互逻辑。</li>
<li><strong>Schema</strong>: <code>GestureEvent</code> 继承自 <code>StateEvent</code>,包含了手势中心点、射线等信息。</li>
<li><strong>Concepts</strong>: Gesture Type, Default Behavior, PreventDefault。</li>
<li><strong>Examples</strong>: 阻止默认行为、点击添加标记。</li>
</ul>
<h2 id="schema" class="tsd-anchor-link">Schema<a href="#schema" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<blockquote>
<p><strong>Definition</strong>: <a href="../../five/utils/event.d.ts">GestureEvent</a></p>
</blockquote>
<p>所有手势事件的回调参数均为 <code>GestureEvent</code> 类型:</p>
<pre><code class="typescript"><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">State</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">"@realsee/five"</span><span class="hl-1">;</span><br/><span class="hl-10">import</span><span class="hl-1"> </span><span class="hl-3">*</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-6">THREE</span><span class="hl-1"> </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">"three"</span><span class="hl-1">;</span><br/><br/><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">GestureEvent</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">type</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-8">// 事件类型,如 "gesture.tap"</span><br/><span class="hl-1"> </span><span class="hl-6">timeStamp</span><span class="hl-1">: </span><span class="hl-7">number</span><span class="hl-1">; </span><span class="hl-8">// 时间戳</span><br/><span class="hl-1"> </span><span class="hl-6">target</span><span class="hl-1">: </span><span class="hl-7">EventTarget</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-6">pointerType</span><span class="hl-1">: </span><span class="hl-9">'touch'</span><span class="hl-1"> | </span><span class="hl-9">'pen'</span><span class="hl-1"> | </span><span class="hl-9">'mouse'</span><span class="hl-1"> | </span><span class="hl-9">'kinect'</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 手势中心点信息</span><br/><span class="hl-1"> </span><span class="hl-6">center</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-6">x</span><span class="hl-1">: </span><span class="hl-7">number</span><span class="hl-1">; </span><span class="hl-8">// 屏幕 X 坐标</span><br/><span class="hl-1"> </span><span class="hl-6">y</span><span class="hl-1">: </span><span class="hl-7">number</span><span class="hl-1">; </span><span class="hl-8">// 屏幕 Y 坐标</span><br/><span class="hl-1"> </span><span class="hl-6">raycaster</span><span class="hl-1">: </span><span class="hl-7">THREE</span><span class="hl-1">.</span><span class="hl-7">Raycaster</span><span class="hl-1">; </span><span class="hl-8">// 从相机发出的射线(已包含坐标变换)</span><br/><span class="hl-1"> };</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 当前相机状态</span><br/><span class="hl-1"> </span><span class="hl-6">state</span><span class="hl-1">: </span><span class="hl-7">State</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 是否是用户触发(区别于代码调用)</span><br/><span class="hl-1"> </span><span class="hl-6">userAction</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 阻止默认行为</span><br/><span class="hl-1"> </span><span class="hl-5">preventDefault</span><span class="hl-1">(): </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-6">defaultPrevented</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<h2 id="concepts" class="tsd-anchor-link">Concepts<a href="#concepts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>Five 的手势系统基于 Hammer.js 封装,主要包含以下几种手势:</p>
<ul>
<li><strong>gesture.fire</strong>: 任意事件被触发。</li>
<li><strong>gesture.pan</strong>: 拖拽/平移。</li>
<li><strong>gesture.pinch</strong>: 双指缩放。</li>
<li><strong>gesture.tap</strong>: 点击。</li>
<li><strong>gesture.dbltap</strong>: 双击。</li>
<li><strong>gesture.press</strong>: 长按。</li>
<li><strong>gesture.mousewheel</strong>: 鼠标滚轮。</li>
</ul>
<h3 id="模式差异-mode-specifics" class="tsd-anchor-link">模式差异 (Mode Specifics)<a href="#模式差异-mode-specifics" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>不同的 Mode 对手势有不同的<strong>默认响应</strong>:</p>
<table>
<thead>
<tr>
<th style="text-align:left">手势</th>
<th style="text-align:left">Panorama (全景)</th>
<th style="text-align:left">Mapview (模型)</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left"><strong>Pan</strong></td>
<td style="text-align:left">旋转相机视角 (Look around)</td>
<td style="text-align:left">围绕模型旋转/平移相机 (Orbit/Pan)</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left"><strong>Pinch</strong></td>
<td style="text-align:left">调整 FOV (Zoom in/out)</td>
<td style="text-align:left">调整相机距离 (Distance)</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left"><strong>Tap</strong></td>
<td style="text-align:left"><strong>移动点位</strong> (Move to pano)</td>
<td style="text-align:left"><strong>切换到全景</strong> (Enter pano)</td>
<td style="text-align:left">若点击到地面/模型,Mapview 下默认无响应,除非点击到点位标记</td>
</tr>
<tr>
<td style="text-align:left"><strong>DblTap</strong></td>
<td style="text-align:left">动画调整 FOV</td>
<td style="text-align:left">聚焦并拉近视角 (Fly to)</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left"><strong>MouseWheel</strong></td>
<td style="text-align:left">调整 FOV</td>
<td style="text-align:left">调整相机距离</td>
<td style="text-align:left"></td>
</tr>
</tbody>
</table>
<h3 id="事件捕获与阻止-event-handling" class="tsd-anchor-link">事件捕获与阻止 (Event Handling)<a href="#事件捕获与阻止-event-handling" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Five 的事件触发顺序如下:</p>
<ol>
<li><strong>Emit Event</strong>: Five 触发 <code>gesture.xxx</code> 事件。</li>
<li><strong>User Callback</strong>: 开发者注册的监听函数被执行。</li>
<li><strong>Default Behavior</strong>: <strong>如果</strong>开发者没有调用 <code>event.preventDefault()</code>,Five 执行默认逻辑(如旋转相机、移动点位)。</li>
</ol>
<p>因此,如果你想自定义交互(例如:点击不走点,而是弹出一个框),<strong>必须</strong>调用 <code>event.preventDefault()</code>。</p>
<h2 id="examples" class="tsd-anchor-link">Examples<a href="#examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<h3 id="快速上手-quick-example" class="tsd-anchor-link">快速上手 (Quick Example)<a href="#快速上手-quick-example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>监听点击事件并打印日志:</p>
<pre><code class="typescript"><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-5">on</span><span class="hl-1">(</span><span class="hl-9">"gesture.tap"</span><span class="hl-1">, (</span><span class="hl-6">event</span><span class="hl-1">) </span><span class="hl-3">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">console</span><span class="hl-1">.</span><span class="hl-5">log</span><span class="hl-1">(</span><span class="hl-9">"点击位置:"</span><span class="hl-1">, </span><span class="hl-6">event</span><span class="hl-1">.</span><span class="hl-6">center</span><span class="hl-1">.</span><span class="hl-6">x</span><span class="hl-1">, </span><span class="hl-6">event</span><span class="hl-1">.</span><span class="hl-6">center</span><span class="hl-1">.</span><span class="hl-6">y</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-8">// event.center.raycaster 可以用来做射线检测</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<h3 id="场景交互:点击添加标签球-add-label-on-click" class="tsd-anchor-link">场景交互:点击添加标签球 (Add Label on Click)<a href="#场景交互:点击添加标签球-add-label-on-click" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>这个示例展示了如何通过点击事件在场景中添加一个红色的球体,并阻止 Five 默认的点位移动行为。</p>
<pre><code class="typescript"><span class="hl-10">import</span><span class="hl-1"> </span><span class="hl-3">*</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-6">THREE</span><span class="hl-1"> </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">"three"</span><span class="hl-1">;</span><br/><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">Five</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">"@realsee/five"</span><span class="hl-1">;</span><br/><br/><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">five</span><span class="hl-1"> = </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-5">Five</span><span class="hl-1">();</span><br/><br/><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-5">on</span><span class="hl-1">(</span><span class="hl-9">"gesture.tap"</span><span class="hl-1">, (</span><span class="hl-6">event</span><span class="hl-1">) </span><span class="hl-3">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-8">// 1. 阻止默认行为(防止点击地面时 Five 自动走点或切换模式)</span><br/><span class="hl-1"> </span><span class="hl-6">event</span><span class="hl-1">.</span><span class="hl-5">preventDefault</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 2. 获取射线</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">raycaster</span><span class="hl-1"> = </span><span class="hl-6">event</span><span class="hl-1">.</span><span class="hl-6">center</span><span class="hl-1">.</span><span class="hl-6">raycaster</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 3. 检测与模型的碰撞</span><br/><span class="hl-1"> </span><span class="hl-8">// five.model.intersectRaycaster 是 Five 提供的便捷方法,会自动检测所有可见模型</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">intersects</span><span class="hl-1"> = </span><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">model</span><span class="hl-1">.</span><span class="hl-5">intersectRaycaster</span><span class="hl-1">(</span><span class="hl-6">raycaster</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-10">if</span><span class="hl-1"> (</span><span class="hl-6">intersects</span><span class="hl-1">.</span><span class="hl-6">length</span><span class="hl-1"> > </span><span class="hl-11">0</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">intersect</span><span class="hl-1"> = </span><span class="hl-6">intersects</span><span class="hl-1">[</span><span class="hl-11">0</span><span class="hl-1">];</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">point</span><span class="hl-1"> = </span><span class="hl-6">intersect</span><span class="hl-1">.</span><span class="hl-6">point</span><span class="hl-1">; </span><span class="hl-8">// 碰撞点世界坐标</span><br/><br/><span class="hl-1"> </span><span class="hl-6">console</span><span class="hl-1">.</span><span class="hl-5">log</span><span class="hl-1">(</span><span class="hl-9">"点击到了模型,坐标:"</span><span class="hl-1">, </span><span class="hl-6">point</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 4. 创建一个小球</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">geometry</span><span class="hl-1"> = </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">SphereGeometry</span><span class="hl-1">(</span><span class="hl-11">0.1</span><span class="hl-1">, </span><span class="hl-11">32</span><span class="hl-1">, </span><span class="hl-11">32</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">material</span><span class="hl-1"> = </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">MeshBasicMaterial</span><span class="hl-1">({ </span><span class="hl-6">color:</span><span class="hl-1"> </span><span class="hl-11">0xff0000</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">sphere</span><span class="hl-1"> = </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">Mesh</span><span class="hl-1">(</span><span class="hl-6">geometry</span><span class="hl-1">, </span><span class="hl-6">material</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 5. 设置位置并添加到场景</span><br/><span class="hl-1"> </span><span class="hl-6">sphere</span><span class="hl-1">.</span><span class="hl-6">position</span><span class="hl-1">.</span><span class="hl-5">copy</span><span class="hl-1">(</span><span class="hl-6">point</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">scene</span><span class="hl-1">.</span><span class="hl-5">add</span><span class="hl-1">(</span><span class="hl-6">sphere</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 强制刷新渲染,确保小球立即出现</span><br/><span class="hl-1"> </span><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">needsRender</span><span class="hl-1"> = </span><span class="hl-3">true</span><span class="hl-1">;</span><br/><span class="hl-1"> } </span><span class="hl-10">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">console</span><span class="hl-1">.</span><span class="hl-5">log</span><span class="hl-1">(</span><span class="hl-9">"未点击到任何模型"</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<h3 id="进阶用法:自定义双指缩放范围" class="tsd-anchor-link">进阶用法:自定义双指缩放范围<a href="#进阶用法:自定义双指缩放范围" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-5">on</span><span class="hl-1">(</span><span class="hl-9">"gesture.pinch"</span><span class="hl-1">, (</span><span class="hl-6">event</span><span class="hl-1">) </span><span class="hl-3">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-8">// 获取当前 FOV</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">currentFov</span><span class="hl-1"> = </span><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">.</span><span class="hl-6">fov</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 假设我们限制 FOV 在 80 到 100 之间</span><br/><span class="hl-1"> </span><span class="hl-8">// 注意:这只是逻辑演示,Five 内部有自己的 minFov/maxFov 配置,</span><br/><span class="hl-1"> </span><span class="hl-8">// 这里演示如何完全接管控制权。</span><br/><span class="hl-1"> </span><span class="hl-10">if</span><span class="hl-1"> (</span><span class="hl-6">currentFov</span><span class="hl-1"> < </span><span class="hl-11">80</span><span class="hl-1"> || </span><span class="hl-6">currentFov</span><span class="hl-1"> > </span><span class="hl-11">100</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-8">// 阻止 Five 的默认缩放</span><br/><span class="hl-1"> </span><span class="hl-6">event</span><span class="hl-1">.</span><span class="hl-5">preventDefault</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-6">console</span><span class="hl-1">.</span><span class="hl-5">log</span><span class="hl-1">(</span><span class="hl-9">"已达到缩放极限"</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<h2 id="debugging" class="tsd-anchor-link">Debugging<a href="#debugging" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<ul>
<li><strong>查看事件触发</strong>: 在控制台监听所有手势。<pre><code class="typescript"><span class="hl-1">[</span><span class="hl-9">"pan"</span><span class="hl-1">, </span><span class="hl-9">"tap"</span><span class="hl-1">, </span><span class="hl-9">"pinch"</span><span class="hl-1">, </span><span class="hl-9">"press"</span><span class="hl-1">].</span><span class="hl-5">forEach</span><span class="hl-1">(</span><span class="hl-6">type</span><span class="hl-1"> </span><span class="hl-3">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-5">on</span><span class="hl-1">(</span><span class="hl-9">`gesture.</span><span class="hl-3">${</span><span class="hl-6">type</span><span class="hl-3">}</span><span class="hl-9">`</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-7">any</span><span class="hl-1">, (</span><span class="hl-6">e</span><span class="hl-1">) </span><span class="hl-3">=></span><span class="hl-1"> </span><span class="hl-6">console</span><span class="hl-1">.</span><span class="hl-5">log</span><span class="hl-1">(</span><span class="hl-6">type</span><span class="hl-1">, </span><span class="hl-6">e</span><span class="hl-1">));</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
</li>
<li><strong>Helper Line</strong>: 如果射线检测不准,可以画出射线辅助线。<pre><code class="typescript"><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">scene</span><span class="hl-1">.</span><span class="hl-5">add</span><span class="hl-1">(</span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">ArrowHelper</span><span class="hl-1">(</span><span class="hl-6">raycaster</span><span class="hl-1">.</span><span class="hl-6">ray</span><span class="hl-1">.</span><span class="hl-6">direction</span><span class="hl-1">, </span><span class="hl-6">raycaster</span><span class="hl-1">.</span><span class="hl-6">ray</span><span class="hl-1">.</span><span class="hl-6">origin</span><span class="hl-1">, </span><span class="hl-11">10</span><span class="hl-1">, </span><span class="hl-11">0xff0000</span><span class="hl-1">));</span><br/><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">needsRender</span><span class="hl-1"> = </span><span class="hl-3">true</span><span class="hl-1">;</span>
</code><button type="button">Copy</button></pre>
</li>
</ul>
<h2 id="common-pitfalls" class="tsd-anchor-link">Common Pitfalls<a href="#common-pitfalls" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<ol>
<li><strong>忘记 preventDefault</strong>: 如果你发现点击后既生成了小球,相机又自动飞走了,通常是因为没有调用 <code>event.preventDefault()</code>。</li>
<li><strong>坐标系混淆</strong>: <code>event.center.x/y</code> 是屏幕像素坐标,<code>event.center.raycaster</code> 已经处理了屏幕到世界的转换。直接使用 <code>raycaster</code> 最安全。</li>
<li><strong>点击穿透</strong>: 如果场景中有 HTML 覆盖层(如按钮),HTML 元素的点击事件可能会冒泡或被 Five 捕获。建议在 HTML 元素上使用 <code>stopPropagation</code> 或判断 <code>event.target</code>。</li>
</ol>
<h2 id="related" class="tsd-anchor-link">Related<a href="#related" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<ul>
<li><a href="features_mode.html">Mode (模式)</a>: 了解不同模式下的默认行为。</li>
<li><a href="features_state.html">State (状态)</a>: 手势最终改变的是 State。</li>
<li><a href="features_raycast.html">Raycast (射线检测)</a>: 深入了解 <code>intersectRaycaster</code> 的工作原理。</li>
</ul>
<hr>
<pre><code class="yaml"><span class="hl-0">tags</span><span class="hl-1">: [</span><span class="hl-2">手势</span><span class="hl-1">, </span><span class="hl-2">点击</span><span class="hl-1">, </span><span class="hl-2">拖拽</span><span class="hl-1">, </span><span class="hl-2">缩放</span><span class="hl-1">, </span><span class="hl-2">长按</span><span class="hl-1">, </span><span class="hl-2">鼠标</span><span class="hl-1">, </span><span class="hl-2">触摸</span><span class="hl-1">, </span><span class="hl-2">交互控制</span><span class="hl-1">, </span><span class="hl-2">自定义交互</span><span class="hl-1">, </span><span class="hl-2">gesture</span><span class="hl-1">, </span><span class="hl-2">event</span><span class="hl-1">, </span><span class="hl-2">interaction</span><span class="hl-1">, </span><span class="hl-2">tap</span><span class="hl-1">, </span><span class="hl-2">pan</span><span class="hl-1">, </span><span class="hl-2">pinch</span><span class="hl-1">, </span><span class="hl-2">preventDefault</span><span class="hl-1">]</span>
</code><button type="button">Copy</button></pre>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#gesture-手势与事件"><span>Gesture (手势与事件)</span></a><ul><li><a href="#schema"><span>Schema</span></a></li><li><a href="#concepts"><span>Concepts</span></a></li><li><ul><li><a href="#模式差异-mode-specifics"><span>模式差异 (<wbr/>Mode <wbr/>Specifics)</span></a></li><li><a href="#事件捕获与阻止-event-handling"><span>事件捕获与阻止 (<wbr/>Event <wbr/>Handling)</span></a></li></ul></li><li><a href="#examples"><span>Examples</span></a></li><li><ul><li><a href="#快速上手-quick-example"><span>快速上手 (<wbr/>Quick <wbr/>Example)</span></a></li><li><a href="#场景交互:点击添加标签球-add-label-on-click"><span>场景交互:点击添加标签球 (<wbr/>Add <wbr/>Label on <wbr/>Click)</span></a></li><li><a href="#进阶用法:自定义双指缩放范围"><span>进阶用法:自定义双指缩放范围</span></a></li></ul></li><li><a href="#debugging"><span>Debugging</span></a></li><li><a href="#common-pitfalls"><span>Common <wbr/>Pitfalls</span></a></li><li><a href="#related"><span>Related</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">如视 Five SDK</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>