터치 또는 마우스 드래그를 통한 서명을 받는 canvas 영역을 구현해야 했다.
나는 서명 그림을 png 또는 jpg로 저장하는것이 아닌 Base64 코드로 DB에 저장하는 방식을 채택했다.
<div class='padsection'>
<canvas id='drawCanvas' width='300px' height='150px' style='position: relative; border:1px solid black; background-color:#ffffff'></canvas>
</div>
화면은 상단과 같이 간단하게 구성했다.
물론 하단에 서명을 받은 뒤 넘어가는 넘어가는 "저장"과 같은 버튼이 있지만 이 글에선 생략하겠다.
(function(obj){
obj.init();
$(obj.onLoad);
})((function(){
canvas = $("#drawCanvas");
var div = canvas.parent("div");
//캔버스의 오브젝트를 가져온다
var ctx = canvas[0].getContext("2d");
var drawble = false;
function canvasResize(){
canvas[0].height = div.height();
canvas[0].width = div.width();
canvas[0].top = window.pageYOffset + div.getBoundingClientRect().top;
}
상단의 코드를 통해 캔버스의 오브젝트를 가져왔다.
그리고 canvasResize() 를 통해 터치되는 곳과 캔버스의 영점을 맞췄다.
처음 작성시엔 다른 블로그에서 참조했던 대로
function canvasResize(){
canvas[0].height = div.height();
canvas[0].width = div.width();
}
위와 같이 작성했고 pc에서 동작했을땐 문제가 없었다.
하지만 모바일 chrome에서 동작했을때 터치되는 곳과 그림이 그려지는 화면 사이에 수직으로 차이가 발생했다.
그래서 추가한 코드가 아래와 같다
canvas[0].top = window.pageYOffset + div.getBoundingClientRect().top;
그 뒤 이벤트 발생을 담당하는 코드는 아래와 같다
//pc에서 사용할 때 사용되는 이벤트
function draw(e){
function getPosition(){
var rect = canvas[0].getBoundingClientRect();
return {
X : e.pageX - rect.left,
Y : e.pageY - rect.top
}
}
switch(e.type){
case "mousedown" : {
drawble = true;
ctx.beginPath();
ctx.moveTo(getPosition().X, getPosition().Y);
}
break;
case "mousemove" : {
if(drawble){
ctx.lineTo(getPosition().X, getPosition().Y);
ctx.stroke();
}
}
break;
case "mouseup":
case "mouseout" :{
drawble = false;
ctx.closePath();
}
break;
}
}
//스마트 폰에서 서명을 할 경우
function touchdraw(e){
function getPosition(){
var rect = canvas[0].getBoundingClientRect();
return {
X: e.changedTouches[0].pageX - rect.left,
Y: e.changedTouches[0].pageY - rect.top
}
}
switch(e.type){
case "touchstart" : {
drawble = true;
ctx.beginPath();
ctx.moveTo(getPosition().X, getPosition().Y);
}
break;
case "touchmove" : {
if(drawble){
//스크롤 이동중 이벤트 중지
if(e.cancelable) e.preventDefault();
ctx.lineTo(getPosition().X, getPosition().Y);
ctx.stroke();
}
}
break;
case "touchend":
case "touchcancel" : {
drawble = false;
ctx.closePath();
}
break;
}
}
return {
init: function(){
//캔버스 사이즈 조절
$(window).on("resize", canvasResize);
canvas.on("mousedown", draw);
canvas.on("mousemove", draw);
canvas.on("mouseup", draw);
canvas.on("mouseout", draw);
//모바일 터치 이벤트
canvas.on("touchstart", touchdraw);
canvas.on("touchend", touchdraw);
canvas.on("touchcancel", touchdraw);
canvas.on("touchmove", touchdraw);
},
onLoad: function(){
canvasResize();
}
}
})());
'Frontend > 03. Java Script' 카테고리의 다른 글
[JavaScript] Check box 전체 선택 후 전체 중 1개라도 해제하면 전체도 함께 해제되게 하기 (0) | 2023.12.08 |
---|---|
Radio button Y/N 설정하기 (0) | 2023.12.08 |
[JS] Java Script의 기본 문법 (0) | 2022.09.12 |