[JavaScript] 그림판 만들기
CANVAS
Canvas API는 JavaScript와 HTML
<canvas>
엘리먼트를 통해 그래픽을 그리기위한 수단을 제공합니다. 무엇보다도 애니메이션, 게임 그래픽, 데이터 시각화, 사진 조작 및 실시간 비디오 처리를 위해 사용됩니다. Canvas API는 주로 2D 그래픽에 중점을 두고 있습니다. WebGL API 또한<canvas>
엘리먼트를 사용하며, 하드웨어 가속 2D 및 3D 그래픽을 그립니다.
HTML
- CSS는
class
이용, JS는id
이용해 일관성 유지
<body>
<canvas id="jsCanvas" class="canvas"></canvas> <!-- canvas tag지정 -->
<div class="controls"> <!-- ragne, button, color변경을 위한 div -->
<div class="controls__range"> <!-- paint 굵기 지정 -->
<input type="range" id="jsRange" min="0.1" max="5" value="2.5" step="0.1"/>
</div>
<div class="controls__btns"> <!-- fill/paint, save및 색생 지정을 위한 controls__btns div-->
<button class="btn" id="fill">Fill</button>
<button class="btn" id="save">Save</button>
</div>
<div class="controls__colors" id="colors"> <!-- 색 변경을 위한 controls__colors div 아래 각 div생성 후 색 지정 -->
<div class="color jsColor" style="background-color:black"></div>
<div class="color jsColor" style="background-color:white"></div>
<div class="color jsColor" style="background-color:red"></div>
<div class="color jsColor" style="background-color:yellow"></div>
<div class="color jsColor" style="background-color:orange"></div>
<div class="color jsColor" style="background-color:green"></div>
<div class="color jsColor" style="background-color:rgb(128, 219, 255)"></div>
<div class="color jsColor" style="background-color:blue"></div>
<div class="color jsColor" style="background-color:rgb(158, 34, 158)"></div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
CSS
@import "reset.css"; /*css 초기화*/
body{
/* background-color: #dfe2e6; */
background-color: #e0e0e0;
font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 50px;
}
.canvas{ /*canvas size및 style지정*/
width: 700px;
height: 700px;
background-color:white;
border-radius: 15px;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0,0,0,0.8);
}
.controls{
padding-top:30px;
display: flex;
flex-direction: column;
align-items: center;
}
.controls .controls__colors{
display: flex;
}
.controls .controls__btns{
margin-bottom : 20px;
}
.controls__btns .btn{
all : unset;
cursor: pointer;
background-color:white;
padding : 5px 0px;
width : 80px;
text-align: center;
border-radius:10px;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0,0,0,0.8);
border : 1px solid rgba(0,0,0,0.2);
color : rgba(0,0,0,0.8);
font-weight: 600;
font-size: 12px;
}
.controls__btns .btn:active{
transform: scale(0.98);
}
.controls__colors .color{
width: 50px;
height: 50px;
border-radius: 50%;
text-align: center;
line-height:50px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0,0,0,0.8);
}
.controls .controls__range{
margin-bottom: 30px;
}
JS
const canvas = document.getElementById('jsCanvas');
const ctx = canvas.getContext('2d');
const colors = document.getElementsByClassName('jsColor')
const range = document.getElementById('jsRange')
const fill = document.getElementById("fill")
const save = document.getElementById("save")
canvas.width = 700;
canvas.height = 700;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// defualt값으로 초기화
ctx.strokeStyle = "black"
ctx.fillStyle = "black"
ctx.lineWidth =2.5;
let painting = false;
let filling = false;
startPainting = () =>{
painting = true;
}
stopPainting = () => {
painting = false;
}
function onMouseMove(event) {
// canvas 안에서만 마우스의 움직임에 따라 좌표를 얻음(screen의 좌표는 clientX,Y참조)
const x = event.offsetX
const y = event.offsetY
if(!painting) { //마우스 이동(클릭X)지점으로 beginpath 및 해당좌표 붓 이동
ctx.beginPath();
ctx.moveTo(x, y);
}else { //line생성
ctx.lineTo(x, y);
ctx.stroke();
}
}
handleCanvasClick = () => {
if(filling){
ctx.fillRect(0,0,canvas.width,canvas.height);
// console.log(e)
}
}
handleCM = (e) => {
// console.log(e)
e.preventDefault();
}
if(canvas){
canvas.addEventListener("mousemove", onMouseMove); //마우스 좌표따라 path생성
canvas.addEventListener("mousedown", startPainting); //painting=true, onMouseMove함수로 인해 path 생성
canvas.addEventListener("mouseup", stopPainting); //painting=flase
canvas.addEventListener("mouseleave", stopPainting); //painting=flase
canvas.addEventListener("click",handleCanvasClick); //paint -> fill 변경
canvas.addEventListener("contextmenu", handleCM); //마우스 우클릭 방지
}
if(range){
// line width조정
range.addEventListener("input",handleRangeChange);
}
handleRangeChange = (e) =>{
const size = e.target.value;
ctx.lineWidth = size;
}
// console.log(Array.from(colors));
if(colors){
Array.from(colors).forEach(color => color.addEventListener("click",changeColor))
fill.addEventListener("click",handleModeClick)
}
changeColor = (e) => {
const bgColor = e.target.style.backgroundColor
// console.log(bgColor);
ctx.strokeStyle = bgColor;
ctx.fillStyle=ctx.strokeStyle;
}
function handleModeClick(){
if(filling === true) {
filling = false;
fill.innerText = "Fill";
}else{
filling = true;
fill.innerText="Paint";
}
}
if(save){
save.addEventListener("click",handleSaveClick)
}
//save
handleSaveClick = () => {
// const image = canvas.toDataURL("image/jpeg"); //jpeg로 저장
const image = canvas.toDataURL(); //png로 저장
const link = document.createElement("a");
link.href = image;
link.download = "PainJS[EXPORT]";
// console.log(link);
link.click();
}
addEventListener - mouse
이벤트명 | 설명 |
---|---|
mousedown | 마우스를 클릭 했을 때 발생 |
mouseout | 마우스가 특정 객체 밖으로 나갔을 때 발생 |
mouseover | 마우스가 특정 객체 위로 올려졌을 때 발생 |
mousemove | 마우스가 움직였을 때 발생 |
mouseup | 마우스에서 손을 뗐을 때 발생 |
댓글남기기