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="flex justify-center align-center">
<div class="propmt-container">
<div class="input-conatiner">
<input v-model="word" @keyup.enter="startProgress(word)" placeholder="궁금한 단어를 검색해보세요!" />
<button @click="startProgress(word)">
<img src="../../resources/img/new_img/icon/search-icon.png" style="width: 52px" />
</button>
</div>
</div>
<div class="modal-container flex" v-if="!modalClose">
<div class="progress-container" v-if="progressWidth < 100 && progressWidth > 1">
<div class="progress-bar" :style="{ width: progressWidth + '%' }">{{ Math.floor(progressWidth) }}%</div>
<!-- 로딩 이미지 -->
<div class="loading-container">
<img src="../../resources/img/jumpingRabbit.gif" alt="Loading" class="loading-gif" />
<p>잠깐만 기다려봐~</p>
</div>
</div>
<div v-if="visibleWord" class="result-container">
<div class="flex align-center modal-box">
<img :src="imageSrc" />
<div class="word-container">
<h2>{{ inputWord }}</h2>
</div>
</div>
<button @click="handleModalClose">
<img src="../../resources/img/btn25_93t_normal.png" alt="" style="width: auto" />
</button>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
progressWidth: 0,
inputWord: '',
word: '',
imageSrc: '',
imageData: null, // 서버에서 받아온 이미지 데이터 저장
visibleWord: false,
modalClose: true, // 초기 상태 === 닫힘
};
},
mounted() {},
methods: {
// 상태 진행 바(progress bar)
startProgress(word) {
if (!word.trim()) {
alert('검색할 단어를 입력해주세요.');
return; // 입력이 없으면 함수 종료
}
this.modalClose = false;
if (this.progressWidth == 100) {
this.resetProgress();
}
if (this.progressWidth > 0) return; // 이미 진행 중이면 중복 실행 방지
const interval = 300; // 30ms
const totalDuration = 3000; // 총 시간 : 10초
const steps = totalDuration / interval;
const increment = 100 / steps;
const progressInterval = setInterval(() => {
this.progressWidth += increment;
if (this.progressWidth >= 100) {
this.progressWidth = 100;
clearInterval(progressInterval);
this.visibleWord = true;
// 진행이 완료된 후에 이미지 데이터 렌더링
if (this.imageData) {
this.imageSrc = this.imageUrl;
}
}
}, interval);
this.getAiImage();
},
setWord(word) {
if (this.progressWidth > 0 && this.progressWidth < 100) return; // progressWidth가 0 또는 100이 아니면 실행 중지
this.inputWord = word;
this.visibleWord = false;
},
resetProgress() {
this.progressWidth = 0;
this.visibleWord = false;
this.imageSrc = ''; // 이미지 URL 초기화
this.imageData = null; // 이미지 데이터 초기화
this.word = '';
},
handleModalClose() {
this.resetProgress();
this.modalClose = true;
console.log('모달 상태 : ', this.modalClose);
},
// 이미지 API
async getAiImage() {
const url = 'http://takensoftai.iptime.org:20200/generate_json';
// console.log(`word : ${this.word}`);
try {
const response = await axios({
url: url,
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
responseType: 'arraybuffer',
data: {
text: this.word,
},
});
// console.log(`응답 : ${response}`);
// 바이너리 데이터 -> Blob으로 변환
const blob = new Blob([response.data], { type: 'image/png' });
// Blob에서 객체 URL 생성
const imageUrl = URL.createObjectURL(blob);
// 이미지 URL 설정
this.imageSrc = imageUrl;
} catch (err) {
console.log(err);
}
},
},
};
</script>
<style>
.propmt-container {
/*padding: 0px 50px 30px 50px;*/
}
/* 입력 컨테이너 */
.input-conatiner {
display: flex;
align-items: center;
width: 80rem;
}
.input-conatiner input {
width: 90%;
height: 100%;
padding: 10px 30px;
border: none;
border-radius: 10px;
box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
outline: none;
font-size: 28px;
}
.input-conatiner button {
width: 15%;
height: 100%;
border: none;
border-radius: 10px;
cursor: pointer;
/*background-color: #ffba08;*/
display: flex;
justify-content: center;
align-items: center;
}
.input-conatiner button p {
font-size: 28px;
}
/* 진행 상태바 */
.progress-container {
width: 50rem;
height: fit-content;
background-color: #ffffff;
border-radius: 10px;
overflow: hidden;
display: flex;
flex-direction: column;
gap: 30px;
padding: 30px;
}
.progress-bar {
height: 30px;
width: 0;
background-color: #4caf50;
text-align: center;
line-height: 30px;
color: white;
border: none;
border-radius: 5px;
transition: width 0.3s;
font-size: 20px;
}
/* 로딩 gif */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 30px;
text-align: center;
}
.loading-gif {
width: 52%;
border-radius: 500px;
}
.loading-container p {
font-size: 25px;
}
/* 결과 container */
.result-container {
display: flex;
flex-direction: row;
align-items: flex-start;
background-color: #fff;
padding: 30px;
border-radius: 10px;
width: 50rem;
height: 100%;
}
.result-container img {
width: 60%;
}
.word-container {
width: 30%;
text-align: center;
padding: 20px 0px;
border: 3px solid #4caf50;
border-radius: 8px;
display: flex;
flex-direction: column;
gap: 15px;
}
.word-container h2 {
font-size: 28px;
}
.aibox {
display: flex;
flex-direction: column;
justify-content: center;
height: auto;
padding: 30px 0px;
}
.modal-container {
width: 50rem;
height: 40rem;
border-radius: 10px;
z-index: 100;
position: absolute;
top: 25rem;
right: 10%;
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
}
.modal-box {
gap: 30px;
margin-top: 10%;
margin-left: 5%;
}
</style>