html 5 에서 제공하는 canvas 는 일반 application 에서 구현이 가능한 영역까지 작업이 가능
한 것이 특징 인 것 같습니다.
web을 기반한 업무 시스템에서 아주 많이 사용된다고는 할 수 없지만, 일반적인 도형 그리기,
이미지 관련 작업, 경우에 따라서는 webgl 을 포함한 3d 작업등에 사용될 수 있는 기술 입니다.
아주 간단한 도형그리기 기초 함수를 구성해 보았습니다.
Mouse Event로 사용자의 Action 을 받아 들여 canvas 를 도화지처럼 사용할 수 있는
기초 함수 들 입니다.
- Canvas 에서 사용할 꾸미기 옵션에 관련한 간단한 예시 입니다.
해당 내용이 추가 되더라도 이곳에서 더 추가후 진행할 수 있도록 함수화 하여 구성
ie 에서는 Object.assign 이 사용되지 못하기 때문에 json 객체는 직접 복제하여야 합니다.
// Object.assign({}, source);
// IE NOT WORKING ....
function getDefaultOptions() {
var obj = {
strokeStyle : "#000000",
fillStyle : "#000000",
lineWidth : 2
};
return obj;
}
function setCurrentOptions(ctx, sOptions) {
if ( !ctx ) {
return;
}
if ( !sOptions ) {
return;
}
ctx.strokeStyle = sOptions.strokeStyle;
ctx.lineWidth = sOptions.lineWidth;
ctx.fillStyle = sOptions.fillStyle;
}
- Line 은 다음과 같은 함수를 활용해 보았습니다.
Polyline 을 그리는 함수는 직접 쓰기 그리기 및 도형을 그리는 영역에서도 사용할 수
있습니다.
function drawLine(ctx, sx, sy, ex, ey, sOptions) {
if ( !ctx )
return;
ctx.save();
setCurrentOptions(ctx, sOptions);
ctx.beginPath();
ctx.moveTo(sx,sy);
ctx.lineTo(ex,ey);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function makePolylines(ctx, sx, sy, ex, ey, points, sOptions, isClosed, isFilled ) {
if ( !ctx )
return;
ctx.save();
setCurrentOptions(ctx, sOptions);
ctx.beginPath();
ctx.moveTo(sx,sy);
if ( points ) {
for ( let i = 0, iSize= points.length; i < iSize; i++ ) {
ctx.lineTo(points[i][0],points[i][1]);
}
}
ctx.lineTo(ex,ey);
if ( isClosed || isFilled ) {
ctx.closePath();
if ( isFilled ) {
ctx.fill();
} else {
ctx.stroke();
}
} else {
ctx.stroke();
ctx.closePath();
}
ctx.restore();
}
function drawBezierLine(ctx, sx, sy, ex, ey, points, sOptions ) {
if ( !ctx )
return;
ctx.save();
setCurrentOptions(ctx, sOptions);
ctx.beginPath();
ctx.moveTo(sx,sy);
let mx01 = sx;
let my01 = sy;
let mx02 = ex;
let my02 = ey;
if ( points ) {
if ( points.length == 1 ) {
mx01 = points[0][0];
my01 = points[0][1];
}
if ( points.length >= 2 ) {
mx01 = points[0][0];
my01 = points[0][1];
mx02 = points[1][0];
my02 = points[1][1];
}
}
ctx.bezierCurveTo(mx01,my01, mx02, my02, ex,ey);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
- 도형은 더 구성할 수도 있지만, 대략 사각형, 원, 타원 등을 그리도록 구성해 보았습니다.
사각형이나, 타원은 위 polyline 으로 구성해 보았습니다.
ie 가 아닌 경우 타원을 그리는 함수가 지원되지만, 구현이 간단하기 때문에 구성해
보았습니다. rotate 등의 각은 모두 radian 을 사용합니다.
function makeRectangle(ctx, sx, sy, ex, ey, sOptions, isFilled ) {
if ( !ctx )
return;
let points = [];
points.push([sx,ey]);
points.push([ex,ey]);
makePolylines(ctx, sx,sy, ex,sy, points, sOptions, true, isFilled );
}
function makeEllipse(ctx, sx, sy, ex, ey, sOptions, isFilled ) {
if ( !ctx )
return;
let rx = Math.abs(sx-ex);
let ry = Math.abs(sy-ey);
let ssx = sx;
let ssy = sy;
let points = [];
for ( let i = 0; i < 360; i++ ) {
let rv = (Math.PI*i/180);
if ( i == 0 ) {
ssx = Math.sin(rv)*rx + sx;
ssy = Math.cos(rv)*ry + sy;
} else if ( i == 359 ) {
ex = Math.sin(rv)*rx + sx;
ey = Math.cos(rv)*ry + sy;
} else {
points.push([Math.sin(rv)*rx+sx, Math.cos(rv)*ry+sy]);
}
}
makePolylines(ctx, ssx,ssy, ex,ey, points, sOptions, true, isFilled );
}
function makeArc(ctx, sx, sy, ex, ey, sOptions , isFilled) {
if ( !ctx )
return;
let radious = Math.sqrt( Math.pow((sx-ex),2)+Math.pow((sy-ey),2));
alert ( radious );
ctx.save();
setCurrentOptions(ctx, sOptions);
ctx.beginPath();
ctx.arc(sx, sy, radious, 0, Math.PI*2);
ctx.closePath();
if ( isFilled ) {
ctx.fill();
} else {
ctx.stroke();
}
ctx.restore();
}
위 함수로 간단히 그려본 결과 입니다.
Mouse Event를 활용 하면 간단한 그림 그리기 도구를 만들 수 있습니다.
function drawTest() {
......
var ctx = canvasObjects.display[1];
var opt = getDefaultOptions();
opt.strokeStyle = "red";
opt.lineWidth = 10;
drawBezierLine(ctx, 100, 100, 300, 300, [[300,100],[100,300]], opt) ;
opt.strokeStyle = "blue";
opt.lineWidth = 3;
makeRectangle(ctx, 100, 100, 300, 300, opt, false);
makeEllipse(ctx, 400,300, 450, 200, opt, false);
opt.strokeStyle = "cyan";
makeArc(ctx, 400, 300, 450, 200, opt, false);
}
댓글 없음:
댓글 쓰기