HTML
<!-- 별 -->
<div id="space" class="space">
<div class="star"></div>
</div>
<!-- 해와 달 -->
<div class="sun"></div>
<div class="moon">
<img src="assets/img/isaac-blog.png" alt="isaac-blog-image" class="moon-image">
<p class="moon-text">클릭 시 기술 블로그로 이동합니다.</p>
</div>
<!-- 해와 달의 파동 -->
<div id="wave-sun" class="wave"></div>
<div id="wave-moon" class="wave"></div>
CSS
.space {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: -1;
}
.star {
position: absolute;
width: 2px;
height: 2px;
background-color: #FFFFFF;
border-radius: 50%;
animation: twinkling infinite;
}
@keyframes twinkling {
0% {
opacity: 0.3;
}
50% {
opacity: 0.8;
}
100% {
opacity: 0.3;
}
}
.sun {
position: fixed;
width: 12rem;
/* 200px */
height: 12rem;
/* 200px */
background-color: #FFFF00;
border-radius: 50%;
top: 80%;
left: 50%;
opacity: 0.9;
transform: translate(-50%, -50%);
transition: top 0.5s, left 0.5s;
z-index: 1;
}
.moon {
position: fixed;
width: 6rem;
/* 100px */
height: 6rem;
/* 100px */
background-color: #FFFFFF;
border-radius: 50%;
top: 180%;
left: 50%;
opacity: 0.9;
transform: translate(-50%, -50%);
transition: top 0.5s, left 0.5s;
z-index: 3;
}
.moon-image {
width: 100%;
height: 100%;
border-radius: 50%;
z-index: 3;
}
.sun,
.moon {
cursor: pointer;
transition: opacity 0.3s ease;
}
.sun:hover {
opacity: 1;
}
.moon:hover {
opacity: 1;
}
/* 달 텍스트 스타일 */
.moon-text {
width: 300px;
left: -130%;
opacity: 0;
transition: opacity 0.5s ease-in-out;
color: white;
position: absolute;
top: 80px;
pointer-events: none; /* 호버 효과 비활성화 */
cursor: default;
}
@keyframes fadeInText {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeOutText {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(20px);
}
}
/* 달 호버 효과 */
.moon:hover .moon-text {
opacity: 1;
animation: fadeInText 0.6s ease-in-out forwards;
}
/* 달이 호버되지 않은 경우 */
.moon:not(:hover) .moon-text {
opacity: 0;
animation: fadeOutText 0.3s ease-in-out forwards;
}
.content {
padding: 20px;
margin-top: 200px;
z-index: 2;
}
section {
margin-bottom: 25px;
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
}
h2 {
color: #ee0000;
}
p {
color: #555;
}
/* 태블릿 가로 화면 (화면 너비 769px - 1024px) */
@media (min-width: 769px) and (max-width: 1024px) {
.sun {
width: 120px;
height: 120px;
}
.moon {
width: 60px;
height: 60px;
}
}
/* 랩탑 화면 (화면 너비 1025px - 1600px) */
@media (min-width: 1025px) and (max-width: 1600px) {
.sun {
width: 150px;
height: 150px;
}
.moon {
width: 75px;
height: 75px;
}
}
/* 파동 효과 */
#wave-sun {
position: fixed;
top: 80%;
left: 50%;
width: 60rem;
/* 1000px */
height: 60rem;
/* 1000px */
background: radial-gradient(circle, rgba(200, 200, 200, 0.6) 0%, rgb(0, 0, 0, 0) 70%);
}
#wave-moon {
position: fixed;
top: 180%;
left: 50%;
width: 50rem;
/* 1000px */
height: 50rem;
/* 1000px */
background: radial-gradient(circle, rgba(230, 230, 230, 0.2) 0%, rgb(0, 0, 0, 0) 60%);
}
.wave {
position: absolute;
transform-origin: center bottom;
animation: waveAnimation 4s infinite alternate ease-in-out;
z-index: 0;
pointer-events: none;
}
@keyframes waveAnimation {
0% {
transform: scale(1);
opacity: 0.8;
}
100% {
transform: scale(1.1);
opacity: 0;
}
}
JavaScript
/*
* 별 생성
*/
const numstar = 400; // 별 개수
const space = document.querySelector('.space');
// 별 사이의 간격 계산
const getRandomInterval = () => {
return Math.random() * 10 + 3;
};
// 별 생성 및 스타일 설정
for (let i = 0; i < numstar; i++) {
const star = document.createElement('div');
star.className = 'star';
star.style.top = `${Math.random() * 100}%`;
star.style.left = `${Math.random() * 100}%`;
const starize = Math.random() * 2 + 0.5;
star.style.width = `${starize}px`;
star.style.height = `${starize}px`;
star.style.animationDuration = `${getRandomInterval()}s`;
space.appendChild(star);
}
// 별 반짝임 효과
const twinklestar = () => {
const star = document.querySelectorAll('.star');
star.forEach(star => {
star.style.animation = 'none';
star.offsetHeight;
star.style.animationDuration = `${getRandomInterval()}s`;
star.style.animation = null;
});
};
/*
* 해와 달 생성
*/
let minus = 250;
const sun = document.querySelector('.sun');
const moon = document.querySelector('.moon');
const content = document.querySelector('.content');
const windowHeight = window.innerHeight;
const contentTop = content.offsetTop - (windowHeight + 500 - minus);
const opacityTop = document.getElementById('resume').offsetTop - windowHeight;
const waveSun = document.getElementById('wave-sun');
const waveMoon = document.getElementById('wave-moon');
let moonOpacity = 0.9;
const opacityThreshold = opacityTop + 50;
// 해, 달, 파동 위치 업데이트
const updateWavePosition = () => {
// 해와 달 위치
const sunPosition = sun.getBoundingClientRect();
const moonPosition = moon.getBoundingClientRect();
// 파동의 위치
waveSun.style.top = `${sunPosition.top - 350}px`;
waveSun.style.left = `${sunPosition.left - 400}px`;
waveMoon.style.top = `${moonPosition.top - 340}px`;
waveMoon.style.left = `${moonPosition.left - 365}px`;
};
// 페이지 스크롤 시 애니메이션 업데이트
const updateWaveAnimation = () => {
// 스크린 백분율 계산
let scrollPercentage = window.scrollY / contentTop;
let opacityPercentage = (window.scrollY - contentTop - 370 + minus) / (opacityTop - contentTop) * 10;
scrollPercentage = Math.min(scrollPercentage, 1);
opacityPercentage = Math.min(opacityPercentage, 1);
// 각도 계산
const angle = Math.PI * scrollPercentage;
// 달 투명도
moonOpacity = 0.9 - opacityPercentage;
if (moonOpacity > 0.9) {
moonOpacity = 0.9;
}
moon.style.opacity = moonOpacity;
// 해와 달 위치 조정
sun.style.top = `${50 - 40 * Math.cos(angle) + 70}%`;
sun.style.left = `${50 + 40 * Math.sin(angle)}%`;
moon.style.top = `${50 + 40 * Math.cos(angle) + 74}%`;
moon.style.left = `${50 - 40 * Math.sin(angle)}%`;
waveSun.style.transform = `rotate(${angle}rad) scaleY(${Math.sin(angle)}`;
waveMoon.style.transform = `rotate(${angle}rad) scaleY(${Math.sin(angle)}`;
// 달의 파동의 투명도
let dynamicOpacity = 0.22 * moonOpacity;
// console.log(moonOpacity + ', ' + dynamicOpacity);
// 달의 투명도가 0인 경우
if (moonOpacity > 0) {
moon.style.pointerEvents = 'auto';
waveMoon.style.background = `radial-gradient(circle, rgba(230, 230, 230, ${dynamicOpacity}) 0%, rgb(0, 0, 0, 0) 60%)`;
// 달 클릭 이벤트
moon.addEventListener('click', (event) => {
window.open('https://isaac-christian.tistory.com/', '_blank');
});
} else {
moon.style.pointerEvents = 'none';
moon.style.opacity = 0;
waveMoon.style.background = '#FFFFFF00';
}
updateWavePosition();
// 페이지 스크롤 백분율에 따른 배경색 및 글자색 변경
if (scrollPercentage > 0.5) {
document.body.style.backgroundColor = '#011936';
} else {
document.body.style.backgroundColor = '#6395ED';
}
requestAnimationFrame(updateWaveAnimation);
};
updateWaveAnimation();
HTML
<!-- 워드 클라우드 -->
<div id="word-cloud-container"></div>
CSS
#word-cloud-container {
position: absolute;
width: 100%;
height: 100vh;
overflow: auto;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.word-cloud-text {
cursor: default;
transition: all 0.3s;
top: 0;
}
@media (max-width: 1440px) {
.sun,
.moon,
.wave {
display: none;
}
#word-cloud-container {
height: 113vh;
}
}
@media (max-width: 768px) {
.sun,
.moon,
.wave {
display: none;
}
#word-cloud-container {
height: 113vh;
}
}
JavaScript
/*
* 워드 클라우드
*/
const words = [
{ text: "Java", size: 60, color: "white", opacity: 1, tags: ["언어", "Java"] },
{ text: "SQL", size: 55, color: "white", opacity: 1, tags: ["데이터베이스", "SQL"] },
{ text: "R", size: 50, color: "white", opacity: 1, tags: ["언어", "R"] },
{ text: "C", size: 50, color: "white", opacity: 1, tags: ["언어", "C"] },
{ text: "C++", size: 50, color: "white", opacity: 1, tags: ["언어", "C++"] },
{ text: "Eclipse", size: 60, color: "white", opacity: 1, tags: ["도구", "Eclipse"] },
{ text: "Oracle", size: 60, color: "white", opacity: 1, tags: ["데이터베이스", "Oracle"] },
{ text: "VS Code", size: 40, color: "white", opacity: 1, tags: ["도구", "VSCode"] },
{ text: "DBeaver", size: 40, color: "white", opacity: 1, tags: ["도구", "DBeaver"] },
{ text: "Git", size: 55, color: "white", opacity: 1, tags: ["도구", "Git"] },
{ text: "Photoshop", size: 45, color: "white", opacity: 1, tags: ["도구", "Photoshop"] },
{ text: "Illustrator", size: 40, color: "white", opacity: 1, tags: ["도구", "Illustrator"] },
{ text: "Premiere Pro", size: 40, color: "white", opacity: 1, tags: ["도구", "Premiere Pro"] },
{ text: "JSP", size: 50, color: "white", opacity: 1, tags: ["언어", "JSP"] },
{ text: "Servlet", size: 45, color: "white", opacity: 1, tags: ["언어", "Servlet"] },
{ text: "JDBC", size: 45, color: "white", opacity: 1, tags: ["데이터베이스", "JDBC"] },
{ text: "Python", size: 40, color: "white", opacity: 1, tags: ["언어", "Python"] },
{ text: "HTML", size: 50, color: "white", opacity: 1, tags: ["언어", "HTML"] },
{ text: "CSS", size: 45, color: "white", opacity: 1, tags: ["언어", "CSS"] },
{ text: "JavaScript", size: 50, color: "white", opacity: 1, tags: ["언어", "JavaScript"] },
{ text: "Spring", size: 50, color: "white", opacity: 1, tags: ["프레임워크", "Spring"] },
{ text: "MyBatis", size: 45, color: "white", opacity: 1, tags: ["프레임워크", "MyBatis"] },
{ text: "jQuery", size: 45, color: "white", opacity: 1, tags: ["라이브러리", "jQuery"] },
{ text: "SPSS", size: 40, color: "white", opacity: 1, tags: ["통계 소프트웨어", "SPSS"] },
{ text: "AWS", size: 55, color: "white", opacity: 1, tags: ["클라우드", "AWS"] },
{ text: "jSoup", size: 40, color: "white", opacity: 1, tags: ["라이브러리", "jSoup"] },
{ text: "Selenium", size: 40, color: "white", opacity: 1, tags: ["프레임워크", "Selenium"] },
{ text: "SDL", size: 40, color: "white", opacity: 1, tags: ["라이브러리", "SDL"] },
{ text: "STS", size: 50, color: "white", opacity: 1, tags: ["도구", "STS"] },
{ text: "Restful API", size: 45, color: "white", opacity: 1, tags: ["라이브러리", "Restful API"] },
{ text: "Elasticsearch", size: 40, color: "white", opacity: 1, tags: ["라이브러리", "Elasticsearch"] },
{ text: "WSL", size: 40, color: "white", opacity: 1, tags: ["도구", "WSL"] },
];
const colorByTag = {
"언어": "#f0cf65",
"데이터베이스": "#bd4f6c",
"도구": "#93b5c6",
"프레임워크": "#d7816a",
"라이브러리": "#ddedaa",
"통계 소프트웨어": "#dee2e6",
"클라우드": "#502e2e" // #af8b60 #482626 #643939
};
// 워드 클라우드 원본 색상 객체
const originalWordSizes = {};
function resizeWordCloud() {
// 브라우저 창 너비, 높이
const svgContainer = d3.select("#word-cloud-container");
const width = window.innerWidth - 100;
const height = window.innerHeight - 250;
// 요소 초기화
svgContainer.selectAll("*").remove();
const svg = svgContainer
.append("svg")
.attr("width", width)
.attr("height", height)
.style("position", "absolute")
.style("left", "50%")
.style("top", "50%")
.style("transform", "translate(-50%, -60%)")
.attr("text-anchor", "middle")
.append("g")
.attr("transform", `translate(${width / 2},${height / 2})`);
const layout = d3.layout.cloud()
.size([width, height])
.words(words)
.padding(5)
.rotate(function () { return ~~(Math.random() * 2); })
.font("'SBAggroB', Impact")
.fontSize(function (d) {
const originalSize = originalWordSizes[d.text];
const newSize = (originalSize / 60) * (width / 20);
const maxSize = originalSize;
return Math.max(Math.min(newSize, maxSize), 30); // 최소 폰트 크기 30, 최대 폰트 크기 기존 크기
})
.on("end", draw);
layout.start();
function draw(words) {
svg
.selectAll("text")
.data(words)
.enter()
.append("text")
.attr("class", "word-cloud-text")
.style("font-size", function (d) { return d.size + "px"; })
.style("font-family", "'SBAggroB', 'Impact'")
.style("fill", "transparent")
.style("stroke", "white")
.style("stroke-width", "0.2px")
.style("opacity", function (d) { return d.opacity; })
.attr("text-anchor", "middle")
.attr("transform", function (d) {
return `translate(${d.x},${d.y})rotate(${d.rotate})`;
})
.text(function (d) { return d.text; })
.on("mouseover", function () {
if (!isOriginalColors) return;
d3.select(this)
.style("fill", function (d) { return colorByTag[d.tags[0]] || "white"; })
.style("stroke", "transparent");
})
.on("mouseout", function () {
if (!isOriginalColors) return;
d3.select(this)
.style("fill", "transparent")
.style("stroke", "white");
});
}
// 해 클릭 이벤트
let isOriginalColors = true;
sun.addEventListener("click", () => {
const wordCloudTextElements = svg.selectAll(".word-cloud-text");
wordCloudTextElements.each(function (d, i) {
const wordCloudText = d3.select(this);
setTimeout(function () {
if (isOriginalColors) {
wordCloudText
.style("fill", "transparent")
.style("stroke", "white");
} else {
wordCloudText
.style("fill", function (d) { return colorByTag[d.tags[0]] || "white"; })
.style("stroke", "transparent");
}
}, i * 20);
});
isOriginalColors = !isOriginalColors;
});
}
// 초기 워드 클라우드 생성
if (Object.keys(originalWordSizes).length === 0) {
// 각 단어의 원래 크기를 저장
words.forEach(word => {
originalWordSizes[word.text] = word.size;
});
setTimeout(resizeWordCloud, 300);
}
HTML
<div class="col-lg-4 col-md-6 portfolio-item filter-web" data-portfolio-number="12">
<div class="portfolio-img"><img src="assets/img/portfolio/portfolio-12/dd-land/dd-land 21.png" class="img-fluid" alt=""></div>
<div class="portfolio-info">
<h4>놀이동산 [DD-Land]</h4>
<div class="portfolio-description">
<p>기존의 DD-Studio 프로젝트를 Spring으로 구현하여 기능을 발전시킨 놀이동산 웹 사이트 프로젝트입니다.</p>
<table class="detail-table">
<tr>
<th><li><strong>Category</strong></li></th>
<td>Spring 프로젝트</td>
</tr>
<tr>
<th><li><strong>Platform</strong></li></th>
<td><high>Windows 11</high> <high>Mac OS</high> <high>WSL</high></td>
</tr>
<tr>
<th><li><strong>Front-End</strong></li></th>
<td><high>HTML</high> <high>CSS</high> <high>JavaScript</high> <high>jQuery</high></td>
</tr>
<tr>
<th><li><strong>Back-End</strong></li></th>
<td><high>Java</high> <high>JSP</high> <high>JSTL</high> <high>Apache Tomcat</high> <high>MyBatis</high> <high>HikariCP</high></td>
</tr>
<tr>
<th><li><strong>Database</strong></li></th>
<td><high>Oracle Database 11g</high></td>
</tr>
<tr>
<th><li><strong>Deployment</strong></li></th>
<td><high>AWS (EC2)</high></td>
</tr>
<tr>
<th><li><strong>Tool</strong></li></th>
<td><high>STS-3</high> <high>SQL Developer</high> <high>DBeaver</high> <high>Git</high> <high>eXERD</high> <high>Draw.io</high> <high>Sourcetree</high> <high>Google Drive</high></td>
</tr>
<tr>
<th><li><strong>Skill</strong></li></th>
<td><high>Spring MVC Pattern</high> <high>Spring Security</high> <high>Socket</high> <high>Restful API</high> <high>Tiles</high> <high>Ajax</high> <high>Elasticsearch</high> <high>RegEx</high></td>
</tr>
<tr>
<th><li><strong>API</strong></li></th>
<td><high>Kakao 지도 API</high> <high>Daum 주소 API</high></td>
</tr>
<tr>
<th><li><strong>Period</strong></li></th>
<td>2023.12.18.~2023.12.27.</td>
</tr>
</table>
</div>
<a href="assets/img/portfolio/portfolio-12/dd-land/dd-land 21.png" data-gallery="portfolioGallery"
class="portfolio-lightbox preview-link" title="놀이동산 [DD-Land]"><i class="fa-solid fa-expand"></i></a>
<a href="portfolio-details12.html" class="details-link" title="More Details"><i class="fa-solid fa-up-right-from-square"></i></a>
</div>
</div>
CSS
/*--------------------------------------------------------------
# My Portfolio
--------------------------------------------------------------*/
.portfolio #portfolio-flters {
list-style: none;
margin-bottom: 20px;
}
.portfolio #portfolio-flters li {
cursor: pointer;
display: inline-block;
margin: 0 10px 10px 10px;
font-size: 16px;
font-weight: 600;
line-height: 1;
padding: 7px 18px 11px 17px;
text-transform: uppercase;
color: #444444;
transition: all 0.2s ease-in-out;
border: 2px solid #f4f4f4;
border-radius: 2px;
}
.portfolio .portfolio-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.portfolio #portfolio-flters li:hover,
.portfolio #portfolio-flters li.filter-active {
color: #4A70B5;
border-color: #4A70B5;
cursor: pointer;
}
.portfolio .portfolio-item {
margin: 0px 10px 30px 10px;
box-shadow: 0 10px 29px 0 rgba(68, 88, 144, 0.1);
padding: 20px;
text-align: center;
}
.portfolio .portfolio-item {
overflow: hidden;
}
.portfolio .portfolio-item .portfolio-img img {
transition: all 0.5s ease-in-out;
}
.portfolio .portfolio-item .portfolio-img img {
width: 100%;
height: auto;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.portfolio .portfolio-item .portfolio-info {
background: rgba(252, 252, 252, 0);
transition: all ease-in-out 0.1s;
padding: 15px 0 0 0;
text-align: center;
}
.portfolio .portfolio-item:hover .portfolio-info {
background: rgb(250, 250, 250);
}
.portfolio .portfolio-item .portfolio-info h4 {
font-size: 20px;
color: #333;
font-weight: 600;
color: #333;
margin-bottom: 0px;
}
.portfolio .portfolio-item .portfolio-info p {
color: #333;
margin: 10px 0 10px 0;
font-size: 18px;
}
.fa-expand {
font-size: 22px;
}
.fa-up-right-from-square {
font-size: 21px;
}
.portfolio .portfolio-item .portfolio-info .preview-link,
.portfolio .portfolio-item .portfolio-info .details-link {
display: inline-flex;
font-size: 24px;
color: #dcdcdc;
transition: 0.3s;
}
.portfolio .portfolio-item .portfolio-info .details-link {
margin-left: 17px;
}
.portfolio .portfolio-item .portfolio-info .preview-link:hover,
.portfolio .portfolio-item .portfolio-info .details-link:hover {
transform: scale(1.2);
color: #4284FF;
}
.portfolio-button {
margin-top: -10px;
}
/*
.portfolio .portfolio-item .portfolio-info .preview-link:hover {
rotate: 30deg;
}
.portfolio .portfolio-item .portfolio-info .details-link:hover {
rotate: 30deg;
}
*/
.portfolio .portfolio-item .portfolio-info .details-link {
right: 10px;
}
.portfolio .portfolio-item:hover .portfolio-info {
opacity: 0.9;
}
.portfolio-description {
text-align: center;
margin: -5px 0px 20px 0px;
}
.portfolio-description p {
font-size: 14px;
color: #333;
}
.portfolio-description::before {
display: block;
content: '';
width: 98%;
height: 1px;
text-align: center;
margin: 15px 0px 10px 0px;
opacity: 0.3;
background-color: #d1d0d0; /* e5e5e5 */
}
.portfolio .col-lg-4 {
display: flex;
flex-direction: column;
width: 100%;
}
.portfolio .col-lg-4.portfolio-item {
border: 2px solid transparent;
transition: border 0.3s, cursor 0.3s;
cursor: pointer;
}
.portfolio .col-lg-4.portfolio-item:hover {
border: 2px solid #4A70B5;
}
#portfolio .col-lg-4 {
width: 47%;
/* width: 100%; */
/* max-width: 400px; */
}
@media (max-width: 576px) {
.portfolio .col-lg-4.portfolio-item {
cursor: default;
}
.portfolio .col-lg-4.portfolio-item:hover {
border: 2px solid transparent;
}
}
@media (max-width: 1200px) {
#portfolio .col-lg-4 {
width: 100%;
}
}
div.portfolio-info > div > table > tbody > tr:nth-child(1) > th {
width: 25%;
}
/*--------------------------------------------------------------
# Portfolio Details
--------------------------------------------------------------*/
.portfolio-details {
padding-top: 40px;
padding-right: 0;
}
.portfolio-details .portfolio-details-slider img {
width: 100%;
}
.portfolio-details .portfolio-details-slider .swiper-pagination {
margin-top: 20px;
position: relative;
}
.portfolio-details .portfolio-details-slider .swiper-pagination .swiper-pagination-bullet {
width: 12px;
height: 12px;
background-color: #fff;
opacity: 1;
border: 1px solid #4A70B5;
}
.portfolio-details .portfolio-details-slider .swiper-pagination .swiper-pagination-bullet-active {
background-color: #4A70B5;
}
.portfolio-details .portfolio-info {
padding: 30px;
padding-bottom: 1px;
box-shadow: 0px 0 30px rgba(59, 67, 74, 0.08);
}
.portfolio-details .portfolio-info h3 {
font-size: 22px;
font-weight: 700;
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
text-align: center;
}
.portfolio-details .portfolio-info ul {
list-style: none;
padding: 0;
font-size: 18px;
}
.portfolio-details .portfolio-info ul li+li {
margin-top: 10px;
}
.portfolio-details .portfolio-description {
padding-top: 30px;
}
.portfolio-details .portfolio-description h2 {
font-size: 26px;
font-weight: 700;
margin-bottom: 20px;
}
.portfolio-details .portfolio-description p {
padding: 0;
}
.portfolio-details-content h2 {
color: rgb(1, 25, 54);
font-size: 30px;
font-weight: bold;
}
.portfolio-details-content h2 #sub-title {
color: #5186e7;
font-size: 29px;
letter-spacing: 1px;
/* text-decoration: underline; */
}
@media (min-width: 300px) and (max-width: 1024px) {
.material-symbols-outlined {
opacity: .9;
vertical-align: middle;
padding-right: 5px;
}
.portfolio-details-content h2 {
margin-top: 20px;
}
}
/* 랩탑 화면 (화면 너비 1025px - 1600px) */
@media (min-width: 769px) and (max-width: 1600px) {
.material-symbols-outlined {
opacity: .9;
vertical-align: top;
padding-top: 10px;
padding-right: 5px;
}
}
.portfolio-info ul li strong {
display: inline-block;
width: 100px;
font-weight: bold;
/* margin-right: 5px; */
margin-top: 10px;
}
.portfolio-info ul li:first-child strong {
margin-top: 0;
}
.portfolio-info ul li strong::before {
content: "•";
margin-right: 5px;
}
.swiper-button-prev,
.swiper-button-next {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 24px;
color: #4A70B5;
cursor: pointer;
z-index: 2;
opacity: 0.7;
transition: all 0.5s;
}
.swiper-button-prev:hover,
.swiper-button-next:hover {
opacity: 1;
}
.swiper-button-prev:hover {
left: 15px;
}
.swiper-button-next:hover {
right: 15px;
}
.swiper-button-prev {
left: 20px;
}
.swiper-button-next {
right: 20px;
}
JavaScript
/*
* portfolio detail 이동
*/
document.addEventListener('DOMContentLoaded', function () {
const portfolioItems = document.querySelectorAll('.portfolio .col-lg-4.portfolio-item');
portfolioItems.forEach((item) => {
if (window.innerWidth >= 576) {
item.addEventListener('click', function (event) {
// 기본 링크 동작 방지
event.preventDefault();
// 클릭한 포트폴리오 아이템에서 포트폴리오 번호 추출
const portfolioNumber = item.getAttribute('data-portfolio-number');
// 포트폴리오 번호를 사용하여 포트폴리오 상세 페이지 URL 생성
const portfolioDetailURL = `portfolio-details${portfolioNumber}.html`;
// URL로 이동
window.location.href = portfolioDetailURL;
});
}
// bx-plus 아이콘 클릭 이벤트 리스너를 추가
const plusIcons = item.querySelectorAll('.portfolio-info .preview-link');
plusIcons.forEach((icon) => {
icon.addEventListener('click', function (event) {
// 상위로 버블링 방지
event.stopPropagation();
});
});
});
});
/**
* 반응형 디자인
*/
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
// 모바일 기기
//console.log("현재 기기: 모바일");
var prevButton = document.querySelector('.swiper-button-prev');
var nextButton = document.querySelector('.swiper-button-next');
if (prevButton && nextButton) {
prevButton.style.display = 'none';
nextButton.style.display = 'none';
}
} else {
// 데스크탑 기기
//console.log("현재 기기: 데스크탑");
window.addEventListener("resize", resizeWordCloud);
}
/**
* Porfolio isotope and filter
*/
window.addEventListener('load', () => {
let portfolioContainer = select('.portfolio-container');
if (portfolioContainer) {
let portfolioIsotope = new Isotope(portfolioContainer, {
itemSelector: '.portfolio-item',
layoutMode: 'masonry', // Masonry 레이아웃 모드 적용
masonry: {
columnWidth: '.portfolio-item',
horizontalOrder: false,
gutter: 25 // 간격 설정
}
});
let portfolioFilters = select('#portfolio-flters li', true);
on('click', '#portfolio-flters li', function (e) {
e.preventDefault();
portfolioFilters.forEach(function (el) {
el.classList.remove('filter-active');
});
this.classList.add('filter-active');
portfolioIsotope.arrange({
filter: this.getAttribute('data-filter')
});
}, true);
}
});
/**
* Initiate portfolio lightbox
*/
const portfolioLightbox = GLightbox({
selector: '.portfolio-lightbox'
});
/**
* Portfolio details slider
*/
new Swiper('.portfolio-details-slider', {
speed: 400,
loop: true,
autoplay: {
delay: 10000,
disableOnInteraction: false
},
pagination: {
el: '.swiper-pagination',
type: 'bullets',
clickable: true
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}
});