
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" style="margin-top : 30px">
<div class="content title-box aibox">
<p class="title mt25 title-bg">모르는 단어를 물어봐~!</p>
<div class="propmt-container">
<div class="input-conatiner">
<input v-model="word" @keyup.enter="startProgress(word)"/>
<button @click="startProgress(word)"> <p> 생성하기 </p> </button>
</div>
<div class="progress-container">
<div class="progress-bar" :style="{ width: progressWidth + '%' }">{{ Math.floor(progressWidth) }}%</div>
<!-- 로딩 이미지 -->
<div v-if="progressWidth < 100 && progressWidth > 1" 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">
<img :src="imageSrc"/>
<div class="word-container">
<h2> {{ inputWord }} </h2>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
progressWidth: 0,
inputWord : "",
// 하드 코딩 -> 수정 필요 : API
word : "",
imageSrc : "",
imageData: null, // 서버에서 받아온 이미지 데이터 저장
visibleWord : false,
};
},
mounted() {
},
methods: {
// 상태 진행 바(progress bar)
startProgress(word) {
if (this.progressWidth == 100) {
this.resetProgress();
}
if (this.progressWidth > 0) return; // 이미 진행 중이면 중복 실행 방지
this.setWord(word);
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; // 이미지 데이터 초기화
},
// 이미지 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;
gap: 30px;
height: 50px;
}
.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: 100%;
background-color: #ffffff;
border-radius: 5px;
overflow: hidden;
margin-top: 20px;
display : flex;
flex-direction: column;
gap :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;
margin-top : 30px;
padding-bottom : 40px;
}
.loading-gif{
width: 25%;
border-radius: 500px;
}
.loading-container p {
font-size : 25px;
}
/* 결과 container */
.result-container{
margin-top: 30px;
display: flex;
flex-direction: column;
align-items: center;
gap: 30px;
}
.result-container img{
width : 30%;
}
.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;
}
</style>