클론코딩/노마드코더 그림 앱
[클론코딩/그림 앱] 노마드 코더 그림 앱 클론코딩 #2 Meme Maker
기록하는_사람
2022. 10. 27. 19:19
Meme Maker - 이미지 띄우기
📌 이미지 url은 실제 인터넷에 존재하지 않음.
브라우저를 위한 url. 브라우저가 자신의 메모리에 있는 파일을 드러내는 방식.
...
function onFileChange(event) {
const file = event.target.files[0];
const url = URL.createObjectURL(file);
const image = new Image();
image.src = url;
}
...
📄 index.html
...
<!-- image -->
<input type="file" accept="image/*" id="file" />
<!-- js -->
<script src="app.js"></script>
</body>
</html>
📄 app.js
...
const fileInput = document.getElementById("file");
...
function onFileChange(event) {
const file = event.target.files[0];
const url = URL.createObjectURL(file);
const image = new Image();
image.src = url;
image.onload = function() {
ctx.drawImage(image, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
fileInput.value = null;
}
}
...
fileInput.addEventListener("change", onFileChange);
Meme Maker - 텍스트 추가하기
📌 ctx.save() : ctx의 현재 상태, 색상, 스타일 등을 저장함.
ctx.restore() : 저장된 상태로 돌아감.
save()와 restore() 사이에 수정된 코드는 저장되지 않음.
📄 index.html
...
<!-- text -->
<input type="text" placeholder="Write and then double click" id="text" />
<!-- js -->
<script src="app.js"></script>
</body>
</html>
📄 app.js
...
const textInput = document.getElementById("text");
...
function onDoubleClick(event) {
ctx.save();
if(text !== "") {
const text = textInput.value;
ctx.lineWidth = 1;
ctx.font = "48px serif";
ctx.strokeText(text, event.offsetX, event.offsetY);
ctx.restore();
}
}
canvas.addEventListener("dblclick", onDoubleClick);
...
Meme Maker - 선 둥글게
📄 app.js
...
ctx.lineWidth = lineWidth.value;
ctx.lineCap = "round";
...
Meme Maker - 이미지 다운로드
📄 index.html
...
<!-- save image -->
<button id="save-btn">Save Image</button>
<!-- js -->
<script src="app.js"></script>
</body>
</html>
📄 app.js
...
const saveBtn = document.getElementById("save-btn");
...
function onSaveClick() {
const url = canvas.toDataURL();
const a = document.createElement("a");
a.href = url;
a.download = "myDrawing.png";
a.click();
}
...
saveBtn.addEventListener("click", onSaveClick);
Meme Maker - css
📌 all : unset;
: 모든 css 속성 제거.
📌 label 태그를 사용해서, input을 클릭한 것처럼 만들 수 있음.
: label 태그의 for값이랑 id값이 같으면, text를 클릭했을 때 id값의 input을 실행시킴.
...
<label for="file">
<!-- image -->
Add Image
<input type="file" accept="image/*" id="file" />
</label>
...
📄 index.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">
<title>Meme Maker</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<!-- color palette -->
<div class="color-options">
<!-- color -->
<input id="color" type="color" />
<!-- color palette -->
<div
class="color-option"
style="background-color: #DF0101"
data-color="#e74c3c"
></div>
<div
class="color-option"
style="background-color: #FF8000"
data-color="#d35400"
></div>
<div
class="color-option"
style="background-color: #f1c40f"
data-color="#f1c40f"
></div>
<div
class="color-option"
style="background-color: #D0FA58"
data-color="#27ae60"
></div>
<div
class="color-option"
style="background-color: #298A08"
data-color="#27ae60"
></div>
<div
class="color-option"
style="background-color: #58D3F7"
data-color="#34495e"
></div>
<div
class="color-option"
style="background-color: #013ADF"
data-color="#3498db"
></div>
<div
class="color-option"
style="background-color: #0B2161"
data-color="#8e44ad"
></div>
<div
class="color-option"
style="background-color: #4B088A"
data-color="#95a5a6"
></div>
<div
class="color-option"
style="background-color: #BDBDBD"
data-color="#95a5a6"
></div>
<div
class="color-option"
style="background-color: #000000"
data-color="#95a5a6"
></div>
</div>
<canvas></canvas>
<div class="btns">
<!-- line width -->
<input id="line-width" type="range" min="1" max="10" vlaue="5" step="0.5" />
<!-- color fill -->
<button id="mode-btn">Fill</button>
<!-- reset -->
<button id="destroy-btn">Destroy</button>
<!-- eraser -->
<button id="eraser-btn">Eraser</button>
<label for="file">
<!-- image -->
Add Image
<input type="file" accept="image/*" id="file" />
</label>
<!-- text -->
<input type="text" placeholder="Add text here" id="text" />
<!-- save image -->
<button id="save-btn">Save Image</button>
</div>
<!-- js -->
<script src="app.js"></script>
</body>
</html>
📄 styles.css
@import "reset.css";
body {
display: flex;
gap:20px;
justify-content: space-between;
align-items: flex-start;
background-color: blanchedalmond;
padding:20px;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
canvas {
width: 800px;
height: 800px;
border-radius: 10px;
background-color: white;
}
body {
display: flex;
justify-content: center;
align-items: center;
}
.btns {
display: flex;
flex-direction: column;
gap:20px;
}
.color-options {
display: flex;
flex-direction: column;
gap: 15px;
align-items: center;
}
.color-option {
width: 50px;
height: 50px;
border: 5px solid white;
border-radius: 25px;
cursor: pointer;
transition: transform ease-in-out .1s;
}
.color-option:hover {
transform: scale(1.2);
}
input#color {
background-color: white;
}
button, label {
all: unset;
padding: 10px 0px;
text-align: center;
background-color: tomato;
color: white;
font-weight: 500;
cursor: pointer;
border-radius: 15px;
transition: opacity linear .1s;
}
button:hover {
opacity: 0.7;
}
input#text {
all: unset;
padding: 10px 0px;
text-align: center;
background-color: white;
font-weight: 500;
border-radius: 15px;
}
input#file {
display: none;
}