.target1{
transform: translate(50%,20px);
}
.target2{
transform:scale(0.8,1.2);
}
.target3{
transform: skew(10deg,30deg);
}
.target4{
transform: rotate(45deg);
}
ex) y축으로 0.75배 축소하고 x축으로 20도 기울이기
.target5{
transform: scaleY(0.75) skewX(20deg);
}
어제 공부한 transition과 오늘 공부한 내용으로 hover 효과를 만들었다. 한글자씩 효과를 줘야돼서 span으로 쪼개버렸다.
<HTML>
<body>
<div class="box">
<span id="text1">T</span>
<span id="text2">R</span>
<span id="text3">A</span>
<span id="text4">N</span>
<span id="text5">S</span>
<span id="text6">F</span>
<span id="text7">O</span>
<span id="text8">R</span>
<span id="text9">M</span>
</div>
</body>
<CSS>
.box #text1{
transition:transform 0.4s ease-in-out;
}
.box #text2{
transition:transform 0.4s ease-in-out 0.1s;
}
.box #text3{
transition:transform 0.4s ease-in-out 0.2s;
}
.box #text4{
transition:transform 0.4s ease-in-out 0.3s;
}
.box #text5{
transition:transform 0.4s ease-in-out 0.4s;
}
.box #text6{
transition:transform 0.4s ease-in-out 0.5s;
}
.box #text7{
transition:transform 0.4s ease-in-out 0.6s;
}
.box #text8{
transition:transform 0.4s ease-in-out 0.7s;
}
.box #text9{
transition:transform 0.4s ease-in-out 0.8s;
}
.box:hover span{
transform:translateY(-20px);
}
최종 결과물의 일부분을 만들었다.
flex로 레이아웃을 나누고 transform과 transition으로 효과를 줬다.
레이아웃 짜고 가상선택자 만드는게 조금 더 걸렸다.
after를 사용해서 반투명한 형태의 박스를 만들고 hover됐을 때 보이게 효과를 줬다. image와 text를 나눴는데 image에는 scale과 filter를 줬고 text에는 translateY만 줬나? 그랬던거같다.
<HTML>
<div class="itemWrap">
<div class="item">
<div class="imageBox">
<img src="./img/item1.jpeg" alt="탁상용 조명">
</div>
<div class="textBox">
<p class="textBox__name">탁상용 조명</p>
<p class="textBox__price">260500 원</p>
</div>
</div>
</div>
<CSS>
.itemWrap {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
}
.item {
position: relative;
width: calc(25% - 7px);
aspect-ratio: 6 / 5;
overflow: hidden;
border-radius: 10px;
}
.imageBox {
width: 100%;
height: 100%;
}
.imageBox img {
width: 100%;
height: 100%;
object-fit: cover;
}
.textBox {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-start;
padding: 20px;
z-index: 3;
}
.textBox p {
color: white;
margin: 5px 0 0;
}
.textBox__name {
font-size: 22px;
font-weight: 500;
opacity: 0;
transform: translateY(100%);
}
.textBox__price {
font-size: 16px;
font-weight: 400;
opacity: 0;
transform: translateY(100%);
}
.item:after {
content: "";
display: block;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: 0;
left: 0;
z-index: 2;
opacity: 0;
}
.item:hover:after {
opacity: 1;
}
.item:hover .imageBox img {
transform: scale(1.1);
filter: blur(3px);
}
.item:hover .textBox__name {
opacity: 1;
transform: translateY(0);
}
.item:hover .textBox__price {
opacity: 1;
transform: translateY(-10%);
}
.item:after,
.item .imageBox img {
transition: all 0.4s ease-in-out;
}
.item .textBox__name {
transition: all 0.4s ease-in-out;
}
.item .textBox__price {
transition: all 0.4s ease-in-out 0.1s;
}
웹팩을 사용해서 환경설정 했는데 npm run dev
를 변경사항이 있을 때마다 해줘야 하는 불편함이 있었다. 이런 문제를 해결하기 위해 hot reload를 적용시키기로 했다.
핫 리로딩은 저장한 결과물에 변경점이 생기면 그 결과물을 자동으로 수정해서 페이지에 반영하는 기능이다.
핫리로딩 플러그인을 설치한다.
npm i -D react-refresh @pmmmwh/react-refresh-webpack-plugin
웹팩 개발 서버를 설치한다.
npm i -D webpack-dev-server
package.json
의 script를 "dev": "webpack serve --env development",
로 수정한다.
webpack.config.js
의 plugin에 저장한 것들을 추가한다.
웹팩 관련해서도 설정사항이 꽤 많다. 시작이 반이라는데 진짜로 반이었음.
require은 node의 모듈시스템이고 import는 react에서 지원하는 기능이라고 한다. 기능은 거의 유사하다.
다만 개발자서버 이용해서 개발할 때 import를 써서 컴포넌트를 받아오니까 오류가 생겼다. babel이 뭐로 쓰던 처리해준다면서...!ㅡㅡ require로 작성하면 문제 없어서 공부하면서 쓸 모든 파일은 require로 쓸 거다.
마찬가지로 module.export와 export default도 유사한 기능이다.
const React = require('react');
const { Component } = React;
이런 식으로 컴포넌트를 불러올 때 그냥 받는 것과 {}으로 받는 것에 차이가 있다.
{}를 써서 받는건 export default가 아니라 export로 내보낸 것이다.
중괄호 쓰지 않고 require로 받아오는 것은 export efault로 내보낸 것이다. 이것도 유사한 기능이고 바벨로 호환됨
리액트의 반복문은 일반적이지 않다. 왜 멀쩡한 for문을 안 쓰지?...라고 생각했는데 jsx를 써서 그런듯 아무튼 대부분의 반복은 map으로 처리한다고 한다.
모든 경우 배열로 받아온다. 그래서 jsx에서는 key값을 설정해야 한다.
key정하는게 좀 귀찮다. 최적화에 쓰이는거라 수정/추가/삭제 될 상황을 염두하고 신경써서 설정해야 함. 중복되면 안됨.
map의 두번째 인자(인덱스)를 key값으로 사용하지 않는다.
당장의 오류는 없앨 수 있지만 key의 목적인 수정/추가/삭제 등에 문제가 생길 수 있다.
<map 사용예시>
<>
<h1>{this.state.result}</h1>
<form onSubmit={this.onSubmitForm}>
<input maxLength={4} value={this.state.value} onChange={this.onChangeInput} />
</form>
<div>시도: {this.state.tries.length}</div>
<ul>
{[
{ fruit: 'apple', taste: 'good' },
{ fruit: 'banana', taste: 'um...' },
{ fruit: 'grape', taste: 'bad' },
{ fruit: 'dohoon', taste: 'lol' },
{ fruit: 'soobin', taste: 'looool' },
].map((v,i) => {
return (
<li key={v.fruit + v.taste}>[{i}] <strong>{v.fruit}</strong> is {v.taste}</li>
);
})}
</ul>
</>
드디어 웹팩 설정이 끝났다. 하루에 한강씩 듣다보면 이번달 안에 완강할 수 있을거강ㅌ다.