Skip to content

Commit 8d9f42d

Browse files
committed
#175 キーフレームに配分を実装(WIP)
1 parent 6eb12b5 commit 8d9f42d

20 files changed

Lines changed: 299 additions & 36 deletions

src/js/controller/application/HistoryArea/usecase/HistoryRedoCommandUseCase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ export const execute = async (
432432

433433
// キーフレームへフレームを挿入
434434
case $TIMELINE_INSERT_KEY_FRAME_COMMAND:
435-
timelineLayerFrameInsertKeyFramesHistoryRedoUseCase(
435+
await timelineLayerFrameInsertKeyFramesHistoryRedoUseCase(
436436
messages[0] as number, // work_space_id
437437
messages[1] as number, // library_id
438438
messages[2] as number, // layer_index

src/js/controller/application/HistoryArea/usecase/HistoryUndoCommandUseCase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ export const execute = async (
428428

429429
// キーフレームへフレームを挿入
430430
case $TIMELINE_INSERT_KEY_FRAME_COMMAND:
431-
timelineLayerFrameInsertKeyFramesHistoryUndoUseCase(
431+
await timelineLayerFrameInsertKeyFramesHistoryUndoUseCase(
432432
messages[0] as number, // WorkSpace ID
433433
messages[1] as number, // MovieClip ID
434434
messages[2] as number, // Layer Index

src/js/external/core/domain/model/ExternalCharacter.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,36 @@ export class ExternalCharacter
9393
return this._$character.id;
9494
}
9595

96+
/**
97+
* @description DisplayObjectの開始フレームを返却
98+
* Returns the start frame of DisplayObject
99+
*
100+
* @member {number}
101+
*/
102+
get startFrame (): number
103+
{
104+
return this._$character.startFrame;
105+
}
106+
set startFrame (frame: number)
107+
{
108+
this._$character.startFrame = frame;
109+
}
110+
111+
/**
112+
* @description DisplayObjectの終了フレームを返却
113+
* Returns the end frame of DisplayObject
114+
*
115+
* @member {number}
116+
*/
117+
get endFrame (): number
118+
{
119+
return this._$character.endFrame;
120+
}
121+
set endFrame (frame: number)
122+
{
123+
this._$character.endFrame = frame;
124+
}
125+
96126
/**
97127
* @description DisplayObjectのx座標を返却
98128
* Returns the x-coordinate of DisplayObject
@@ -693,7 +723,7 @@ export class ExternalCharacter
693723
* @method
694724
* @public
695725
*/
696-
async delete (): Promise<void>
726+
async remove (): Promise<void>
697727
{
698728
await externalCharacterDeleteUseCase(
699729
this._$workSpace,

src/js/external/core/domain/model/ExternalLayer.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ export class ExternalLayer
274274
async addCharacter (
275275
external_character: ExternalCharacter,
276276
depth: number = 0
277-
): Promise<void>
278-
{
277+
): Promise<void> {
279278
await externalLayerAddCharacterUseCase(
280279
this._$workSpace,
281280
this._$movieClip,

src/js/history/application/timeline/application/TimelineLayerFrame/AddKeyframe/usecase/TimelineLayerFrameAddKeyframeHistoryUndoUseCase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export const execute = async (
7070
// fixed logic
7171
if (workSpace.active && movieClip.active) {
7272
// スクリーンに追加したElementを削除
73-
screenAreaRemoveDisplayObjectElementService(layer.id, character.depth);
73+
screenAreaRemoveDisplayObjectElementService(character.id);
7474

7575
for (const [index, depths] of movieClip.selectedDepths) {
7676
const layer = movieClip.getLayer(index);

src/js/history/application/timeline/application/TimelineLayerFrame/InsertKeyFrames/usecase/TimelineLayerFrameInsertKeyFramesHistoryRedoUseCase.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { MovieClip } from "@/core/domain/model/MovieClip";
22
import { $getWorkSpace } from "@/core/application/CoreUtil";
33
import { execute as externalTimelineLayerFrameBehindKeyframeService } from "@/external/timeline/application/ExternalTimelineLayerFrame/service/ExternalTimelineLayerFrameBehindKeyframeService";
44
import { execute as timelineLayerAddFrameUpdateLayerStyleUseCase } from "@/timeline/application/TimelineLayer/usecase/TimelineLayerAddFrameUpdateLayerStyleUseCase";
5+
import { execute as screenAreaRedrawUseCase } from "@/screen/application/ScreenArea/usecase/ScreenAreaRedrawUseCase";
6+
import { execute as screenDisplayObjectAllSelectedActiveUseCase } from "@/screen/application/DisplayObject/usecase/ScreenDisplayObjectAllSelectedActiveUseCase";
57

68
/**
79
* @description 空のキーフレームへのフレーム追加処理を元に戻す
@@ -12,17 +14,17 @@ import { execute as timelineLayerAddFrameUpdateLayerStyleUseCase } from "@/timel
1214
* @param {number} layer_index
1315
* @param {number} start_frame
1416
* @param {number} num_frame
15-
* @return {void}
17+
* @return {Promise<void>}
1618
* @method
1719
* @public
1820
*/
19-
export const execute = (
21+
export const execute = async (
2022
work_space_id: number,
2123
library_id: number,
2224
layer_index: number,
2325
start_frame: number,
2426
num_frame: number
25-
): void => {
27+
): Promise<void> => {
2628

2729
const workSpace = $getWorkSpace(work_space_id);
2830
if (!workSpace) {
@@ -57,8 +59,23 @@ export const execute = (
5759
}
5860

5961
// アクティブならタイムラインを再描画
60-
if (workSpace.active && movieClip.active) {
62+
if (!workSpace.active) {
63+
return ;
64+
}
65+
66+
if (movieClip.active) {
6167
// タイムラインのレイヤー表示を更新
6268
timelineLayerAddFrameUpdateLayerStyleUseCase(movieClip, layer);
69+
70+
// スクリーンエリアを再描画
71+
await screenAreaRedrawUseCase(movieClip);
72+
} else {
73+
const movieClip = workSpace.scene;
74+
// スクリーンエリアを再描画
75+
await screenAreaRedrawUseCase(movieClip);
76+
77+
// 選択中のDisplayObjectをアクティブにする
78+
// fixed logic
79+
screenDisplayObjectAllSelectedActiveUseCase(movieClip);
6380
}
6481
};

src/js/history/application/timeline/application/TimelineLayerFrame/InsertKeyFrames/usecase/TimelineLayerFrameInsertKeyFramesHistoryUndoUseCase.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { MovieClip } from "@/core/domain/model/MovieClip";
22
import { $getWorkSpace } from "@/core/application/CoreUtil";
33
import { execute as externalTimelineLayerFrameForwardKeyframeService } from "@/external/timeline/application/ExternalTimelineLayerFrame/service/ExternalTimelineLayerFrameForwardKeyframeService";
44
import { execute as timelineLayerAddFrameUpdateLayerStyleUseCase } from "@/timeline/application/TimelineLayer/usecase/TimelineLayerAddFrameUpdateLayerStyleUseCase";
5+
import { execute as screenAreaRedrawUseCase } from "@/screen/application/ScreenArea/usecase/ScreenAreaRedrawUseCase";
6+
import { execute as screenDisplayObjectAllSelectedActiveUseCase } from "@/screen/application/DisplayObject/usecase/ScreenDisplayObjectAllSelectedActiveUseCase";
57

68
/**
79
* @description キーフレームへのフレーム追加処理を元に戻す
@@ -12,17 +14,17 @@ import { execute as timelineLayerAddFrameUpdateLayerStyleUseCase } from "@/timel
1214
* @param {number} layer_index
1315
* @param {number} start_frame
1416
* @param {number} num_frame
15-
* @return {void}
17+
* @return {Promise<void>}
1618
* @method
1719
* @public
1820
*/
19-
export const execute = (
21+
export const execute = async (
2022
work_space_id: number,
2123
library_id: number,
2224
layer_index: number,
2325
start_frame: number,
2426
num_frame: number
25-
): void => {
27+
): Promise<void> => {
2628

2729
const workSpace = $getWorkSpace(work_space_id);
2830
if (!workSpace) {
@@ -60,8 +62,23 @@ export const execute = (
6062
}
6163

6264
// アクティブならタイムラインを再描画
63-
if (workSpace.active && movieClip.active) {
65+
if (!workSpace.active) {
66+
return ;
67+
}
68+
69+
if (movieClip.active) {
6470
// タイムラインのレイヤー表示を更新
6571
timelineLayerAddFrameUpdateLayerStyleUseCase(movieClip, layer);
72+
73+
// スクリーンエリアを再描画
74+
await screenAreaRedrawUseCase(movieClip);
75+
} else {
76+
const movieClip = workSpace.scene;
77+
// スクリーンエリアを再描画
78+
await screenAreaRedrawUseCase(movieClip);
79+
80+
// 選択中のDisplayObjectをアクティブにする
81+
// fixed logic
82+
screenDisplayObjectAllSelectedActiveUseCase(movieClip);
6683
}
6784
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { $SCREEN_DISTRIBUTE_TO_KEYFRAMES_ID } from "@/config/ScreenConfig";
2+
import type { MovieClip } from "@/core/domain/model/MovieClip";
3+
4+
/**
5+
* @description スクリーンのメニューを選択中のElementに合わせてアクティブ・非アクティブに更新する
6+
* Update the screen menu to be active/inactive according to the selected Element
7+
*
8+
* @param {MovieClip} movie_clip
9+
* @return {void}
10+
* @method
11+
* @public
12+
*/
13+
export const execute = (movie_clip: MovieClip): void =>
14+
{
15+
// 単独選択時の表示
16+
const element: HTMLElement | null = document
17+
.getElementById($SCREEN_DISTRIBUTE_TO_KEYFRAMES_ID) as HTMLElement;
18+
if (!element) {
19+
return ;
20+
}
21+
22+
let show = false;
23+
for (const depths of movie_clip.selectedDepths.values()) {
24+
25+
// 単体選択ならスキップ
26+
if (depths.length === 1) {
27+
continue;
28+
}
29+
30+
// 複数選択なら表示
31+
show = true;
32+
break;
33+
}
34+
35+
if (show) {
36+
element.setAttribute("style", "");
37+
} else {
38+
element.style.opacity = "0.5";
39+
element.style.pointerEvents = "none";
40+
}
41+
};
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { $getCurrentWorkSpace } from "@/core/application/CoreUtil";
2+
import { $allHideMenu } from "../../MenuUtil";
3+
import { ExternalTimeline } from "@/external/timeline/domain/model/ExternalTimeline";
4+
import { ExternalCharacter } from "@/external/core/domain/model/ExternalCharacter";
5+
import { ExternalLayer } from "@/external/core/domain/model/ExternalLayer";
6+
import { execute as cacheRemoveService } from "@/cache/service/CacheRemoveService";
7+
import { execute as screenAreaRedrawUseCase } from "@/screen/application/ScreenArea/usecase/ScreenAreaRedrawUseCase";
8+
9+
/**
10+
* @description スクリーンの選択中のDisplayObjectをキーフレームに配分する
11+
* Distribute the selected DisplayObject on the screen to keyframes
12+
*
13+
* @param {PointerEvent | KeyboardEvent} event
14+
* @return {Promise<void>}
15+
* @method
16+
* @public
17+
*/
18+
export const execute = async (event: PointerEvent | KeyboardEvent): Promise<void> =>
19+
{
20+
// メニューを全て閉じる
21+
$allHideMenu();
22+
23+
const workSpace = $getCurrentWorkSpace();
24+
const movieClip = workSpace.scene;
25+
26+
// 選択中のMovieClipが無い場合は処理を終了
27+
if (!movieClip.selectedDepths.size) {
28+
return ;
29+
}
30+
31+
// イベントの伝播を止める
32+
event.stopPropagation();
33+
34+
// 現在のフレームを取得
35+
const frame = movieClip.currentFrame;
36+
37+
// ExternalTimelineを取得
38+
const externalTimeline = new ExternalTimeline(workSpace, movieClip);
39+
40+
// レイヤーに配分
41+
for (const [layerIndex, depths] of movieClip.selectedDepths) {
42+
43+
// 選択中のDisoplayObjectが1つだけの場合はスキップ
44+
if (depths.length === 1) {
45+
continue;
46+
}
47+
48+
const layer = movieClip.getLayer(layerIndex);
49+
if (!layer) {
50+
continue;
51+
}
52+
53+
// 昇順にソートして先頭以外を新規レイヤーに移動
54+
depths.sort((a, b) => a - b);
55+
56+
const character = layer.getCharacter(frame, depths[0]);
57+
if (!character) {
58+
continue;
59+
}
60+
61+
// 移動するキャラクターを取得
62+
const characters = [];
63+
for (let idx = 1; idx < depths.length; idx++) {
64+
65+
const character = layer.getCharacter(frame, depths[idx]);
66+
if (!character) {
67+
continue;
68+
}
69+
70+
characters.push(character);
71+
}
72+
73+
// レイヤーAPIを取得
74+
const externalLayer = new ExternalLayer(workSpace, movieClip, layer);
75+
await externalTimeline
76+
.selectedLayers([externalLayer.index]);
77+
78+
// 必要なフレーム数を追加
79+
if (character.startFrame + characters.length > character.endFrame - 1) {
80+
await externalTimeline
81+
.insertFrames(character.startFrame + characters.length - (character.endFrame - 1));
82+
} else {
83+
// フレーム数が多い場合は削除
84+
await externalTimeline
85+
.eraseFrames(
86+
character.startFrame + characters.length,
87+
character.endFrame - 1
88+
);
89+
}
90+
91+
// 開始となるキーフレームをセット
92+
const keyframe = character.startFrame + 1;
93+
94+
// 空のキーフレームを追加
95+
for (let idx = 0; idx < characters.length; idx++) {
96+
await externalTimeline
97+
.convertToEmptyKeyframes(keyframe + idx);
98+
}
99+
100+
// キャラクターを移動
101+
for (let idx = 0; idx < characters.length; idx++) {
102+
103+
const character = characters[idx];
104+
if (!character) {
105+
continue;
106+
}
107+
108+
// 現在のレイヤーからDisplayObjectを削除
109+
const externalCharacter = new ExternalCharacter(
110+
workSpace,
111+
movieClip,
112+
layer,
113+
character
114+
);
115+
await externalCharacter.remove();
116+
117+
// 新しいキーフレームにDisplayObjectを追加
118+
const frame = keyframe + idx;
119+
externalCharacter.startFrame = frame;
120+
externalCharacter.endFrame = frame + 1;
121+
122+
await externalLayer.addCharacter(externalCharacter);
123+
}
124+
}
125+
126+
// キャッシュを削除
127+
cacheRemoveService(workSpace, movieClip.id);
128+
129+
// 画面を再描画
130+
await screenAreaRedrawUseCase(movieClip);
131+
};

src/js/menu/application/ScreenMenu/usecase/ScreenMenuDistributeToLayersUseCase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export const execute = async (event: PointerEvent | KeyboardEvent): Promise<void
8585
layer,
8686
character
8787
);
88-
await externalCharacter.delete();
88+
await externalCharacter.remove();
8989

9090
// 新規レイヤーにDisplayObjectを追加
9191
await externalLayer.addCharacter(externalCharacter);

0 commit comments

Comments
 (0)