
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div class="w_100 h_100 layout sterech gap30">
<div class="left-zone">
<div class="prompt-zone mb10">
<div class="tabs layout center">
<button
v-for="tab in tabs"
:key="tab"
:class="{ active: activeTab === tab }"
@click="activeTab = tab"
>
{{ tab }}
</button>
</div>
<div class="tab-content">
<div class="layout center justify-center h_100" style="background-color: #ffffff; border-radius: 2rem;" v-if="activeTab === 'Image Prompt'">
<div class="layout center center" style="flex-direction: column;">
<input type="file" name="" id="file" class="sr-only">
<span class="file-icon" id="file"><img src="../../../resources/img/content/ico_file.svg" alt=""></span>
<label for="file" style="text-align: center;">파일을 업로드하세요.</label>
</div>
</div>
<div class="h_100" v-else-if="activeTab === 'Text Prompt'">
<textarea class="form-control sm" style="height: 100%;" placeholder="텍스트를 입력하세요."></textarea>
</div>
</div>
</div>
<div class="btn-zone gap10 mb30">
<button class="btn md ico-before ico-reset">초기화</button>
<button class="btn md ico-before ico-3d">3D 변환</button>
</div>
<div class="direction-zone mb30">
<ul>
<li v-for="btn in buttons" :key="btn.icon" class="button-list">
<button class="layout center gap10">
<span class="icon-wrap"><img :src="btn.icon" :alt="btn.label + ' 아이콘'" ></span>
<span class="button-font"> {{ btn.label }}</span>
</button>
</li>
</ul>
</div>
<div class="zoom-container" tabindex="0">
<div class="zoom-controls">
<button @click="decreaseZoom" aria-label="Zoom out">-</button>
<input
type="range"
min="50"
max="200"
step="5"
v-model="zoom"
@input="updateZoom"
aria-label="Zoom level"
/>
<button @click="increaseZoom" aria-label="Zoom in">+</button>
</div>
<div class="zoom-display">{{ zoom }}%</div>
</div>
</div>
<div class="right-zone stretch">
<div class="canvas-zone h_100">
<div class="top-zone layout center space-between">
<!-- 왼쪽 툴 -->
<ul class="toolbar left layout gap10">
<li
v-for="tool in subTolls.slice(0, 3)"
:key="tool.id"
>
<button :title="tool.title" @click="toggleTool(tool)">
<img :src="tool.icon" :alt="tool.title + ' 아이콘'" style="vertical-align: middle;"/>
</button>
</li>
</ul>
<!-- 오른쪽 툴 -->
<ul class="toolbar right layout gap10">
<li
v-for="tool in subTolls.slice(-4)"
:key="tool.id"
:class="{ active: activeToolId === tool.id && !activeSubToolId }"
style="position: relative;">
<button :title="tool.title" @click="toggleTool(tool)" >
<img :src="tool.icon" :alt="tool.title + ' 아이콘'" style="vertical-align: middle;"/>
</button>
<div v-if="activeModalTool?.id === tool.id" class="custom-modal">
<div class="modal-content">
<p class="modeling-title">{{ activeModalTool.title }}</p>
<div class="modeling-content">
<ul v-if="activeModalTool.title === '참여자'">
<li>참여자1</li>
<li>참여자1</li>
<li>참여자1</li>
<li>참여자1</li>
</ul>
<div v-else-if="activeModalTool.title === '코멘트'">
<div class="input-group mb10">
<label for="">writer</label>
<input type="text" class="form-control sm" disabled>
</div>
<div class="input-group mb10">
<label for="">summary</label>
<input type="text" class="form-control sm">
</div>
<div class="input-group">
<label for="">comment</label>
<textarea class="form-control sm"></textarea>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<div class="bottom-zone"></div>
</div>
<div class="equipment-zone h_100">
<div class="button-collection h_100">
<ul>
<li
v-for="tool in tools"
:key="tool.id"
:data-tool-id="tool.id"
:class="{ active: activeToolId === tool.id }"
style="position: relative;">
<button
:title="tool.title"
@click="toggleTool(tool)"
>
<img :src="getToolIcon(tool)" :alt="tool.title + ' 아이콘'" />
<input
type="color"
:ref="'colorInput_' + tool.id"
v-model="selectedColor"
@input.stop
v-if="tool.type === 'palette' && openedToolId === tool.id" class="palette-picker"
/>
</button>
<!-- 자식 버튼이 있을 경우 -->
<ul
v-if="tool.children && tool.children.length && openedToolId === tool.id"
class="child-buttons"
>
<li
v-for="child in tool.children"
:key="child.id"
:class="{ active: activeSubToolId === child.id }"
@click.stop="selectSubTool(tool, child)"
>
<button :title="child.title">
{{ child.title }}
</button>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tabs: ['Image Prompt', 'Text Prompt', ],
activeTab: 'Image Prompt',
buttons: [
{ icon: require('../../../resources/img/content/ico_right.svg'), label: '오른쪽으로 90도 회전(R)' },
{ icon: require('../../../resources/img/content/ico_left.svg'), label: '왼쪽으로 90도 회전(L)' },
{ icon: require('../../../resources/img/content/ico_top_bottom.svg'), label: '상하 대칭' },
{ icon: require('../../../resources/img/content/ico_left_right.svg'), label: '좌우 대칭' }
],
zoom: 100,
tools: [
{
id: 1,
icon: {
normal: require('../../../resources/img/content/ico_move_w.svg'),
active: require('../../../resources/img/content/ico_move.svg'),
},
title: '이동도구',
children: []
},
{
id: 2,
icon: {
normal: require('../../../resources/img/content/ico_3dview_w.svg'),
active: require('../../../resources/img/content/ico_3dview.svg'),
},
title: '크기조절도구',
children: []
},
{
id: 3,
icon: {
normal: require('../../../resources/img/content/ico_copy_w.svg'),
active: require('../../../resources/img/content/ico_copy.svg'),
},
title: '복사도구',
children: []
},
{
id: 4,
icon: {
normal: require('../../../resources/img/content/ico_crop_w.svg'),
active: require('../../../resources/img/content/ico_crop.svg'),
},
title: '자르기 도구',
children: [
{
id: 11,
title: '선택 객체 자르기'
},
{
id: 12,
title: '사용자 지정 자르기'
}
]
},
{
id: 5,
icon: {
normal: require('../../../resources/img/content/ico_punching_w.svg'),
active: require('../../../resources/img/content/ico_punching.svg'),
},
title: '패스도구',
children: [
{
id: 51,
title: '원형 패스 도구'
},
{
id: 52,
title: '사각형 패스 도구'
}
]
},
{
id: 6,
icon: {
normal: require('../../../resources/img/content/ico_palette_w.svg'),
active: require('../../../resources/img/content/ico_palette.svg'),
},
title: '팔레트 도구',
type: 'palette',
children: []
},
{
id: 7,
icon: {
normal: require('../../../resources/img/content/ico_texture_w.svg'),
active: require('../../../resources/img/content/ico_texture.svg'),
},
title: '재질 도구',
children: [
{
id: 71,
title: '금속 재질 도구'
},
{
id: 72,
title: '투명 재질 도구'
},
{
id: 73,
title: '플라스틱 재질 도구'
},
{
id: 74,
title: '목재 재질 도구'
}
]
},
{
id: 8,
icon: {
normal: require('../../../resources/img/content/ico_measure_w.svg'),
active: require('../../../resources/img/content/ico_measure.svg'),
},
title: '길이 측정 도구',
children: []
},
{
id: 9,
icon: {
normal: require('../../../resources/img/content/ico_reset_w.svg'),
active: require('../../../resources/img/content/ico_resett.svg'),
},
title: '초기화',
children: []
},
],
subTolls:[
{
id: 100,
icon: require('../../../resources/img/content/ico_save_w.svg'),
title: '저장',
},
{
id: 200,
icon: require('../../../resources/img/content/ico_turnBack_w.svg'),
title: '뒤로 되돌리기',
},
{
id: 300,
icon: require('../../../resources/img/content/ico_trunFoward_w.svg'),
title: '앞으로 되돌리기',
},
{
id: 400,
icon: require('../../../resources/img/content/ico_user_w.svg'),
title: '참여자',
type: 'modal'
},
{
id: 500,
icon: require('../../../resources/img/content/ico_comment_w.svg'),
title: '코멘트',
type: 'modal'
},
{
id: 600,
icon: require('../../../resources/img/content/ico_share_w.svg'),
title: '공유',
},
{
id: 700,
icon: require('../../../resources/img/content/ico_close_w.svg'),
title: '닫기',
},
],
activeToolId: 1,
activeSubToolId: null,
openedToolId: null,
selectedColor: '#000000',
activeModalTool : false
};
},
methods: {
decreaseZoom() {
if (this.zoom > 50) {
this.zoom -= 5
}
},
increaseZoom() {
if (this.zoom < 200) {
this.zoom += 5
}
},
updateZoom(event) {
this.zoom = Number(event.target.value)
},
toggleTool(tool) {
if (tool.type === 'modal') {
this.openModal(tool);
return;
}
// 기존 도구(tool) 처리 로직
this.activeToolId = tool.id;
if (tool.children && tool.children.length) {
this.openedToolId = this.openedToolId === tool.id ? null : tool.id;
this.activeSubToolId = null;
} else {
this.activeSubToolId = null;
this.openedToolId = tool.id;
}
if (tool.type === 'palette') {
this.$nextTick(() => {
console.log('colorInput ref:', this.$refs.colorInput);
this.$refs.colorInput?.click();
});
}
},
selectSubTool(tool, child) {
this.activeToolId = tool.id;
this.activeSubToolId = child.id;
this.openedToolId = tool.id;
},
openModal(tool) {
this.activeModalTool = tool; // or tool.id
},
closeModal() {
this.activeModalTool = null;
},
},
watch: {},
computed: {
getToolIcon() {
return (tool) => {
const isActive = this.activeToolId === tool.id;
if (tool.icon && typeof tool.icon === 'object') {
return isActive ? tool.icon.active : tool.icon.normal;
}
return tool.icon;
};
}
},
components: {},
created() {},
mounted() {},
beforeUnmount() {},
};
</script>