whatisthis?
Painting App - (app.js) 해결중 본문
** 깃헙에 업로드 해두었다.
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">
<link rel="stylesheet" href="style.css">
<title>PaintJS</title>
</head>
<body>
<canvas id="jsCanvas" class="canvas"></canvas>
<div class="controls">
<div class="controls__range">
<input type="range" id="jsRange" min="0.1" max="5.0" value="2.5" step="0.1"/>
</div>
<div class="controls__btns">
<button id="jsMode">Fill</button>
<button id="jsSave">Save</button>
</div>
<div class="controls__colors" id='jsColors'>
<div class="controls__color jsColors" style="background-color: #2c2c2c;"></div>
<div class="controls__color jsColors" style="background-color: #fff;"></div>
<div class="controls__color jsColors" style="background-color: #FF3B30;"></div>
<div class="controls__color jsColors" style="background-color: #ff9500;"></div>
<div class="controls__color jsColors" style="background-color: #FFCC00;"></div>
<div class="controls__color jsColors" style="background-color: #4CD963;"></div>
<div class="controls__color jsColors" style="background-color: #5AC8FA;"></div>
<div class="controls__color jsColors" style="background-color: #0579FF;"></div>
<div class="controls__color jsColors" style="background-color: #5856D6;"></div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
style.css
@import "./reset.css";
body {
background-color: #f6f9fc;
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: 50px 0px;
}
.canvas {
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.08);
}
.controls {
margin-top: 80px;
display: flex;
flex-direction: column;
align-items: center;
}
.controls .controls__btns { /* .controls 의 하위요소를 .controls__btns로 */
margin-bottom: 30px;
}
.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(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
border: 2px solid rgba(0, 0, 0, 0.2);
color: rgba(0, 0, 0, 0.7);
text-transform: uppercase;
font-weight: 600;
font-size: 12px;
}
.controls__btns button:active { /* 가상클래스 ㅡ active시 변형 */
transform: scale(0.98);
}
.controls .controls__colors {
display: flex;
}
.controls__colors .controls__color {
width: 50px;
height: 50px;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
border-radius: 25px;
cursor: pointer;
margin-left: 2px;
}
.controls .controls__range {
margin-bottom: 30px;
}
app.js
const canvas = document.getElementById("jsCanvas");
const colors = document.getElementsByClassName("jsColors");
const range = document.getElementById("jsRange");
const mode = document.getElementById("jsMode");
const save = document.getElementById("jsSave");
const ctx = canvas.getContext("2d");
const INITIAL_COLOR = "#2c2c2c";
canvas.width = document.getElementsByClassName("canvas")[0].offsetWidth;
canvas.height = document.getElementsByClassName("canvas")[0].offsetHeight;
// Default
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = INITIAL_COLOR;
ctx.fillStyle = INITIAL_COLOR;
ctx.lineWidth = 2.5;
let filling = false;
let painting = false;
function stopPainting() {
painting = false;
}
function startPainting() {
painting = true;
}
function onMouseMove(event) {
const x = event.offsetX;
const y = event.offsetY;
if(!painting) {
ctx.beginPath();
ctx.moveTo(x, y);
// console.log('creating path in', x, y);
} else {
ctx.lineTo(x, y);
ctx.stroke();
// console.log('creating line in', x, y);
}
}
function handleColorClick(event) {
const color = event.target.style.backgroundColor;
if(filling) {
ctx.fillStyle = color;
} else {
ctx.strokeStyle = color;
}
}
function handleRangeChange(event) {
const size = event.target.value;
ctx.lineWidth = size;
}
function fillColor(event) {
if(filling) {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
function handleModeClick(event) {
if(filling === true) { // filling 모드이면
filling = false;
mode.innerText = "fill"
} else {
filling = true;
mode.innerText = "paint" // paint 모드이면 ㅡ 맨처음
}
}
function handleCM(event) {
event.preventDefault();
}
function handleSaveClick(event) {
const image = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.href = image;
link.download = "paintJS[🎨]";
link.click();
}
if (canvas) {
canvas.addEventListener('mousemove',onMouseMove);
canvas.addEventListener('mousedown', startPainting);
canvas.addEventListener('mouseup', stopPainting);
canvas.addEventListener('mouseleave', stopPainting);
canvas.addEventListener('click', fillColor);
canvas.addEventListener('contextmenu', handleCM);
}
Array.from(colors).forEach(color => color.addEventListener("click", handleColorClick));
if (range) {
range.addEventListener('input', handleRangeChange);
}
if (mode) {
mode.addEventListener('click', handleModeClick);
}
if (save) {
save.addEventListener('click', handleSaveClick);
}
🔻🔻 실패는 성공의 어머니(...) 를 보고싶은 분들만
수정하고 싶은 것
- 파일명을 사용자가 직접 입력 가능하도록
>> prompt()를 입력할지
- prompt로 입력하면 모달창에 스타일을 입히기 힘들고
- 페이지가 일시정지 되기 때문에 잘 쓰지 않는다.
1. 첫번째로 생각난 것은
window.open으로 팝업창을 만들고
이름을 입력받아app.js에서 그 이름값으로 저장하는 것이다.
처음엔 popup.html과 popup.js 를 추가하여popup.js에서
const form = document.getElementById('name-form');
const input = document.getElementById('name-input');
function onFormSubmit(event) {
const fileName = input.value;
export { fileName }
window.close();
}
form.addEventListener('submit', onFormSubmit);
위와 같이export를 해보려했는데(js파일에서 - 다른 js파일로 변수 값 옮기는?)
모듈 밖에선 import할 수 없다고 뜬다.
export에 대해서 잘 이해를 못하겠어서나중에 시도해보는거로 하고..
input type text를 사용하면처음엔 그 창이 안보이게 하고,save를 눌렀을 때새 창으로 뜨게 해야할듯.
>> window.open으로 팝업창 뜨게 해도 될듯?
function handleSaveClick(event) {
const image = canvas.toDataURL("image/png");
const link = document.createElement("a");
const popup = window.open('popup.html', 'FileName','width=400,height=200');
const fileName = popup.document.getElementById('name-input').value;
link.href = image;
link.download = fileName;
link.click();
}
우선 이렇게 한다음에popup.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>Save File</title>
</head>
<body>
<h1>Save Image File</h1>
<form id="name-form" action="#">
<input id="name-input" required type="text" placeholder="file name" />
<button id="name-btn">save</button>
</form>
<script src="popup.js"></script>
</body>
</html>
위와 같이 작성했는데,
이런 오류가 발생한다.
window.open() 동작을 이용해서
팝업을 띄우고,
window.open()메서드 자체를 popup이라는 변수로 저장하여
getElementById로 가져오려했는데, 동작이 안된다.
const form = document.getElementById('name-form');
function onFormSubmit(event) {
event.preventDefault();
window.close();
}
form.addEventListener('submit', onFormSubmit);
까먹고 있던 event.preventDefault를 해봤다.
역시나 해결이 안된다.
import- export로 해결하는 것과
window.open()을 통해 연 팝업창에서 정보를 가져오는 것에 대해
알아보고 해결하도록 하겠다.ㅠㅠ
'PRACTICE > SELF' 카테고리의 다른 글
CSS - Position prac.01 (0) | 2022.02.11 |
---|---|
html. <map>과 <area> 예제 (0) | 2022.02.04 |
javaScript. Painting App 구현 - (7) Save Image (0) | 2022.02.03 |
javaScript. Painting App 구현 - (6) Fill mode (0) | 2022.02.03 |
javaScript. Painting App 구현 - (5) Brush Size (1) | 2022.02.02 |