[TIL] 2021 01 08 Fri
1. Javascript 30
Day 7 : Array Cardio Day 2
이번에도 간단한 배열 메소드를 연습하는 프로젝트.
some, every, find, findIndex 메소드 사용
Day 8 : Fun with HTML5 Canvas
선을 그릴 때마다 색깔과 선 두께가 바뀌는 HTML 캔버스 구현 프로젝트.
1. canvas 태그
<canvas id="draw" width="800" height="800"></canvas>
canvas 태그의 속성은 width와 height 뿐(디폴트 300px, 150px)이며 DOM을 통해서 추후 조절이 가능하다.
또 주의할 것! canvas는 셀프클로징이 불가능한 태그라고 한다. 닫는 태그</canvas>
가 꼭 필요! -> 캔버스를 지원하지 않는 브라우저에는 canvas 태그 안에 img 태그 등을 임의로 넣어줄 수 있다.
2. context 생성
캔버스 태그가 랜더링 영역을 지정해준다면, context는 컨텐츠의 출력 및 렌더링을 담당한다고 한다. getContext()라는 메소드를 사용하여 선언할 수 있으며, 인자로 '2d', '3d'를 지정해줄 수 있다. (webGL의 경우가 "3d")
const canvas = document.querySelector("#draw");
// 캔버스의 크기 설정하기
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 2d 렌더링 컨텍스트 설정하기
const ctx = canvas.getContext("2d");
// 선의 모양 설정하기
ctx.strokeStyle = "#BADA55"; /* 선의 색, 그라디언트, 패턴 등을 결정 */
ctx.lineJoin = "round"; /* 두 선이 만났을 때 접점을 둥글게 처리 */
ctx.lineCap = "round"; /* 선 끝을 둥글게 */
ctx.lineWidth = 100; /* 선의 두께 */
3. 그리기
let isDrawing = false; /* isDrawing state */
let lastX = 0; /* 시작점의 x좌표 설정 */
let lastY = 0; /* 시작점의 y좌표 설정 */
function draw(e) {
if (!isDrawing) return;
ctx.beginPath(); /* 경로를 그리기 시작 */
ctx.moveTo(lastX, lastY); /* 경로를 그리지 않고 해당 좌표로 이동 : 시작점*/
ctx.lineTo(e.offsetX, e.offsetY); /* 경로를 그리며 이동 : 끝점 */
ctx.stroke(); /* 지정한 경로에 실제로 선을 남김 */
lastX = e.offsetX; /* 그리기가 끝난 시점에 다음 시작점의 x좌표 설정 */
lastY = e.offsetY; /* 그리기가 끝난 시점에 다음 시작점의 y좌표 설정 */
}
canvas.addEventListener("mousemove", draw);
canvas.addEventListener("mousedown", (e) => {
isDrawing = true; /* isDrawing state 변경 */
lastX = e.offsetX; /* drawing 시작점의 x좌표 설정 */
lastY = e.offsetY; /* drawing 시작점의 y좌표 설정 */
});
canvas.addEventListener("mouseup", () => (isDrawing = false));
canvas.addEventListener("mouseout", () => (isDrawing = false));
4. 색깔과 선 두께 바꾸기
hsl은 hue(색상), saturation(채도), lightness(명도)를 모두 바꿀 수 있는 메소드이다.
hue는 0부터 360까지의 스펙트럼(빨강 ~ 보라)을 가지고, saturation와 lightness는 0에서 100%까지의 스펙트럼을 가진다. saturation의 기본값은 100%, lightness는 50%인 듯?
let hue = 0;
let direction = true; /* 선 두께를 변경하기 위한 flag 역할 */
function draw(e) {
/* ...위 코드에 이어서 계속... */
hue++; /* 드로잉이 진행되는 동안 hue를 지속적으로 변경한다. */
if (hue >= 360) hue = 0; /* hue는 360까지이므로 다시 0으로 리셋 */
/* 선 두께를 0 ~ 100까지 조절하기 위한 flag */
if (ctx.lineWidth >= 100 || ctx.lineWidth <= 1) {
direction = !direction;
}
direction ? ctx.lineWidth++ : ctx.lineWidth--;
}
참고자료
2. Advanced CSS and Sass Flexbox, Grid, Animations and More!
section 5: Natours Project — Using Advanced CSS and Sass (Part 2)
1. 순수 CSS로 배경사진 위에 도형 덮기
background-image 속성에 가장 마지막 인자로 이미지 url을 넣으면 배경사진이 가장 마지막에 위치하게 된다.
그 위로 linear-gradient 효과를 주는데, 같은 %를 준다면 그 경계가 그라디언트가 아니라 면으로 나누어지는 효과를 활용하면 된다.
<div class="book"></div>
.book {
background-image:
linear-gradient(
105deg, /* 각도 조절! */
rgba($color-white, 0.9) 0%, /* 0 ~ 50%을 하얀색으로 */
rgba($color-white, 0.9) 50%, /* 50%라는 숫자가 겹치므로 경계는 면이 된다 */
transparent 50% /* 나머지를 투명색으로 */
),
url("../img/nat-10.jpg"); /* 배경이미지는 가장 마지막으로 */
}
2. input validation check
순수 html form 태그에서도 validation check가 가능하다는 걸 오늘 알았다.
<input type="text" class="form__input" required />
이렇게 required 속성을 주면 된다!
.form__input:focus:invalid {
border-bottom: 3px solid $color-secondary-dark;
}
그리고 css에서 :focus:invalid를 설정하면 validation에 따른 스타일 설정이 가능하다.
3. 형제(동위) 셀렉터 (Sibling Combinator)
- 인접 형제 셀렉터(Adjacent Sibling Combinator) : 셀렉터A의 형제 요소 중 셀렉터A 바로 뒤에 위치하는 셀렉터B 요소를 선택한다. A와 B 사이에 다른 요소가 존재하면 선택되지 않는다
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
/* 인접한 형제기 때문에 가능 */
.one + .two {
display: block;
}
/* 인접한 형제가 아니기 때문에 불가능 */
.one + .three {
display: block;
}
- 일반 형제 셀렉터(General Sibling Combinator) : 셀렉터A의 형제 요소 중 셀렉터A 뒤에 위치하는 셀렉터B 요소를 모두 선택한다.
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
/* one two three 모두 선택 */
.one ~ .three {
display: block;
}
참고자료
4. radio input 커스텀하기
라디오 버튼은 브라우저 자체 디자인이기 때문에 커스텀이 불가능해서 "display: none"으로 숨기고 임의의 span 태그를 디자인하는 꼼수를 배웠다!
<div class="form__radio-group">
<input type="radio" name="tour" id="small" class="form__radio-input"/>
<label for="small" class="form__radio-label">
<!--👇 요 친구가 가짜 라디오 버튼. label 안에 넣었기 때문에 input과 함께 묶인다 -->
<span class="form__radio-button"></span>
Small tour group
</label>
</div>
.form {
/* 진짜 라디오버튼은 숨긴다 */
&__radio-input {
display: none;
}
&__radio-label {
position: relative;
}
/* 임의의 라디오버튼 디자인 (테두리) */
&__radio-button {
height: 3rem;
width: 3rem;
border: 5px solid $color-primary;
border-radius: 50%;
display: inline-block;
position: absolute;
left: 0;
top: -0.4rem;
/* 임의의 라디오버튼 디자인 (select 시 나타나는 동그라미) */
&::after {
content: "";
display: block;
height: 1.3rem;
width: 1.3rem;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: $color-primary;
opacity: 0;
transition: opacity 0.2s;
}
}
/* Sibling을 통해 input이 check 속성이 되었을 때 그 속성을 넘겨받는다 */
&__radio-input:checked ~ &__radio-label &__radio-button::after {
opacity: 1;
}
}
3. 포트폴리오 구상 중
오늘은 집중이 잘 안 돼서 코드보다는 웹 포트폴리오 구상에 집중했다. 처음에는 이력서 양식을 계승한 포트폴리오를 만드려고 헀는데, 그럼 그냥 이력서를 pdf로 보는게 낫지 웹사이트로 보는 게 무슨 의미가 있지? 이런 생각이 들어서 색다른 시도를 해보기로 헀다. 인터렉티브까지는 되지 않더라도 최대한 playground처럼 꾸며보기로 했다. 나 자신을 표현하는 공간 그 자체로. 단순한 이력서가 아니라.
일단 구상하면서 도메인도 구매해놔야겠다.
Author And Source
이 문제에 관하여([TIL] 2021 01 08 Fri), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dongoc21hj/TIL-2021-01-08-Fri저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)