Skip to content

Commit 27adcc7

Browse files
committed
✨ 增加摄像机翻页式移动:PageUp,PageDown,Home,End
1 parent ed0ee60 commit 27adcc7

File tree

4 files changed

+99
-4
lines changed

4 files changed

+99
-4
lines changed

app/src/core/service/controlService/shortcutKeysEngine/shortcutKeysGroup.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ export const shortcutKeysGroups: ShortcutKeysGroup[] = [
5151
"masterBrakeControl",
5252
"CameraScaleZoomIn",
5353
"CameraScaleZoomOut",
54+
"CameraPageMoveUp",
55+
"CameraPageMoveDown",
56+
"CameraPageMoveLeft",
57+
"CameraPageMoveRight",
5458
],
5559
},
5660
{

app/src/core/service/controlService/shortcutKeysEngine/shortcutKeysRegister.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,42 @@ export namespace ShortcutKeysRegister {
172172
).down(() => {
173173
Camera.zoomOutByKeyboard();
174174
});
175+
(
176+
await KeyBinds.create("CameraPageMoveUp", "pageup", {
177+
control: false,
178+
alt: false,
179+
shift: false,
180+
})
181+
).down(() => {
182+
Camera.pageMove(Direction.Up);
183+
});
184+
(
185+
await KeyBinds.create("CameraPageMoveDown", "pagedown", {
186+
control: false,
187+
alt: false,
188+
shift: false,
189+
})
190+
).down(() => {
191+
Camera.pageMove(Direction.Down);
192+
});
193+
(
194+
await KeyBinds.create("CameraPageMoveLeft", "home", {
195+
control: false,
196+
alt: false,
197+
shift: false,
198+
})
199+
).down(() => {
200+
Camera.pageMove(Direction.Left);
201+
});
202+
(
203+
await KeyBinds.create("CameraPageMoveRight", "end", {
204+
control: false,
205+
alt: false,
206+
shift: false,
207+
})
208+
).down(() => {
209+
Camera.pageMove(Direction.Right);
210+
});
175211

176212
(
177213
await KeyBinds.create("folderSection", "t", {

app/src/core/stage/Camera.tsx

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { Dialog } from "../../components/dialog";
2+
import { Direction } from "../../types/directions";
23
import { NumberFunctions } from "../algorithm/numberFunctions";
4+
import { Queue } from "../dataStruct/Queue";
35
import { Rectangle } from "../dataStruct/shape/Rectangle";
46
import { Vector } from "../dataStruct/Vector";
57
import { Renderer } from "../render/canvas2d/renderer";
68
import { TextRiseEffect } from "../service/feedbackService/effectEngine/concrete/TextRiseEffect";
9+
import { easeOutExpo } from "../service/feedbackService/effectEngine/mathTools/easings";
710
import { Settings } from "../service/Settings";
811
import { Stage } from "./Stage";
912
import { StageManager } from "./stageManager/StageManager";
@@ -103,10 +106,47 @@ export namespace Camera {
103106
let cameraResetViewPaddingRate = 1.5;
104107
export let cameraFollowsSelectedNodeOnArrowKeys = false;
105108

106-
// IDEA: 突然有一个好点子
107-
// 把wsad移动的逻辑改成瞬间爆炸的冲刺一小段距离,而不是改成直接赋予永久的作用力方向然后再撤销
108-
// 这样可以避免好多潜在bug
109-
// 但这样估计就又不流畅了
109+
// pageup / pagedown 爆炸式移动
110+
111+
const shockMoveDiffLocationsQueue = new Queue<Vector>();
112+
/**
113+
* 触发一次翻页式移动
114+
*
115+
* 触发一次后,接下来的60帧里,摄像机都会移动一小段距离,朝向目的位置移动
116+
*/
117+
export function pageMove(direction: Direction) {
118+
// 先清空之前的队列
119+
shockMoveDiffLocationsQueue.clear();
120+
// 计算爆炸式移动的目标位置
121+
const targetLocation = location.clone();
122+
const rect = Renderer.getCoverWorldRectangle();
123+
if (direction === Direction.Up) {
124+
targetLocation.y -= rect.height * 1;
125+
} else if (direction === Direction.Down) {
126+
targetLocation.y += rect.height * 1;
127+
} else if (direction === Direction.Left) {
128+
targetLocation.x -= rect.width * 1;
129+
} else if (direction === Direction.Right) {
130+
targetLocation.x += rect.width * 1;
131+
}
132+
// 生成接下来一些帧里的移动轨迹位置点。
133+
const frameCount = 40;
134+
const movePoints = [];
135+
for (let i = 0; i < frameCount; i++) {
136+
// 进度:0~1
137+
const rate = easeOutExpo(i / frameCount);
138+
const newPoint = location.add(targetLocation.subtract(location).multiply(rate));
139+
movePoints.push(newPoint);
140+
}
141+
// 根据位置轨迹点生成距离变化小向量段
142+
const diffLocations = [];
143+
for (let i = 1; i < movePoints.length; i++) {
144+
const diff = movePoints[i].subtract(movePoints[i - 1]);
145+
diffLocations.push(diff);
146+
// 将距离变化加入队列
147+
shockMoveDiffLocationsQueue.enqueue(diff);
148+
}
149+
}
110150

111151
export function frameTick() {
112152
// 计算摩擦力 与速度方向相反,固定值,但速度为0摩擦力就不存在
@@ -151,6 +191,13 @@ export namespace Camera {
151191
],
152192
});
153193
}
194+
// 冲击式移动
195+
if (!shockMoveDiffLocationsQueue.isEmpty()) {
196+
const diffLocation = shockMoveDiffLocationsQueue.dequeue();
197+
if (diffLocation !== undefined) {
198+
location = location.add(diffLocation);
199+
}
200+
}
154201

155202
// 计算摩擦力
156203
let friction = Vector.getZero();

app/src/locales/zh_CN.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,14 @@ keyBinds:
982982
CameraScaleZoomOut:
983983
title: 视野缩小
984984
description: 按下后,视野缩小
985+
CameraPageMoveUp:
986+
title: 视野向上翻页式移动
987+
CameraPageMoveDown:
988+
title: 视野向下翻页式移动
989+
CameraPageMoveLeft:
990+
title: 视野向左翻页式移动
991+
CameraPageMoveRight:
992+
title: 视野向右翻页式移动
985993
exitSoftware:
986994
title: 退出软件
987995
description: 按下后,退出软件

0 commit comments

Comments
 (0)