# 6.인터렉션디자인

In 
ui

# 목차

  • 1. 원페이지 반응형 레이아웃
    • 1.1. 배경색상 변경
    • 1.2. 배경이미지 변경
    • 1.3. 네비게이션 버튼 배경 적용
    • 1.4. 메뉴변경 이벤트위임
    • 1.5. 미디어쿼리를 이용한 반응형 웹 적용
  • 4. 스모크문자 만들기

# 1. 원페이지 반응형 레이아웃

원페이지 반응형 레이아웃 구성 원페이지 방식의 반응형 웹사이트를 제작할 수 있는 네비게이션 프레임을 제작한다.

# 1.1. 배경색상 변경

미리보기
https://qwerewqwerew.github.io/source/js/deep/interaction/1-1.html

<div class="btns">
	<button class="btn_toggle">배경색상변경_토글버튼</button>
	<button class="btn--reset">배경색상_리셋</button>
	<button class="btn--bggray">배경색상변경_그레이</button>
</div>
body {
	background-color: lightyellow;
	transition: all 1s;
}
.bgcolor--blue {
	background-color: lightblue;
}
.bgcolor--gray {
	background-color: lightgray;
}
.btns {
	position: relative;
	top: 60px;
	width: 600px;
	margin: auto;
	text-align: center;
}
const btnToggle = document.querySelector('.btn_toggle');
// addEventListener('이벤트', 실행함수);
btnToggle.addEventListener('click', function () {
	document.body.classList.toggle('bgcolor--blue');
});

//console.log('');

const btnReset = document.querySelector('.btn--reset');
const btnBgGray = document.querySelector('.btn--bggray');

btnReset.addEventListener('click', function () {
	document.body.classList.remove('bgcolor--blue', 'bgcolor--gray');
});

btnBgGray.addEventListener('click', function () {
	document.body.classList.add('bgcolor--gray');
});

# 1.2. 배경이미지 변경

이미지다운로드
https://qwerewqwerew.github.io/source/js/deep/interaction/bg.png

미리보기
https://qwerewqwerew.github.io/source/js/deep/interaction/1-2.html

html#6
<div class="btns">
	<button class="btn--toggle">배경색상변경_토글버튼</button>
	<button class="btn--reset">배경색상_리셋</button>
	<button class="btn--bggray">배경색상변경_그레이</button>
	<button class="btn--bgimg">배경이미지 변경</button>
	<div class="bg_img"></div>
</div>
.bg_img {
	margin: 0;
	position: absolute;
	width: 100vw;
	height: 100vh;
	background: url('bg.png');
	transition: all 1s;
	opacity: 0;
}
.bg_img-show {
	opacity: 1;
}
const bgContainer = document.querySelector('.bg_img');
const btnToggle = document.querySelector('.btn--toggle');

btnToggle.addEventListener('click', function () {
	bgContainer.classList.remove('bg_img--show');
	document.body.classList.toggle('bgcolor--blue');
});

const btnReset = document.querySelector('.btn--reset');
btnReset.addEventListener('click', function () {
	bgContainer.classList.remove('bg_img--show');
	document.body.classList.remove('bgcolor--blue', 'bgcolor--gray', 'bg--img');
});

const btnBgGray = document.querySelector('.btn--bggray');
btnBgGray.addEventListener('click', function () {
	bgContainer.classList.remove('bg_img--show');
	document.body.classList.add('bgcolor--gray');
});

const btnBgImg = document.querySelector('.btn--bgimg');
btnBgImg.addEventListener('click', function () {
	bgContainer.classList.add('bg_img--show');
});

# 1.3. 네비게이션 버튼 배경 적용

아래쪽으로 스크롤하면 버튼 아래쪽에 배경이 나타났다가 다시 위로 이동하면 버튼 아래 배경이 사라지도록 한다.

미리보기
https://qwerewqwerew.github.io/source/js/deep/interaction/1-3.html

  1. 구조변경
html
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
...
<div class="bg_img"></div>
<div class="btns">
	<div class="container">
		<div class="btns_menu">
			<button class="btn--toggle">toggle</button>
			<button class="btn--reset">reset</button>
			<button class="btn--bggray">gray</button>
			<button class="btn--bgimg">img</button>
		</div>
		<button class="btns_toggle-btn"><span class="material-icons">menu</span></button>
	</div>
</div>
  1. section 영역 추가
html
<section id="home">
	<h2>Home</h2>
	<p>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet consectetur adipisicing elit, inte, quisquam. Eus necessitatibus sit impediteu culpa sed, corporis voluptate commodi office similique Poslanec impedit sequi ab compt Home Lorem ipsum dolor sit amet. Lower door met connectetur adipisicing this piquam fan recetas sit erectum culpa sed corpore voluptate commodi officia sinique Possimus ullam nesciunt impede sequ, ab compt</p>
</section>
<section>
	<h2>Skills</h2>
	<p>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet consectetur adipisicing elit, inte, quisquam. Eus necessitatibus sit impediteu culpa sed, corporis voluptate commodi office similique Poslanec impedit sequi ab compt Home Lorem ipsum dolor sit amet. Lower door met connectetur adipisicing this piquam fan recetas sit erectum culpa sed corpore voluptate commodi officia sinique Possimus ullam nesciunt impede sequ, ab compt</p>
</section>
  1. up버튼 추가
</section>
<button class="arrow-up"><span class="material-symbols-outlined"> arrow_upward </span></button>
  1. reset 추가
reset.css
/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain)
*/

html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
	display: block;
}
body {
	line-height: 1;
}
ol,
ul {
	list-style: none;
}
blockquote,
q {
	quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
  1. 배경색이 보이지 않다가 아래로 스크롤하면 배경색이 보이도록 배경색을 지정하고 transition 속성을 추가한다.
css
.btns_menu {
	display: flex;
}
button {
	background-color: #9ad7d9;
	border: transparent;
	padding: 1rem;
	display: block;
	cursor: pointer;
}
.btns {
	position: fixed;
	width: 100%;
	margin: auto;
	z-index: 10;
}
.btns .container {
	position: relative;
	max-width: 900px;
	padding: 20px;
	background-color: transparent;
	transition: 0.3s;
	margin: auto;
	display: flex;
	justify-content: center;
	border-radius: 0 0 10px 10px;
}
.btns .container.bgshow {
	padding: 20px;
	background-color: #9ad7d9;
}
section {
	padding-top: 100px;
	height: 100vh;
}
section h2 {
	color: #9ad7d9;
	font-size: 5rem;
	text-align: center;
}
section p {
	width: clamp(30%, 50%, 50%);
	font-size: 1.4rem;
	margin: auto;
	line-height: 1.75;
}
  1. opacity 속성을 이용해 위로 이동버튼을 나타나게 할 수 있다. opacity: 0 속성 값이 0이면 투명하지만 마우스가 위로 이동하면 커서가 나타난다. 커서가 나타나지 않도록 하려면 visibility 속성 값을 hidden 으로 설정하고 나타날때는 visible로 설정한다.
.arrow-up {
	position: fixed;
	bottom: 50px;
	right: 50px;
	width: 70px;
	height: 70px;
	color: rgb(255, 255, 255);
	background-color: rgb(33, 112, 231);
	border-radius: 50%;
	text-align: center;
	opacity: 0;
}
.arrow-up span {
	line-height: 70px;
	font-size: 50px;
}
.arrow-up.visible {
	opacity: 1;
}
  1. if문을 이용해 60픽셀이상 스크롤하면 .container 요소에 .bgshow 스타일이 추가되서 배경색이 나타나도록 작업한다.
js
const navContainer = document.querySelector('.btns .container');

document.addEventListener('scroll', function () {
	console.log(window.scrollY);
	if (window.scrollY > 60) {
		navContainer.classList.add('bgshow');
	} else {
		navContainer.classList.remove('bgshow');
	}
});
  1. if문을 이용해서 500픽셀이상 스크롤되면 위로가기 버튼이 나타나고 버튼을 누르면 scrollIntoView() 메서드를 이용해서 인수로 behavior: "smooth" 를 입력해서 홈(#home)으로 부드럽게 스크롤되도록 한다.
const arrowUp = document.querySelector('.arrow-up');

document.addEventListener('scroll', function () {
	if (window.scrollY > 500) {
		arrowUp.classList.add('visible');
	} else {
		arrowUp.classList.remove('visible');
	}
});

const home = document.querySelector('#home');

arrowUp.addEventListener('click', function () {
	home.scrollIntoView({ behavior: 'smooth' });
});

# 1.4. 메뉴변경 이벤트위임

미리보기
https://qwerewqwerew.github.io/source/js/deep/interaction/1-4.html

  1. .btn_menu 하위 button 태그를 수정한다.
<div class="btns_menu">
	<button class="btn home" data-link="#home">home</button>
	<button class="btn about" data-link="#about">about</button>
	<button class="btn skills" data-link="#skills">skills</button>
	<button class="btn skills" data-link="#works">works</button>
	<button class="btn contact" data-link="#contact">contact</button>
</div>
  1. section 요소 추가 #home,#about,#skills,#works,#contact 를 각각 추가
<section id="home">
	<div class="wrapper">
		<h2>Home</h2>
		<h3>quisquam.</h3>
		<p>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet consectetur adipisicing elit, inte, quisquam. Eus necessitatibus sit impediteu culpa sed, corporis voluptate commodi office similique Poslanec impedit sequi ab compt Home Lorem ipsum dolor sit amet. Lower door met connectetur adipisicing this piquam fan recetas sit erectum culpa sed corpore voluptate commodi officia sinique Possimus ullam nesciunt impede sequ, ab compt</p>
	</div>
</section>
  1. 섹션의 폭과 높이를 100% 로 설정하고 .wrapper의 최대폭을 1200px , 수평 중앙정렬한다.
section {
	width: 100%;
	height: 100vh;
	padding-top: 88px;
}
`` .wrapper {
	max-width: 1200px;
	margin: auto;
	text-align: center;
}
h3 {
	font-size: 24px;
}
  1. 버튼의 부모요소인 btns_menu 요소에 이벤트리스너를 적용하고 클릭이벤트가 발생하면 콜백함수에 event 인수를 전달해서 link 속성에 값이 있는지 확인해서 값이 없으면 return 하고 값이 있으면 해당ID의 요소로 자연스럽게 스크롤되도록 입력한다.
const btnsMenu = document.querySelector('.btns_menu');
btnsMenu.addEventListener('click', (event) => {
	const target = event.target;
	const link = target.dataset.link;
	console.log(link);
	if (link == null) {
		return;
	}
	const scrollTo = document.querySelector(link);
	console.log(scrollTo);
	scrollTo.scrollIntoView({ behavior: 'smooth', block: 'start' });
	btnsMenu.classList.remove('open');
});

# 1.5. 미디어쿼리를 이용한 반응형 웹 적용

미리보기
https://qwerewqwerew.github.io/source/js/deep/interaction/1-5.html

  1. 햄버거버튼 입력해서 폭이 700픽셀 이하가 되면 나타날 수 있도록 한다.
<button class="btns_toggle-btn">
	<span class="material-symbols-outlined"> menu </span>
</button>
  1. 햄버거버튼의 display 속성 값을 none으로 설정하고 미디어 쿼리를 이용해 브라우저의 폭이 700픽셀보다 작아지면 block으 로 변경해서 화면에 나타나도록 한다. 그 다음 버튼들의 부모요소 인 .btns_menuflex-direction 속성의 값을 column으 로 변경해서 버튼이 세로방향으로 나타나도록 하고 .open 스타일을 추가하면 버튼이 나타나도록 display속성 값을 block으 로 지정한다.
.btns_toggle-btn {
	position: absolute;
	top: 10px;
	right: 32px;
	color: #193f40;
	transition: 0.3s;
	display: none;
}
.btns_toggle-btn span {
	font-size: 24px;
}
@media screen and (max-width: 700px) {
	body .btns .container.bgshow {
		backdrop-filter: blur(10px);
		background-color: #9ad7d955;
		/* filter: blur(10px); */
	}
	.btns.container {
		background-color: #9accd9;
		border-radius: 0;
		padding: 24px;
	}
	.btns_toggle-btn {
		display: block;
	}
	.btns_menu {
		flex-direction: column;
		width: 100%;
		align-items: center;
		justify-content: center;
		padding-top: 20px;
		display: none;
	}
	.btns_menu.open {
		display: flex;
	}
	.btns_menu button {
		display: block;
		margin: 10px auto;
		width: 80%;
	}
}
  1. 햄버거 버튼을 누르면 메뉴가 나타나고 사라지도록 toggle 메서 드를 이용해 .open 스타일을 인수로 적용한다.
const btnsToggleBtn = document.querySelector('.btns_toggle-btn');
btnsToggleBtn.addEventListener('click', function (e) {
	e.preventDefault();
	btnsMenu.classList.toggle('open');
});

# 4. 스모크문자 만들기

미리보기
https://qwerewqwerew.github.io/source/js/deep/interaction/4-1.html

div 태그를 입력하고 자식요소로 클래스속성 값이 “p" 태그에 내용입력

<div>
	<p class="text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Optio eius doloribus, ab obcaecati facere omnis reiciendis dolore quod quidem aperiam repellat tempora vitae at excepturi sunt doloremque et quonesciunt!</p>
</div>

구글폰트 사이트에서 아래 폰트를 복사해서 CSS에 임포트한다. Roboto 폰트 사용(300, 400, 500, 700, 900) 유니버셜 선택자를 이용해 마진과 패딩을 0으로 설정하고 보더를 포함한 폭과 높이를 갖도록 박스사이징을 >보더박스로 설정하고 구 글폰트에서 임포트한 Roboto 폰트를 적용한다. section 태그에 포지션은 relative를 적용하고 디스플레이를 플렉스로 적용해서 수평, 수직 정렬을 중앙으로 해서 문자열이 중앙에 배치되 도록 해주며, 영역을 넘어가는 콘텐츠를 숨겨지도록 하기 위해 overflow 속성은 hidden으로 설정한다.

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap');

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap');

* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Roboto', sans-serif;
}
div {
	position: relative;
	display: flex;
	justify-content: center;
	align-items: center;
	min-height: 100vh;
	background-color: skyblue;
	overflow: hidden;
}
div .text {
	position: relative;
	color: #fff;
	margin: 40px;
	max-width: 800px;
	user-select: none;
	line-height: 3.5em;
	font-size: 3.5em;
}
div .text span {
	position: relative;
	display: inline-flex;
	cursor: pointer;
}
div .text span.active {
	animation: smoke 2s linear forwards;
	transform-origin: bottom;
}
@keyframes smoke {
	0% {
		opacity: 1;
		filter: blur(0);
		transform: translateX(0) translateY(0) rotate(0deg) scale(1);
	}
	50% {
		opacity: 1;
		pointer-events: none;
	}
	100% {
		opacity: 0;
		filter: blur(20px);
		transform: translateX(300px) scale(4);
	}
}
const text = document.querySelector('.text');
text.innerHTML = text.textContent.replace(/\S/g, ' <span>$&</span>');
const letters = document.querySelectorAll('span');
for (let i = 0; i < letters.length; i++) {
	letters[i].addEventListener('mouseover', function () {
		this.classList.add('active');
	});
}