polarvo-layout 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/FastMenu/DesignFastmenu.vue +2 -2
- package/src/components/FastMenu/DisplayFastMenu.vue +2 -2
- package/src/components/FastMenu/LayoutFastMenu.vue +18 -10
- package/src/components/Layout/CanvasContainer.vue +30 -6
- package/src/components/SideBar/ElementSideBar.vue +2 -2
- package/src/components/SideBar/LayoutSettingSideBar.vue +18 -10
- package/src/components/SideBar/LayoutSideBar.vue +19 -8
- package/src/configs/index.js +1 -0
- package/src/core/engines/DisplayEngine.js +72 -64
- package/src/core/engines/FreeDropEngine.js +40 -42
- package/src/core/engines/GridDropEngine.js +33 -43
- package/src/core/engines/HistoryEngine.js +55 -51
- package/src/core/engines/LayoutEngine.js +89 -68
- package/src/core/engines/originals/FreeDropEngine_0402.js +786 -0
- package/src/core/engines/originals/GridDropEngine_0402.js +557 -0
- package/src/core/managers/EngineManager.js +93 -131
- package/src/core/managers/originals/EngineManager_0402.js +826 -0
- package/src/library/DisplayLibrary.js +14 -17
- package/src/library/FreeDropLibrary.js +6 -4
- package/src/library/GridDropLibrary.js +3 -5
- package/src/library/LayoutLibrary.js +45 -48
- package/src/library/originals/DisplayLibrary_0402.js +137 -0
- package/src/library/originals/FreeDropLibrary_0402.js +185 -0
- package/src/library/originals/GridDropLibrary_0402.js +202 -0
- package/src/library/originals/HistoryLibrary_0402.js +98 -0
- package/src/library/originals/LayoutLibrary_0402.js +264 -0
- package/src/utils/index.js +8 -3
package/package.json
CHANGED
|
@@ -31,8 +31,8 @@ const props = defineProps({
|
|
|
31
31
|
const { activeDesign } = toRefs(props.polarvo.display.state);
|
|
32
32
|
const { setActiveDesign } = props.polarvo.display;
|
|
33
33
|
|
|
34
|
-
const {
|
|
35
|
-
const sectionMode = computed(() =>
|
|
34
|
+
const { activeMode, activeSection } = toRefs(props.polarvo.layout.state);
|
|
35
|
+
const sectionMode = computed(() => activeMode.value);
|
|
36
36
|
|
|
37
37
|
const { activeElement: freeActiveElement } = toRefs(props.polarvo.freeDrop.state);
|
|
38
38
|
const { activeElement: gridActiveElement } = toRefs(props.polarvo.gridDrop.state);
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
name="px"
|
|
23
23
|
aria-label="픽셀 단위 크기"
|
|
24
24
|
min="600"
|
|
25
|
-
max="
|
|
25
|
+
max="1200"
|
|
26
26
|
step="50"
|
|
27
27
|
:value="displaySize?.px"
|
|
28
28
|
class="border-b-2 pr-1 border-white focus:outline-none focus:border-b-2 focus:border-blue-500"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
name="percent"
|
|
35
35
|
aria-label="퍼센트 단위 크기"
|
|
36
36
|
min="0"
|
|
37
|
-
max="
|
|
37
|
+
max="200"
|
|
38
38
|
step="10"
|
|
39
39
|
:value="displaySize?.percent"
|
|
40
40
|
class="border-b-2 pr-1 border-white focus:outline-none focus:border-b-2 focus:border-blue-500"
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
<div class="text-sm">보조선 표시</div>
|
|
19
19
|
<input
|
|
20
20
|
type="checkbox"
|
|
21
|
-
:checked="
|
|
22
|
-
@change="
|
|
21
|
+
:checked="activeConfig?.showGuideLine"
|
|
22
|
+
@change="handleSectionConfigChange('guideLine', $event.target.checked)"
|
|
23
23
|
/>
|
|
24
24
|
</div>
|
|
25
25
|
</template>
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
min="1"
|
|
34
34
|
max="50"
|
|
35
35
|
class="text-sm text-center w-6 border-b-2 border-white focus:outline-none focus:border-b-2 focus:border-blue-500"
|
|
36
|
-
:value="
|
|
37
|
-
@change="
|
|
36
|
+
:value="activeConfig?.gridRows"
|
|
37
|
+
@change="handleSectionConfigChange('row', $event.target.value)"
|
|
38
38
|
/>
|
|
39
39
|
</div>
|
|
40
40
|
<div class="flex items-center gap-1">
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
min="1"
|
|
46
46
|
max="12"
|
|
47
47
|
class="text-sm text-center w-6 border-b-2 border-white focus:outline-none focus:border-b-2 focus:border-blue-500"
|
|
48
|
-
:value="
|
|
49
|
-
@change="
|
|
48
|
+
:value="activeConfig?.gridColumns"
|
|
49
|
+
@change="handleSectionConfigChange('column', $event.target.value)"
|
|
50
50
|
/>
|
|
51
51
|
</div>
|
|
52
52
|
<div class="flex items-center gap-1">
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
min="0"
|
|
58
58
|
max="12"
|
|
59
59
|
class="text-sm text-center w-6 border-b-2 border-white focus:outline-none focus:border-b-2 focus:border-blue-500"
|
|
60
|
-
:value="
|
|
61
|
-
@change="
|
|
60
|
+
:value="activeConfig?.gridGap"
|
|
61
|
+
@change="handleSectionConfigChange('gap', $event.target.value)"
|
|
62
62
|
/>
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
@@ -77,9 +77,17 @@ const props = defineProps({
|
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
-
const { activeSection,
|
|
80
|
+
const { activeSection, activeMode, activeConfig } = toRefs(props.polarvo.layout.state);
|
|
81
81
|
const { setSectionMode, setSectionConfig } = props.polarvo.layout;
|
|
82
|
-
const sectionMode = computed(() =>
|
|
82
|
+
const sectionMode = computed(() => activeMode.value);
|
|
83
|
+
|
|
84
|
+
function handleSectionConfigChange(type, value) {
|
|
85
|
+
const { result, message } = setSectionConfig(type, value)
|
|
86
|
+
|
|
87
|
+
if (!result) {
|
|
88
|
+
alert(message)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
83
91
|
</script>
|
|
84
92
|
|
|
85
93
|
<style scoped lang="scss">
|
|
@@ -23,10 +23,16 @@ const props = defineProps({
|
|
|
23
23
|
},
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
const DEFAULT_DISPLAY_SIZE = {
|
|
27
|
+
px: 1200,
|
|
28
|
+
percent: 100,
|
|
29
|
+
gridSize: 16,
|
|
30
|
+
aspectRatio: '16/9',
|
|
31
|
+
};
|
|
32
|
+
|
|
26
33
|
// height 관련 여유 공간 추가하여 계산함 (50, 200)
|
|
27
34
|
const { displaySize } = toRefs(props.polarvo.display.state);
|
|
28
35
|
const { elements } = toRefs(props.polarvo.layout.state);
|
|
29
|
-
const gridSize = computed(() => displaySize.value?.gridSize || 16);
|
|
30
36
|
const defaultHeight = computed(() => {
|
|
31
37
|
return (
|
|
32
38
|
elements.value?.reduce((max, el) => {
|
|
@@ -52,19 +58,37 @@ function expandContainer() {
|
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
const containerStyle = computed(() => {
|
|
61
|
+
if (!displaySize.value) {
|
|
62
|
+
return {
|
|
63
|
+
aspectRatio: DEFAULT_DISPLAY_SIZE.aspectRatio,
|
|
64
|
+
width: `${DEFAULT_DISPLAY_SIZE.px}px`,
|
|
65
|
+
height: `${displayHeight.value}px`,
|
|
66
|
+
margin: '0 auto',
|
|
67
|
+
transform: `scale(${DEFAULT_DISPLAY_SIZE.percent / 100})`,
|
|
68
|
+
transformOrigin: 'top center',
|
|
69
|
+
backgroundImage: `
|
|
70
|
+
linear-gradient(rgba(0,0,0,0.05) 1px, transparent 1px),
|
|
71
|
+
linear-gradient(90deg, rgba(0,0,0,0.05) 1px, transparent 1px)
|
|
72
|
+
`,
|
|
73
|
+
backgroundSize: `${DEFAULT_DISPLAY_SIZE.gridSize}px ${DEFAULT_DISPLAY_SIZE.gridSize}px`,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
return {
|
|
56
|
-
aspectRatio: displaySize.value
|
|
57
|
-
width: `${displaySize.value
|
|
78
|
+
aspectRatio: displaySize.value.aspectRatio,
|
|
79
|
+
width: `${displaySize.value.px}px`,
|
|
58
80
|
height: `${displayHeight.value}px`,
|
|
59
|
-
margin:
|
|
60
|
-
transform: `scale(${displaySize.value
|
|
81
|
+
margin: '0 auto',
|
|
82
|
+
transform: `scale(${displaySize.value.percent / 100})`,
|
|
61
83
|
transformOrigin: 'top center',
|
|
62
84
|
backgroundImage: `
|
|
63
85
|
linear-gradient(rgba(0,0,0,0.05) 1px, transparent 1px),
|
|
64
86
|
linear-gradient(90deg, rgba(0,0,0,0.05) 1px, transparent 1px)
|
|
65
87
|
`,
|
|
66
|
-
backgroundSize: `${
|
|
88
|
+
backgroundSize: `${displaySize.value.gridSize}px ${displaySize.value.gridSize}px`,
|
|
67
89
|
};
|
|
90
|
+
|
|
91
|
+
|
|
68
92
|
});
|
|
69
93
|
|
|
70
94
|
// 전체 elements
|
|
@@ -29,8 +29,8 @@ const props = defineProps({
|
|
|
29
29
|
const { addElement: addElementToFree } = props.polarvo.freeDrop;
|
|
30
30
|
const { addElement: addElementToGrid } = props.polarvo.gridDrop;
|
|
31
31
|
|
|
32
|
-
const {
|
|
33
|
-
const sectionMode = computed(() =>
|
|
32
|
+
const { activeMode } = toRefs(props.polarvo.layout.state);
|
|
33
|
+
const sectionMode = computed(() => activeMode.value);
|
|
34
34
|
|
|
35
35
|
const allElements = ref([]);
|
|
36
36
|
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
id="row-count"
|
|
26
26
|
min="1"
|
|
27
27
|
max="50"
|
|
28
|
-
:value="
|
|
29
|
-
@change="
|
|
28
|
+
:value="activeConfig.gridRows"
|
|
29
|
+
@change="handleSectionConfigChange('row', $event.target.value)"
|
|
30
30
|
/>
|
|
31
31
|
</div>
|
|
32
32
|
<div class="flex flex-row items-center gap-4">
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
id="column-count"
|
|
38
38
|
min="1"
|
|
39
39
|
max="12"
|
|
40
|
-
:value="
|
|
41
|
-
@change="
|
|
40
|
+
:value="activeConfig.gridColumns"
|
|
41
|
+
@change="handleSectionConfigChange('column', $event.target.value)"
|
|
42
42
|
/>
|
|
43
43
|
</div>
|
|
44
44
|
<div class="flex flex-row items-center gap-4">
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
id="gap-size"
|
|
50
50
|
min="0"
|
|
51
51
|
max="12"
|
|
52
|
-
:value="
|
|
53
|
-
@change="
|
|
52
|
+
:value="activeConfig.gridGap"
|
|
53
|
+
@change="handleSectionConfigChange('gap', $event.target.value)"
|
|
54
54
|
/>
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
class="text-sm w-4 h-4 border-b-2 border-white focus:outline-none focus:border-b-2 focus:border-blue-500"
|
|
64
64
|
type="checkbox"
|
|
65
65
|
id="guide-line"
|
|
66
|
-
:checked="
|
|
67
|
-
@change="
|
|
66
|
+
:checked="activeConfig.showGuideLine"
|
|
67
|
+
@change="handleSectionConfigChange('guideLine', $event.target.checked)"
|
|
68
68
|
/>
|
|
69
69
|
</div>
|
|
70
70
|
</div>
|
|
@@ -81,10 +81,18 @@ const props = defineProps({
|
|
|
81
81
|
required: true,
|
|
82
82
|
},
|
|
83
83
|
});
|
|
84
|
-
const {
|
|
84
|
+
const { activeMode, activeConfig } = toRefs(props.polarvo.layout.state);
|
|
85
85
|
const { setSectionMode, setSectionConfig } = props.polarvo.layout;
|
|
86
86
|
|
|
87
|
-
const sectionMode = computed(() =>
|
|
87
|
+
const sectionMode = computed(() => activeMode.value);
|
|
88
|
+
|
|
89
|
+
function handleSectionConfigChange(type, value) {
|
|
90
|
+
const { result, message } = setSectionConfig(type, value)
|
|
91
|
+
|
|
92
|
+
if (!result) {
|
|
93
|
+
alert(message)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
88
96
|
</script>
|
|
89
97
|
|
|
90
98
|
<style lang="scss" scoped></style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div class="aspect-[3/2] border border-gray-200 rounded-md bg-white
|
|
3
|
+
<div class="aspect-[3/2] border border-gray-200 rounded-md bg-white">
|
|
4
4
|
<BaseLayout id="preview" :polarvo="polarvo" :preview="true" @click:section="setActiveSection($event)" />
|
|
5
5
|
<button
|
|
6
6
|
class="text-sm bg-blue-100 text-center w-full py-1 hover:cursor-pointer hover:bg-blue-200 active:opacity-80"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
type="number"
|
|
36
36
|
:id="`col-ratio-${column}`"
|
|
37
37
|
:value="gridRatio.column[column - 1]"
|
|
38
|
-
@change="
|
|
38
|
+
@change="handleGridRatio('column', column - 1, $event)"
|
|
39
39
|
/>
|
|
40
40
|
</template>
|
|
41
41
|
</div>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
type="number"
|
|
49
49
|
:id="`row-ratio-${row}`"
|
|
50
50
|
:value="gridRatio.row[row - 1]"
|
|
51
|
-
@change="
|
|
51
|
+
@change="handleGridRatio('row', row - 1, $event)"
|
|
52
52
|
/>
|
|
53
53
|
</template>
|
|
54
54
|
</div>
|
|
@@ -60,11 +60,7 @@
|
|
|
60
60
|
현재 활성화 섹션:
|
|
61
61
|
<span class="text-sm text-red-400 font-medium cursor-default">{{ activeSection }}</span>
|
|
62
62
|
</h5>
|
|
63
|
-
<LayoutSetting
|
|
64
|
-
v-if="activeSection !== null"
|
|
65
|
-
:polarvo="polarvo"
|
|
66
|
-
class="mt-2 border border-gray-200 rounded-md bg-white"
|
|
67
|
-
/>
|
|
63
|
+
<LayoutSetting v-if="activeSection !== null" :polarvo="polarvo" class="mt-2 border border-gray-200 rounded-md bg-white" />
|
|
68
64
|
<div v-else>
|
|
69
65
|
<div class="text-center text-sm text-red-400 bg-red-50 mt-1 py-1 cursor-default">선택된 섹션이 없습니다.</div>
|
|
70
66
|
</div>
|
|
@@ -86,4 +82,19 @@ const props = defineProps({
|
|
|
86
82
|
});
|
|
87
83
|
const { layoutName, activeSection, gapSize, gridNumber, gridRatio } = toRefs(props.polarvo.layout.state);
|
|
88
84
|
const { setGapSize, setRatio, setActiveSection } = props.polarvo.layout;
|
|
85
|
+
|
|
86
|
+
function handleGridRatio(type, index, event) {
|
|
87
|
+
const value = event.target.value;
|
|
88
|
+
if (Number(value) > 100 || Number(value) < 0 || isNaN(Number(value))) {
|
|
89
|
+
alert('비율은 0에서 100 사이의 숫자여야 합니다.');
|
|
90
|
+
event.target.value = gridRatio.value[type][index]; // 원래 값으로 복원
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const { result, message } = setRatio(type, index, value)
|
|
95
|
+
|
|
96
|
+
if (!result) {
|
|
97
|
+
alert(message)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
89
100
|
</script>
|
package/src/configs/index.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { omit } from 'lodash-es';
|
|
2
|
-
|
|
3
1
|
// event 발행 시 'display'으로 시작하는 이름 사용
|
|
2
|
+
const DISPLAY_LIMITS = {
|
|
3
|
+
percent: { max: 200, min: 0, unit: '%', name: '배율' },
|
|
4
|
+
px: { max: 1200, min: 1, unit: 'px', name: '크기' },
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const DEFAULT_DISPLAY_SIZE = {
|
|
8
|
+
px: 1200,
|
|
9
|
+
percent: 100,
|
|
10
|
+
gridSize: 16,
|
|
11
|
+
aspectRatio: '16/9',
|
|
12
|
+
};
|
|
13
|
+
|
|
4
14
|
class DisplayEngine {
|
|
5
15
|
constructor({ eventBus, options }) {
|
|
6
16
|
this.eventBus = eventBus;
|
|
@@ -11,6 +21,8 @@ class DisplayEngine {
|
|
|
11
21
|
this.displayMode = 'desktop'; // 현재 디스플레이 모드 (초기값 = 'desktop')
|
|
12
22
|
this.displaySize = null;
|
|
13
23
|
|
|
24
|
+
this._resetDisplaySizeByMode(this.displayMode);
|
|
25
|
+
|
|
14
26
|
this._subscriptions = []; // 구독 해제 함수 저장용
|
|
15
27
|
this._setupSubscriptions();
|
|
16
28
|
}
|
|
@@ -31,20 +43,8 @@ class DisplayEngine {
|
|
|
31
43
|
_setupSubscriptions() {
|
|
32
44
|
// 초기화 완료 이벤트 구독 - from EngineManager
|
|
33
45
|
this._subscribe('system:engineInitialized', () => {
|
|
34
|
-
this._resetDisplaySizeByMode(this.displayMode);
|
|
35
|
-
|
|
36
46
|
this.eventBus.emit('display:engineInitialized', {
|
|
37
|
-
displaySize: this.displaySize,
|
|
38
|
-
timestamp: Date.now(),
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
this._subscribe('system:enginesReset', () => {
|
|
43
|
-
this.displayMode = 'desktop';
|
|
44
|
-
this._resetDisplaySizeByMode(this.displayMode);
|
|
45
|
-
|
|
46
|
-
this.eventBus.emit('display:enginesReset', {
|
|
47
|
-
displaySize: this.displaySize,
|
|
47
|
+
$displaySize: this.displaySize,
|
|
48
48
|
timestamp: Date.now(),
|
|
49
49
|
});
|
|
50
50
|
});
|
|
@@ -54,15 +54,9 @@ class DisplayEngine {
|
|
|
54
54
|
this.setActiveDesign(null);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
this._subscribe('layout:setLayoutName', ({ screenConfig }) => {
|
|
58
|
-
this.displayMode = screenConfig.displayMode;
|
|
59
|
-
this.displaySize = {
|
|
60
|
-
|
|
61
|
-
this.eventBus.emit('display:setLayoutName', {
|
|
62
|
-
displayMode: this.displayMode,
|
|
63
|
-
displaySize: this.displaySize,
|
|
64
|
-
timestamp: Date.now(),
|
|
65
|
-
});
|
|
57
|
+
this._subscribe('layout:setLayoutName', ({ $screenConfig }) => {
|
|
58
|
+
this.displayMode = $screenConfig.displayMode;
|
|
59
|
+
this.displaySize = { ...$screenConfig.displaySize };
|
|
66
60
|
});
|
|
67
61
|
|
|
68
62
|
this._subscribe('freeDrop:startDrag', () => {
|
|
@@ -72,19 +66,27 @@ class DisplayEngine {
|
|
|
72
66
|
|
|
73
67
|
this._subscribe('gridDrop:setActiveElement', ({ action }) => {
|
|
74
68
|
if (action === 'update') return;
|
|
75
|
-
|
|
76
|
-
// this.setActiveMenu('element');
|
|
77
|
-
// } else {
|
|
78
|
-
this.setActiveMenu(null);
|
|
79
|
-
// }
|
|
80
|
-
|
|
69
|
+
this.setActiveMenu(null);
|
|
81
70
|
this.setActiveDesign(null);
|
|
82
71
|
});
|
|
83
72
|
|
|
84
73
|
this._subscribe('gridDrop:requestOpenElementBar', () => {
|
|
85
74
|
this.setActiveMenu('element');
|
|
86
75
|
this.setActiveDesign(null);
|
|
87
|
-
})
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** 엔진 초기화 */
|
|
80
|
+
reset() {
|
|
81
|
+
this.activeMenu = null;
|
|
82
|
+
this.activeDesign = null;
|
|
83
|
+
this.displayMode = 'desktop';
|
|
84
|
+
this._resetDisplaySizeByMode(this.displayMode);
|
|
85
|
+
|
|
86
|
+
this.eventBus.emit('display:enginesReset', {
|
|
87
|
+
$displaySize: this.displaySize,
|
|
88
|
+
timestamp: Date.now(),
|
|
89
|
+
});
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
/** 삭제 및 정리 */
|
|
@@ -95,6 +97,8 @@ class DisplayEngine {
|
|
|
95
97
|
}
|
|
96
98
|
});
|
|
97
99
|
|
|
100
|
+
this.reset();
|
|
101
|
+
|
|
98
102
|
this._subscriptions = [];
|
|
99
103
|
this.eventBus = null;
|
|
100
104
|
this.resource = null;
|
|
@@ -130,7 +134,6 @@ class DisplayEngine {
|
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/** ---------------------------------- 공통 메소드 ---------------------------------- **/
|
|
133
|
-
|
|
134
137
|
/** 아이콘바 메뉴 변경
|
|
135
138
|
* @param {string} name - 메뉴 이름
|
|
136
139
|
*/
|
|
@@ -139,7 +142,7 @@ class DisplayEngine {
|
|
|
139
142
|
this.activeMenu = name;
|
|
140
143
|
|
|
141
144
|
this.eventBus.emit('display:updateActiveMenu', {
|
|
142
|
-
menu: name,
|
|
145
|
+
$menu: name,
|
|
143
146
|
timestamp: Date.now(),
|
|
144
147
|
});
|
|
145
148
|
}
|
|
@@ -152,7 +155,7 @@ class DisplayEngine {
|
|
|
152
155
|
this.activeDesign = name;
|
|
153
156
|
|
|
154
157
|
this.eventBus.emit('display:updateActiveDesign', {
|
|
155
|
-
design: name,
|
|
158
|
+
$design: name,
|
|
156
159
|
timestamp: Date.now(),
|
|
157
160
|
});
|
|
158
161
|
}
|
|
@@ -168,15 +171,16 @@ class DisplayEngine {
|
|
|
168
171
|
|
|
169
172
|
if (this.displayMode === mode) return;
|
|
170
173
|
|
|
174
|
+
const prevDisplayMode = this.displayMode;
|
|
171
175
|
this.displayMode = mode;
|
|
172
176
|
const prevDisplaySize = { ...this.displaySize };
|
|
173
177
|
this._resetDisplaySizeByMode(mode);
|
|
174
178
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
displayMode: this.displayMode,
|
|
178
|
-
displaySize: this.displaySize,
|
|
179
|
-
prev: { displaySize: prevDisplaySize },
|
|
179
|
+
this.eventBus.emit('display:displayChanged', {
|
|
180
|
+
type: 'mode',
|
|
181
|
+
$displayMode: this.displayMode,
|
|
182
|
+
$displaySize: this.displaySize,
|
|
183
|
+
prev: { displayMode: prevDisplayMode, displaySize: prevDisplaySize },
|
|
180
184
|
timestamp: Date.now(),
|
|
181
185
|
});
|
|
182
186
|
}
|
|
@@ -185,14 +189,19 @@ class DisplayEngine {
|
|
|
185
189
|
* @param {string} mode - 디스플레이 모드
|
|
186
190
|
*/
|
|
187
191
|
_resetDisplaySizeByMode(mode) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
gridSize: this.resource[mode]?.gridSize || 16,
|
|
193
|
-
aspectRatio: this.resource[mode]?.aspectRatio || '16/9',
|
|
194
|
-
};
|
|
192
|
+
const defaults = DEFAULT_DISPLAY_SIZE;
|
|
193
|
+
if (!this.resource[mode]) {
|
|
194
|
+
this.displaySize = { ...defaults };
|
|
195
|
+
return;
|
|
195
196
|
}
|
|
197
|
+
|
|
198
|
+
const resource = this.resource[mode];
|
|
199
|
+
this.displaySize = {
|
|
200
|
+
px: resource.defaultWidth ?? defaults.px,
|
|
201
|
+
percent: defaults.percent,
|
|
202
|
+
gridSize: resource.gridSize ?? defaults.gridSize,
|
|
203
|
+
aspectRatio: resource.aspectRatio ?? defaults.aspectRatio,
|
|
204
|
+
};
|
|
196
205
|
}
|
|
197
206
|
|
|
198
207
|
/** displaySize 변경
|
|
@@ -201,34 +210,33 @@ class DisplayEngine {
|
|
|
201
210
|
*/
|
|
202
211
|
setDisplaySize(type, size) {
|
|
203
212
|
if (!['px', 'percent'].includes(type)) {
|
|
204
|
-
|
|
205
|
-
return;
|
|
213
|
+
return { result: false, message: '입력할 수 없는 사이즈 타입입니다.' };
|
|
206
214
|
}
|
|
207
|
-
|
|
208
215
|
const numSize = Number(size);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
216
|
+
const limit = DISPLAY_LIMITS[type];
|
|
217
|
+
const result = {result: true, message: '사이즈가 성공적으로 변경되었습니다.'};
|
|
213
218
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
219
|
+
if (isNaN(numSize) || numSize <= limit.min) {
|
|
220
|
+
result.result = false;
|
|
221
|
+
result.message = `설정 가능한 최소 ${limit.name}는 ${limit.min}${limit.unit}입니다.`;
|
|
222
|
+
}
|
|
218
223
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
224
|
+
if (isNaN(numSize) || numSize > limit.max) {
|
|
225
|
+
result.result = false;
|
|
226
|
+
result.message = `설정 가능한 최대 ${limit.name}는 ${limit.max}${limit.unit}입니다.`;
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
const prevDisplaySize = { ...this.displaySize };
|
|
225
|
-
this.displaySize[type] = Math.min(Math.max(0, numSize),
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
this.displaySize[type] = Math.min(Math.max(0, numSize), limit.max);
|
|
231
|
+
this.eventBus.emit('display:displayChanged', {
|
|
232
|
+
type: 'size',
|
|
233
|
+
$displayMode: this.displayMode,
|
|
234
|
+
$displaySize: this.displaySize,
|
|
229
235
|
prev: { displaySize: prevDisplaySize },
|
|
230
236
|
timestamp: Date.now(),
|
|
231
237
|
});
|
|
238
|
+
|
|
239
|
+
return result;
|
|
232
240
|
}
|
|
233
241
|
}
|
|
234
242
|
|