Canvas라는 elements를 이용해 그림을 그릴 수 있는 기능을 사용할 수 있다.
해당 캔버스엔 선, 원과 같은 그림을 그리는 기능을 사용할 수 있는데.
Script 에서 제공하는 이벤트 기능과 합쳐 그림판을 만들 수 있는 것이다.
어떻게 동작하는건지 알아보자
원리는 간단하다!
canvas위 마우스 클릭 이벤트를 감지해서 현재 마우스가 위치한 영역에 좌표를 구하고,
그 좌표에 작은 원을 그려준다.
마우스가 이동할때 감지되는 mousemove 이벤트는 계속해서 현재 마우스의 위치를
가져오고 그 위치에 계속해서 원을 그려주는 것이다.
이렇게 되면 마치 우리가 연필로 그림을 그리듯한 모습을 볼수있다.
마우스가 움직일때마다 그림을 그려주면 마우스가 움직일때마다 그림을 그리기 떄문에
아래 코드를 보면 painting 이라는 flag를 추가했다.
마우스가 클릭되면 이 flag를 true로 변경해 그림을 그리게 시키고..
마우스 클릭이 off되면 flag를 false로 변경해서 더이상 그림을 그리지 않도록 처리되는 것이다.
touch 이벤트도 감지하도록 아래 코드에 적어뒀기 때문에
아이패드, 노트북 펜슬 등으로 터치해도 기능이 잘 동작한다!
아래 샘플코드를 그대로 복사하면
샘플을 확인할 수 있다~
<canvas id="canvas" ></canvas>
<script src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
// 캔버스 객체를 가져온다.
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
painting = false, // 그림을 그릴 상황인지 체크하는 flag
lastX = 0, // 마지막 x 좌표
lastY = 0, // 마지막 y 좌표
lineThickness = 1; // 펜 굵기
// canvas 사이즈설정
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 터치감지 이벤트
document.body.addEventListener("touchstart", function (e) {
if (e.target == canvas) {e.preventDefault(); }
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousedown", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
document.body.addEventListener("touchend", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mouseup", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
document.body.addEventListener("touchmove", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousemove", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
// 마우스 이벤트
canvas.onmousedown = function(e) {
painting = true;
ctx.fillStyle = "#000";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
};
canvas.onmouseup = function(e){
painting = false; // 마우스로 그림그리기가 끝나면 플래그를 변경해준다.
}
// 그림을 그려주는 function
canvas.onmousemove = function(e) {
if (painting) {
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep){
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 3 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
if(lineThickness < 1){
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
ctx.fillRect(y, x, lineThickness , lineThickness );
} else {
ctx.fillRect(x, y, lineThickness , lineThickness );
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
}
lastX = mouseX;
lastY = mouseY;
}
}
// 캔버스에 이미지를 그려준다.
// 나의 경우 이미지 위에 그림을 그려야해서 사용함.
// 생략가능
setBackground();
function setBackground() {
var image = new Image();
image.onload = function() {
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
}
image.src = "/resources/images/suit.png";
}
</script>
결과

* 추가적으로 Hammer.js 를 사용하면 모바일 환경에서 발생되는 더 많은 터치기능(확대, swipe, tab)을 처리할 수 있다.
'프로그래밍' 카테고리의 다른 글
| MySQL PRIMARY KEY 변경 방법 (0) | 2022.04.14 |
|---|---|
| [Jquery Image preview] 초간단 이미지 미리보기 구현! (0) | 2022.03.04 |
| [Spring] Google Captcha checkbox sample! (0) | 2021.10.20 |
| Javascript While 문 일정시간 지연시키기!! (0) | 2021.08.18 |
| [완전체] JAVA + ORACLE + inset, update, delete, select (0) | 2021.06.24 |














