From 94fde7942f5397d34f74ad92b121c6c8ed8c013c Mon Sep 17 00:00:00 2001 From: fukunee Date: Fri, 18 Sep 2026 21:39:11 +0800 Subject: [PATCH] Prevent text selection and restrict globe/camera controls Disable copy, cut, and context menu site-wide, and limit Cesium camera input to left-drag rotation and wheel zoom only. Also speed up page flip animation from 1.3s to 0.6s with an ease-out curve for a snappier feel. --- src/main.js | 5 +++++ src/scene/CesiumGlobe.js | 13 +++++++++++++ src/scene/binder.js | 8 ++++---- src/styles.css | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main.js b/src/main.js index 3d6daab..004717f 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,10 @@ import { App } from './core/App.js'; +// 全站禁止复制/剪切/右键菜单(配合 CSS user-select: none 禁止选中) +for (const ev of ['copy', 'cut', 'contextmenu']) { + document.addEventListener(ev, (e) => e.preventDefault()); +} + // 启动应用 const app = new App(); window.__app = app; // 便于调试 diff --git a/src/scene/CesiumGlobe.js b/src/scene/CesiumGlobe.js index a48e8ff..4d4a51d 100644 --- a/src/scene/CesiumGlobe.js +++ b/src/scene/CesiumGlobe.js @@ -57,6 +57,19 @@ export class CesiumGlobe { controller.minimumZoomDistance = 10000; // 最近约 10 km(区域尺度) controller.maximumZoomDistance = 8e6; // 最远约 8000 km + // 限制鼠标按钮:只保留左键旋转 + 滚轮缩放;禁用中键倾斜、右键缩放 + controller.zoomEventTypes = [ + Cesium.CameraEventType.WHEEL, + Cesium.CameraEventType.PINCH, + ]; + controller.tiltEventTypes = [ + Cesium.CameraEventType.PINCH, + { + eventType: Cesium.CameraEventType.LEFT_DRAG, + modifier: Cesium.KeyboardEventModifier.CTRL, + }, + ]; + // 精细化渲染:质量与性能的平衡 scene.globe.maximumScreenSpaceError = 2.0; // 默认细分,最省性能 scene.globe.tileCacheSize = 600; // 更大的瓦片缓存,减少细节刷新 diff --git a/src/scene/binder.js b/src/scene/binder.js index 9ec6d1c..363ccf2 100644 --- a/src/scene/binder.js +++ b/src/scene/binder.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import { ENTRIES } from '../data/entries.js'; import { PAGE_W, PAGE_H, HOLE_U, getPageTextures } from '../textures/pages.js'; -import { clamp, easeInOutQuint } from '../utils/easing.js'; +import { clamp, easeOutCubic } from '../utils/easing.js'; const RING_R = 0.085; const RING_TUBE = 0.0115; @@ -481,13 +481,13 @@ export class Binder { flipForward() { if (!this.canFlipForward()) return; - this.flip = { index: this.current, from: 0, to: -Math.PI, t: 0, duration: 1.3 }; + this.flip = { index: this.current, from: 0, to: -Math.PI, t: 0, duration: 0.6 }; this.pages[this.current].group.position.z = 0.006; } flipBackward() { if (!this.canFlipBackward()) return; - this.flip = { index: this.current - 1, from: -Math.PI, to: 0, t: 0, duration: 1.3 }; + this.flip = { index: this.current - 1, from: -Math.PI, to: 0, t: 0, duration: 0.6 }; this.pages[this.current - 1].group.position.z = 0.006; } @@ -496,7 +496,7 @@ export class Binder { const f = this.flip; f.t += dt / f.duration; const k = clamp(f.t, 0, 1); - const e = easeInOutQuint(k); + const e = easeOutCubic(k); const angle = f.from + (f.to - f.from) * e; const p = this.pages[f.index]; diff --git a/src/styles.css b/src/styles.css index 2ded785..7d1d9c9 100644 --- a/src/styles.css +++ b/src/styles.css @@ -14,7 +14,7 @@ --kai: "Kaiti SC", "STKaiti", "KaiTi", "Segoe Script", cursive; } -* { box-sizing: border-box; margin: 0; padding: 0; } +* { box-sizing: border-box; margin: 0; padding: 0; -webkit-user-select: none; user-select: none; } html, body { height: 100%;