일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 코딩테스트 고득점 Kit
- 자바 공부
- Java
- codesandbox
- 장고
- NextJS
- 코틀린
- 디자인 패턴
- useEffect
- useState
- 프로그래머스
- websocket
- design pattern
- 자바
- 자바스크립트
- 컴퓨터 네트워크
- 코딩테스트 고득점 Kit 완전탐색
- vanillaJS
- react
- 프로그래머스 완전탐색
- 리액트 훅
- JavaScript
- 프로그래밍 언어론
- 리액트
- React JS
- react firebase
- 데이터모델링과마이닝
- 프로그래머스 자바
- react hook
- 백준
- Today
- Total
기록하는 개발자
[VanillaJS] 그림판 만들기 본문
- 주어진 팔레트 내에서 색상을 변경할 수 있다(default : black).
- 주어진 range 내에서 브러쉬 크기를 변경할 수 있다(default : 10).
- fill 버튼을 누르면 버튼이 paint로 바뀌고, canvas를 클릭하면 배경색이 채워진다.
- paint로 바뀐 버튼을 누르면 다시 text가 fill로 바뀌고, canvas에 선을 그릴 수 있다.
- clear 버튼을 클릭하면 canvas가 초기화 된다.
<HTML>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css"/>
<title>Let's Paint!🎨</title>
</head>
<body>
<canvas id="jsCanvas" class="canvas"></canvas>
<div class="controls">
<div class="controls_range">
<input type="range" id="jsRange" min="1" max="20" value="10" steps="1">
</div>
<div class="controls_btns">
<button id="jsMode">Fill</button>
<button id="jsClear">Clear</button>
</div>
<div class="controls_colors" if="jsColors">
<div class="controls_color jsColor" style="background-color: black;"></div>
<div class="controls_color jsColor" style="background-color: white;"></div>
<div class="controls_color jsColor" style="background-color: rgb(219, 42, 42);"></div>
<div class="controls_color jsColor" style="background-color: rgb(255, 123, 0);"></div>
<div class="controls_color jsColor" style="background-color: rgb(255, 196, 0);"></div> <div class="controls_color jsColor" style="background-color: rgb(81, 119, 64);"></div>
<div class="controls_color jsColor" style="background-color: rgb(41, 56, 121);"></div>
<div class="controls_color jsColor" style="background-color: rgb(87, 34, 122);"></div>
<div class="controls_color jsColor" style="background-color: rgb(168, 81, 135);"></div>
</div>
</div>
<script src="js/app.js"></script>
</body>
</html>
<CSS>
@import "reset.css";
body{
background-color: #f6f9fc;
display: flex;
flex-direction: column;
align-items : center;
padding-top : 30px;
}
.canvas{
width : 500px;
height : 500px;
background-color: white;
border-radius: 15px;
box-shadow : 0 4px 6px rgba(53, 53, 53, 0.11), 0 1px 3px rgba(66, 66, 66, 0.88);
}
.controls_colors .controls_color{
width : 50px;
height : 50px;
border-radius : 25px;
box-shadow : 0 4px 6px rgba(50,50,93,0.11), 0 1px 3px rgba(0, 0, 0, 0.88);
margin-left : 5px;
}
.controls{
display: flex;
flex-direction: column;
align-items : center;
margin-top : 30px;
}
.controls .controls_colors{
display : flex;
}
.controls .controls_btns{
margin-bottom : 20px;
}
.controls .controls_btns button{
all :unset;
cursor: pointer;
background-color: white;
padding : 5px 0px;
width : 80px;
text-align : center;
border-radius : 10px;
box-shadow : 0 4px 6px rgba(66, 66, 66, 0.11), 0 1px 3px rgba(87, 87, 87, 0.88);
text-transform: uppercase;
font-size: 12px;
font-weight: 800;
}
.controls_btns button:active{
transform : scale(0.98);
}
.controls .controls_range{
margin-bottom : 20px;
}
<JS>
const canvas = document.getElementById("jsCanvas");
const context = canvas.getContext("2d");
const colors = document.getElementsByClassName("jsColor");
const range = document.getElementById("jsRange");
const mode = document.getElementById("jsMode");
const clear = document.getElementById("jsClear");
const INITIAL_COLOR ="#2C2C2C";
const CANVAS_SIZE = 500;
let painting = false;
let filling = false;
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
context.strokeStyle = INITIAL_COLOR;
context.fillStyle =INITIAL_COLOR;
context.lineWidth = 10;
function stopPainting(){
painting=false;
}
function startPainting(){
painting=true;
}
function onMouseMove(event){
const x=event.offsetX;
const y=event.offsetY;
if(!painting) {
context.beginPath();
context.moveTo(x,y);
}
else{
context.lineTo(x,y);
context.stroke();
}
}
function handleColorClick(event){
const color = event.target.style.backgroundColor;
context.strokeStyle = color;
context.fillStyle = color;
}
function handleRangeChange(event){
const lineSize = event.target.value;
context.lineWidth = lineSize;
}
function handleModeClick(){
if(filling===true) {
filling=false;
mode.innerText = "FILL";
}
else{
filling=true;
mode.innerText = "PAINT";
}
}
function clearCanvas(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
}
function handleCanvasClick(){
if(filling)
context.fillRect(0,0,CANVAS_SIZE,CANVAS_SIZE);
}
if(canvas){
canvas.addEventListener("mousemove",onMouseMove);
canvas.addEventListener("mousedown",startPainting);
canvas.addEventListener("mouseup",stopPainting);
canvas.addEventListener("mouseleave", stopPainting);
canvas.addEventListener("click", handleCanvasClick);
}
Array.from(colors).forEach(colorItem =>
colorItem.addEventListener("click", handleColorClick)
);
if(range) range.addEventListener("input", handleRangeChange);
if(mode) mode.addEventListener("click", handleModeClick);
if(clear) clear.addEventListener("click", clearCanvas);
< 변수 선언 부 >
const canvas = document.getElementById("jsCanvas");
const context = canvas.getContext("2d");
const colors = document.getElementsByClassName("jsColor");
const range = document.getElementById("jsRange");
const mode = document.getElementById("jsMode");
const clear = document.getElementById("jsClear");
const INITIAL_COLOR ="#2C2C2C";
const CANVAS_SIZE = 500;
let painting = false;
let filling = false;
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
context.strokeStyle = INITIAL_COLOR;
context.fillStyle =INITIAL_COLOR;
context.lineWidth = 10;
canvas 태그 : html element로 다른 element와 다른 점으로는 context를 갖는다는 점이다.
context : element안에서 우리가 픽셀에 접근할 수 있는 방법
* pixel modifier : offsetX, offsetY 사용을 위해 canvas 크기 지정 해야한다.
→ css 에서 지정한 canvas 크기와는 다르다.
참고 : https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial
< 함수 >
1. stopPainting, startPainting
function stopPainting(){
painting=false;
}
function startPainting(){
painting=true;
}
2. onMouseMove
function onMouseMove(event){
const x=event.offsetX;
const y=event.offsetY;
if(!painting) { // 마우스 클릭 안한 경우
context.beginPath();
context.moveTo(x,y);
}
else{
context.lineTo(x,y);
context.stroke();
}
}
- offsetX, offsetY : canvas 범위
- clientX, clientY : 전체 screen 범위
1. mouse click을 하지 않았을 때
- beginPath : starts a new path by emptying the list of sub-paths. Call this method when you want to create a new path.(sub-paths list를 비우고 new path를 생성한다.)
- moveTo : 펜을 x와 y 로 지정된 좌표로 옮긴다.
2. mouse가 canvas위에서 클릭 되어있는 경우
- lineTo : path의 이전 위치부터 현 위치까지 line을 만든다.
- stroke : 현재의 sub-path를 현재의 stroke style로 line을 긋는다.
3. handleColorClick
function handleColorClick(event){
const color = event.target.style.backgroundColor;
context.strokeStyle = color;
context.fillStyle = color;
}
- 배열에 저장된 element들을 클릭할 때 마다
현재 함수 내의 color 변수에 해당 element의 backgroundColor가 저장된다.
- strokeStyle, fillStyle을 클릭한 color로 초기화한다.
4. handleRangeChange
function handleRangeChange(event){
const lineSize = event.target.value;
context.lineWidth = lineSize;
}
input range를 변경할 때마다 현재 함수 내 lineSize 변수에 해당 element의 value 저장된다.*/
5. clearCanvas
function clearCanvas(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
}
6. handleCanvasClick
function handleCanvasClick(){
if(filling)
context.fillRect(0,0,CANVAS_SIZE,CANVAS_SIZE);
}
7. handleModeClick
function handleModeClick(){
if(filling===true) {
filling=false;
mode.innerText = "FILL";
}
else{
filling=true;
mode.innerText = "PAINT";
}
}
< 함수 실행 부 >
if(canvas){
canvas.addEventListener("mousemove",onMouseMove);
canvas.addEventListener("mousedown",startPainting);
canvas.addEventListener("mouseup",stopPainting);
canvas.addEventListener("mouseleave", stopPainting);
canvas.addEventListener("click", handleCanvasClick);
}
//classname으로 'jsColor'를 가진 element들을 array로 묶고 이벤트를 추가한다.
Array.from(colors).forEach(colorItem =>
colorItem.addEventListener("click", handleColorClick)
);
if(range) range.addEventListener("input", handleRangeChange);
if(mode) mode.addEventListener("click", handleModeClick);
if(clear) clear.addEventListener("click", clearCanvas);
'Web > Javascript' 카테고리의 다른 글
[vanillaJs] 프레임워크없이 SPA 만들기-1. 라우팅 설정하기 (0) | 2022.08.31 |
---|---|
[Javascript] JS DOM 이란? (1) | 2022.01.10 |
[VanillaJS] Google Chrome App Momentum 만들기 - 6. 완성 (0) | 2021.08.06 |
[VanillaJS] Google Chrome App Momentum 만들기 - 5. weather (0) | 2021.08.06 |
[VanillaJS] Google Chrome App Momentum 만들기 - 4-2. Checklist Delete (0) | 2021.08.05 |