Tizen의 사용자 지정 2D 그래픽

이 문서에서는 TizenPaint 샘플 앱을 통해 HTML5 캔버스 API와 Fabric 캔버스 API 모두 사용하여 사각형, 원형, 삼각형 등의 기본 도형을 그리는 방법에 대해 설명합니다. 또한 획의 너비와 색상 등 기본 도형의 일부 속성을 변경하는 방법에 대해 설명합니다. 본 문서의 뒷부분에서 직렬화된 문자열 형태에서 그림 저장 방법에 대한 주제도 다룰 것입니다.

HTML5 Canvas API & Fabric.js 이해

자세한 내용으로 들어가기 전에 먼저 HTML5 캔버스와 Fabric.js JavaScript 프레임워크에 익숙해져야 합니다. HTML5 Canvas는 동적으로 2D/3D 그래픽을 그리는 데 사용할 수 있는 DOM 요소입니다. 그래픽 개체를 그릴 수 있는 웹 페이지 또는 장치 화면에 정의된 영역입니다. 캔버스를 만들려면 이 코드를 HTML 파일에 추가할 수 있습니다.

"paint-canvas" width="680" height="1000">

  Fabric.js 프레임워크는 캔버스 요소 상단에 내장된 대화형 개체 모델입니다. 이를 사용하면 HTML5 캔버스 요소를 사용하여 작업하기가 한결 수월합니다. 기하학적 모양 및 수백 또는 수천 개의 간단한 경로로 구성된 복잡한 모양과 같은 개체를 만들고 채울 수 있습니다. Fabric.js 라이브러리를 사용하는 방법에 대한 자세한 내용은 http://fabricjs.com/docs/를 방문하십시오.

 

TizenPaint 샘플 애플리케이션 소개

TizenPaint 샘플 애플리케이션은 HTML5 Canvas API와 Fabric.js 프레임워크를 사용하여 HTML5 캔버스에서 2D 그래픽을 만들고 작업하는 방법을 보여줍니다. 이 샘플 애플리케이션의 UI에는 한 페이지 요소만으로 구성되어 있습니다. 샘플 애플리케이션을 실행한 후 다른 이름으로 저장, 열기, 그리기 등 빈 캔버스와 일부 버튼이 표시됩니다. 이 샘플을 페이지 하단에 있는 두 개의 버튼으로 표시된 그리기 및 편집의 두 가지 모드로 사용할 수 있습니다. 기본 모드는 편집 모드입니다. 편집 모드에서는 예를 들어 선택한 개체를 이동, 크기 조정 또는 회전하고 개체의 색상 또는 선 너비를 변경하거나 사용 가능한 이미지 리소스(“이미지” 폴더에 저장)에서 SVG 파일을 추가하는 등 개체를 조작할 수 있습니다. 그리기 모드를 설정하고 화면을 터치하여 새 개체를 그릴 수 있습니다. 제공한 도구를 사용하여 선, 사각형, 원형, 삼각형 및 다각형 등 간단한 2D 셰이프를 그릴 수 있습니다. 장치 저장소에 그림을 저장할 수 있습니다. 샘플 애플리케이션은 Tizen(720 x 1280)에 전체 뷰포트를 사용하고 및 jQuery 1.8.0 라이브러리를 포함합니다.샘플 애플리케이션은 Tizen SDK 2.0.0a2에서 테스트되었습니다.    

그림: 샘플 애플리케이션 스크린샷

frabric.js 프레임워크를 사용하여 캔버스에 그리기

캔버스 API를 사용하여 기본 셰이프인 사각형을 직접 그릴 수 있습니다. 다른 셰이프를 그리려는 경우 하나 또는 여러 경로를 생성한 다음 캔버스에 경로를 그려야 합니다. 또는 fabric.js 프레임워크를 사용하여 복잡한 셰이프를 좀 더 편리한 방법으로 그릴 수 있습니다. 각 셰이프를 정의된 속성을 가진 개체로 생성할 수 있는 대신 경로 지점을 정의하고 경로를 연결할 필요가 없습니다. 문서에서 fabric.js 프레임워크와 Canvas API를 사용하여 셰이프를 만드는 방법을 보여줍니다. fabric.js 프레임워크를 사용하려면 다음과 같이 Canvas 요소에 fabric.Canvas() 개체의 인스턴스를 생성해야 합니다.

var fabricCanvas = new fabric.Canvas('paint-canvas');

fabric.Canvas 생성자를 호출할 때 fabric.js 프레임워크는 보조 캔버스 요소(“upper-canvas” 클래스 ID를 가진 캔버스임)를 DOM에 추가합니다.

"paint-canvas" class="lower-canvas">
"upper-canvas">

“Draw” 버튼을 클릭하면 그리기 모드를 활성화하고 캔버스에 있는 다른 모든 항목의 선택을 취소합니다. 이는 그리는 동안 일부 임의의 개체를 선택하는 상황을 방지하기 위한 것입니다.

$('#add-figure').unbind().click(function() {
    /**
     * Draws line or adds figure on click
     */
    if ($('#shape-menu').hasClass('hidden')) {
        drawMode = true;
        if (currShape == 'pencil')
            fabricCanvas.isDrawingMode = true;
        else
            $('#stroke-menu').toggleClass('hidden', false);
        if (currShape == 'polygon')
            $('#vertex').toggleClass('hidden', false);
        if (!($('#colors-menu').hasClass('hidden'))) {
            $('#colors-menu').addClass('hidden');
            $('#choose-color').removeClass('selected');
        }
        $('#shape-menu').toggleClass('hidden', false);
        $('#edit-figure').removeClass('selected');
        $('#add-figure').addClass('selected');

        fabricCanvas.deactivateAll();
        for ( var i = 0; i < fabricCanvas.getObjects().length; i++)
            fabricCanvas.item(i).selectable = false;

        fabricCanvas.renderAll();

    } else {
        $('#shape-menu').toggleClass('hidden', true);
        $('#stroke-menu').toggleClass('hidden', true);
        $('#vertex').toggleClass('hidden', true);
    }
});

기본적으로 선택한 도구는 간단한 선을 그릴 수 있는 연필입니다. 이 도구를 사용하려면 fabricCanvas.isDrawingMode를 true로 설정해야 합니다.

Canvas API를 사용하여 캔버스에 그리기

Canvas API를 사용하여 캔버스에 그리는 옵션도 있습니다.  Canvas API를 사용하려면 다음 코드를 사용하여 touchstart와 touchmove의 두 가지 이벤트를 처리하기 위해 캔버스를 등록해야 합니다.

canvas.addEventListener("touchstart", handleStart);
canvas.addEventListener("touchmove", handleMove);

addEventListener() 메서드로 전달된 첫 번째 매개 변수는 이벤트 유형입니다. 두 번째 매개 변수는 리스너 그 자체입니다. 지정한 이벤트 유형이 발생하면 알림을 수신합니다. 그림 자체는 실제로 터치 위치를 기록할 뿐입니다. 다음 코드를 사용하여 수행할 수 있습니다.

function handleStart(evt) {
    var touches = evt.changedTouches[0];
    var x = touches.pageX - leftPos;
    var y = touches.pageY - topPos;

evt.changedTouches[0] 속성은 사용자의 뷰 포트에서 첫 번째 터치 점을 나타내는 개체를 반환합니다. touches.pageX 및 touches.pageY 속성은 뷰 포트의 왼쪽 맨 윗부분 모서리를 기준으로 x 및 y 좌표를 나타냅니다. leftPos 및 topPos 속성은 캔버스의 왼쪽 맨 윗부분 모서리를 기준으로 x 및 y 좌표를 나타냅니다. touches.pageX(the same applies to topPos and touches.pageY)에서 leftPos를 빼면 캔버스의 x(또는 y) 좌표 지점을 가져옵니다. 'Touchstart' 리스너에서 beginPath() 메서드를 호출하여 그림을 그리기 시작하고 ctx.moveTo(x,y) 메서드를 사용하여 시작 지점을 정의해야 합니다.

    ctx.beginPath();
    ctx.moveTo(x,y);

‘touchmove’ 리스너에서 lineTo(x, y) 메서드를 사용하여 선의 끝 지점(또는 경로)을 정의하고 stroke() 메서드를 호출하여 선을 스트로크해야 합니다.

    ctx.lineTo(x, y);
    ctx.stroke();

 

다른 셰이프 그리기

이 섹션에서는 fabric.js API와 Canvas API를 모두 사용하여 더 복잡한 셰이프를 그리는 방법에 대해 설명합니다.  가장 간단한 셰이프인 사각형부터 시작합니다.  

사각형

fabric.js API를 사용할 때 사각형을 그리는 것은 간단합니다. 다음 코드를 사용하여 사각형을 만들 수 있습니다.

var rect = new fabric.Rect({
    width : 100,
    height : 100,
    left : x,
    top : y,
    selectable : false
});

왼쪽 및 상단 속성은 사각형의 중심점 위치를 표시합니다. 너비와 높이 속성은 사각형의 크기를 정의합니다. 선택 가능한 속성은 개체가 선택 가능한지 여부를 나타냅니다. 마지막으로 add() 메서드를 호출하여 이 사각형을 캔버스에 추가합니다.

fabricCanvas.add(rect);

사각형의 색상을 변경하려는 경우 다음 사각형 개체의 속성을 사용할 수 있습니다.

  • ‘fill’ – 주어진 색으로 셰이프를 채우려는 경우
  • ‘stroke’ – 획의 색상을 주어진 색으로 설정하려는 경우
fill : 'rgb(34,177,76)',
stroke : 'rgba(0,0,0,0.8)',

fill 또는 stroke 속성의 색상을 지정하지 않는 경우 기본 색상은 검은색입니다. 기본 색상을 변경하려는 경우 W3C CSS3 색상 권장 사항에 정의된 색상을 지정할 수 있습니다. Canvas API와 달리 fabric.js에서는 모든 셰이프가 개체입니다. 속성 값을 변경하려는 경우 set() 메서드를 사용할 수 있습니다.

rect.set('left', 'x+50');

  Canvas API를 사용하여 사각형을 그릴 때 다음 메서드를 사용할 수 있습니다.

  • 채워진 사각형: fillRect(x,y,width,height)
  • 획을 포함한 빈 사각형: strokeRect(x,y,width,height)

X 및 y 좌표는 사각형의 왼쪽 상단 모서리에 있습니다. 너비 및 높이는 사각형의 크기를 정의합니다. 캔버스 API를 사용하여 사각형을 그릴 때 fabric.js API를 사용할 때와는 달리 중심점이 아닌 사각형의 왼쪽 상단 모서리를 정의해야 합니다. Canvas API에는 셰이프에 색상을 적용하는 데 사용할 수 있는 두 가지 중요한 속성인 fillStyle 및 strokeStyle이 있습니다.

fillStyle = color
strokeStyle = color

 

패브릭에 원을 그리는 것은 매우 간단합니다. 다음과 같이 fabric.js에서 원 개체를 만들 수 있습니다.

var circle = new fabric.Circle({
    radius : 50,
    left : x,
    top : y,
    opacity : 1,
    selectable : false
});

원 개체 속성을 초기화해야 합니다. 예를 들어 원의 반경을 50픽셀로, 중심점을 (x, y)로, 불투명도를 1로 초기화하고 원의 선택을 취소합니다. arc() Canvas API를 사용하여 원을 그리는 또 다른 방법이 있다.

ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)

arc() 메서드는 가상 원의 둘레 부분을 그립니다. 원은 중심점(x, y)과 radius 매개 변수에 의해 정의됩니다. startAngle 및 endAngle 매개 변수는 양의 x축에서 시계 방향에서 라디안으로 정의됩니다. 마지막 매개 변수는 두 점 사이의 원호 경로 방향을 정의합니다. 전체 원을 그려야 하는 경우 startAngle = 0 * Math.PI, endAngle = 2 * Math.PI를 정의할 수 있습니다.

http://www.html5canvastutorials.com/demos/tutorials/html5-canvas-arcs/html5-canvas-arcs-diagram.png

그림: 원호 매개 변수

 

삼각형

아래의 코드를 사용하여 fabric.js에서 삼각형을 그리는 것은 간단합니다.

var triangle = new fabric.Triangle({
    left : x,
    top : y,
    width : 100,
    height : 100,
    opacity : 1,
    selectable : false
});

속성: 왼쪽 및 상단은 삼각형의 중심 위치를 표시합니다. 다른 속성은 상당히 명백합니다. Canvas API를 사용하여 삼각형을 그리려는 경우 fabric.js API를 사용하는 것보다 조금 더 복잡합니다. 앞에서도 언급했듯이, 주어진 Canvas 메서드를 사용하여 사각형만 그릴 수 있습니다. 다른 셰이프의 경우 moveTo 및 lineTo 메서드를 사용하여 경로를 생성해야 합니다. 다음 코드는 삼각형을 그리는 방법을 보여줍니다.

ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x+50, y+100);
ctx.lineTo(x-50, y+100);
ctx.lineTo(x, y);

ctx.fill(); 	// for filled triangle
//ctx.stroke(); 	// for stroked triangle
ctx.closePath();

 

그리기 속성 변경

캔버스에 몇 가지 기본적인 모양을 그리는 방법을 배웁니다. 이제 채우기 색상 및 획의 너비 등 셰이프의 속성을 변경하는 방법을 보여줍니다. 다시 TizenPaint 샘플을 예로 사용합니다. 샘플 애플리케이션의 “Colors” 버튼을 클릭하면 사용 가능한 색상과 선 너비에 대한 메뉴를 보여줍니다. 선 너비를 변경할 때 전달한 값과 함께 setStrokeWidth() 메서드를 호출합니다. 다음 코드는 stroke width using fabric.js API를 사용하여 획 너비를 설정하는 방법을 보여줍니다.

function setStrokeWidth(value) {
    $('#line-width').text(value);
    fabricCanvas.freeDrawingLineWidth = parseInt($('#line-width').text(), 10);

    if (fabricCanvas.getActiveObject()) {
        if (fabricCanvas.getActiveObject().get('stroke')) {
            fabricCanvas.getActiveObject().set('strokeWidth', parseInt($('#line-width').text(), 10) || 1);
        }
        fabricCanvas.renderAll();
    }
}

셰이프를 그리기 전에 선 너비를 변경하려는 경우 fabricCanvas.freeDrawingLineWidth 속성을 사용하여 그리기 모드에서 선 너비를 설정할 수 있습니다. 선택한 셰이프의 선 너비를 변경하려는 경우 fabricCanvas.getActiveObject() 메서드를 사용하여 캔버스 개체를 선택하고 get() 매서드를 사용하여 선택한 캔버스 개체의 ‘stroke’ 속성을 선택할 수 있습니다. 마지막으로 set() 메서드를 사용하여 선 너비 값을 설정할 수 있습니다. 이제 그림 개체의 색상을 변경하는 방법을 살펴봅니다. 샘플 애플리케이션에서 setColors()라는 메서드를 구현합니다. 색상을 선택하는 경우 이 메서드를 호출합니다. setColors() 메서드는 그림 색상뿐만 아니라 캔버스에서 활성 개체의 ‘fill’ 또는 ‘stroke’ 속성 색상도 변경합니다. 다음 코드는 setColors() 메서드가 구현되는 방법을 보여줍니다.

function setColors(color) {
    if (!(color.prop("checked"))) {
        actualColor.css('border', '1px solid black');
        actualColor.prop("checked", false);
        color.css('border', '3px solid red');
        color.prop("checked", true);
        actualColor = color;

        fabricCanvas.freeDrawingColor = color.css('background-color');

        if (fabricCanvas.getActiveObject())
            if (fabricCanvas.getActiveObject().get('active'))
                if (fabricCanvas.getActiveObject().get('stroke'))
                    fabricCanvas.getActiveObject().set('stroke', color.css('background-color'));
                else
                    fabricCanvas.getActiveObject().set('fill', color.css('background-color'));

        fabricCanvas.renderAll();
    }
}

이 메서드에서 fabricCanvas.freeDrawingColor 속성을 사용하여 그리기 모드에서 색상을 설정할 수 있습니다. fabricCanvas인 상단 캔버스와 HTML5 캔버스 요소인 보조 컨테이너 캔버스의 변경 사항을 렌더링하는 fabricCanvas.renderAll() 메서드를 호출해야 합니다. 캔버스 레이어에 대한 자세한 내용은 여기에서 찾을 수 있습니다. 패브릭 캔버스를 지우려는 경우 fabricCanvas.clear() 메서드를 사용할 수 있습니다.  

편집 모드 옵션 사용

이 섹션에서 샘플 앱에서 편집 모드를 사용하는 방법을 설명합니다. “Edit” 버튼을 클릭할 때 editModeOn() 메서드를 호출하고 편집 모드를 설정합니다. 한편 이 메서드는 그리기 모드를 비활성화하고 일부 옵션(표시되어 있는 경우)을 숨기고 캔버스의 모든 항목의 선택을 취소합니다.

function editModeOn() {
    if (drawMode) {
        drawMode = false;
        fabricCanvas.isDrawingMode = false;
        $('#shape-menu').toggleClass('hidden', true);
        $('#stroke-menu').toggleClass('hidden', true);
        $('#vertex').toggleClass('hidden', true);
        $('#add-figure').removeClass('selected');
        $('#edit-figure').addClass('selected');

        for ( var i = 0; i < fabricCanvas.getObjects().length; i++) {
            fabricCanvas.item(i).selectable = true;
        }

        fabricCanvas.renderAll();
    }
}

편집 모드에서 셰이프를 선택하고 다음을 수행할 수 있습니다.

  • 드래그 앤 드롭으로 셰이프 이동
  • 셰이프 주위의 컨트롤 중 하나를 클릭하고 당기거나 회전시켜 셰이프 크기 조정/회전
  • 'Colors' 메뉴를 선택하여 색상 또는 선 너비 변경(획 구성된 셰이프의 경우)

파일 저장 및 열기

Fabric.js를 사용하면 JSON 개체에 전체 캔버스를 직렬화할 수 있습니다. “Save” 버튼을 클릭할 때 stringify()라는 직렬화 함수를 호출합니다.

var canvasSerialized = JSON.stringify(fabricCanvas);

캔버스를 직렬화한 후 장치 파일 시스템에서 canvasSerialized 개체를 처리할 수 있습니다. Filesystem Tizen Device API를 사용하여 문자열에 불과한 이 개체를 파일에 저장합니다. 다음 섹션에서는 해당 작업의 수행 방법을 설명합니다.  

Filesystem Tizen Device API 사용

Tizen Filesystem API를 사용하여 장치의 파일 시스템에 대해 액세스할 수 있습니다. Filesystem 개체 기능을 사용하려면 config.xml 파일에 이 기능(http://tizen.org/api/filesystem)을 선언해야 합니다. Filesystem Tizen Device API에 대한 자세한 내용은 여기에서 찾을 수 있습니다.  

디렉터리 확인

무엇이든 파일에 저장하기 전에 작동하려고 하는 파일에 대한 디렉터리를 지정해야 합니다. 샘플 애플리케이션에서 모든 텍스트 문서에 대해 ‘documents’라는 루트 폴더를 사용합니다. 모든 디렉터리 작업에 앞서 디렉터리를 확인해야 합니다. 확인 작업은 애플리케이션이 디렉터리에 액세스할 수 있는지 결정합니다. 액세스가 허용되는 경우 디렉터리를 나타내는 개체가 제공됩니다. dir이라는 파일 핸들은 콜백 함수에 반환됩니다. 이 파일을 만들거나 삭제하는 등 이 파일에 다양한 작업을 수행할 때 사용할 수 있습니다. tizen.filesystem.resolve() 메서드는 다음 매개 변수를 사용합니다.

  • 위치 - 파일 또는 디렉터리에 대한 상대 경로
  • 성공 콜백 - 작업 성공 시 호출됨
  • 오류 콜백 - 오류 발생 시 호출됨(선택 사항)
  • 모드 - 파일 또는 디렉터리를 여는 데 애플리케이션이 요청하는 모드(선택 사항), 가능한 값: "r"(읽기) 또는 "rw"(읽기 및 쓰기)

이것이 샘플 애플리케이션이 이 메서드를 사용하는 방법입니다.

tizen.filesystem.resolve("documents", function(dir) {
    gDocumentsDir = dir;
}, onError, "rw");

성공 콜백에 전달된 유일한 매개 변수는 dir라는 파일 핸들입니다. 파일 핸들은 파일이나 디렉터리가 될 수 있습니다. 이 경우에는 디렉터리를 나타냅니다. 콜백 함수에서 파일 핸들 dir를 샘플 애플리케이션의 다른 부분에 사용될 gDocumentsDir라는 자체 변수에 할당합니다. 파일을 저장하고 재정의해야 하기 때문에 이 경우에는 파일 모드를 ‘rw’로 설정합니다.  

파일 만들기 및 쓰기

디렉터리를 확인하고 디렉터리 또는 파일에 액세스하면 지금 생성하고 파일에 쓸 수 있습니다. 파일 개체에 의해 제공된 createFile() 메서드를 사용하여 주어진 파일 이름으로 파일을 생성할 수 있습니다. 샘플 애플리케이션에서 입력 필드에 파일 이름을 입력하고 “Save” 버튼을 클릭하여 파일을 생성합니다.

var filename = $('#file-name').val();

try {
    gDocumentsDir.createFile(filename);
} catch (exc) {
    $('#save-popup').toggleClass('hidden', false);
    return;
}

파일이 이미 존재하는 경우 샘플 애플리케이션이 팝업을 표시하고 파일 이름을 변경하거나 기존 파일을 재정의할 수 있습니다. 이 함수는 아래와 같이 writeToFile() 메서드에서 구현됩니다.

var filename = $('#file-name').val();

function writeToFile(filename) {
    var file;

    try {
        file = gDocumentsDir.resolve(filename);
    } catch (exc) {
        console.error('Could not resolve file: ' + exc.message);
        return;
    }

    try {
        file.openStream('w', writeToStream, onError);
    } catch (exc) {
        console.error('Could not write to file: ' + exc.message);
    }
}

기존 파일에 작성하는 것은 새 파일을 만드는 것과 약간 다릅니다. 파일 개채에서 제공하는 resolve() 메서드를 사용하여 파일을 확인해야 합니다. 이 경우에는 gDocumentsDir 개체입니다. 메서드는 Openstream() 메서드를 사용하여 파일을 여는 데 사용하는 새 파일 핸들을 반환합니다. 여기서는 'w'를 메서드에 전달하기 위해 쓰기 모드로 열려고 합니다. 성공 콜백 함수는 다음과 같습니다.

function writeToStream(fileStream) {
    try {
        fileStream.write(canvasSerialized);
        fileStream.close();
    } catch (exc) {
        console.error(exc.message);
    }
}

  JSON 문자열인 직렬화된 캔버스를 파일에 저장하려고 합니다. 따라서 canvasSerialized 문자열 개체를 write() 메서드에 전달합니다. 텍스트가 파일에 작성된 후 close() 메서드를 사용하여 스트림을 닫습니다. 오류가 발생할 경우 onError() 오류 콜백 함수가 호출됩니다.

function onError(err) {
    console.error("Error: " + err.message);
}

 

파일에서 읽기

샘플 애플리케이션을 사용하면 직렬화된 캔버스를 포함하는 파일을 열 수 있습니다. 당신은 캔버스를 가져오고 개체를 수정할 수 있습니다. 이 섹션에서 파일을 읽는 방법을 보여줍니다. 파일 열기 이벤트를 처리하는 displayFileContents()라는 메서드를 구현합니다. “Open” 버튼을 클릭할 때 이 메서드를 호출합니다. 다음 코드는 구현하는 방법을 보여줍니다.

function displayFileContents() {
    var file;

    try {
        file = gDocumentsDir.resolve($('#file-name').val());
    } catch (exc) {
        console.error('resolve() exception: ' + exc.message);
        return;
    }

    try {
        file.openStream('r', readFromStream, onError);
    } catch (exc) {
        console.error('openStream() exception:' + exc.message);
    }
}

앞에서 설명한 것처럼 writeToFile() 메서드와 매우 유사합니다. resolve() 메서드에서 파일 핸들을 받은 후 파일 개체에서 openStream() 메서드를 호출하고 'r'을 전달하여 읽기 모드로 파일을 열 것인지 지정합니다. 성공 콜백 함수 및 오류 콜백 함수도 필요합니다. 구현한 성공 콜백 함수는 readFromStream()이라고 합니다. OpenStream() 메서드에서 스트림을 사용합니다.

function readFromStream(fileStream) {
    try {
        var contents = fileStream.read(fileStream.bytesAvailable);
        fileStream.close();

        fabricCanvas.loadFromJSON(contents);

        for ( var i = 0; i < fabricCanvas.getObjects().length; i++) {
            if (drawMode)
                fabricCanvas.item(i).set('selectable', false);
            else
                fabricCanvas.item(i).set('selectable', true);
        }
    } catch (exc) {
        console.error('File reading exception: ' + exc.message);
    }
}

스트림에서 유효한 바이트를 읽을 수 있도록 bytesAvailable 속성을 사용해야 합니다. 스트림에서 읽을 수 있는 바이트 수를 반환합니다. 그런 다음 read() 메서드는 주어진 FileStream에서 모든 문자를 읽습니다. 스트림에서 읽기 완료되면 close() 메서드를 호출하여 스트리밍을 닫아야 합니다. 다음 단계는 캔버스 개체에 대한 JSON 개체인 직렬화된 문자열을 구문 분석하는 것입니다. Fabric.js는 작업을 수행하기 위해 loadFromJSON()이라는 메서드를 제공합니다. 참고: 샘플 애플리케이션이 ‘Draw 모드’에 있는 경우 모든 개체는 선택할 수 없어야 합니다.

SVG 파일

fabric.js 프레임워크와 함께 수행할 수 있는 것이 한 가지 더 있습니다. SVG 이미지를 캔버스에 삽입할 수도 있습니다. 샘플 애플리케이션의 “SVG files” 버튼을 사용하면 해당 작업을 수행할 수 있습니다. 세 가지 버튼(SVG1, SVG2, SVG3)으로 메뉴를 엽니다. 모든 버튼은 loadSVGFromURL()이라는 함수를 트리거합니다.

var svgFileName = 'someFile.svg';

fabric.loadSVGFromURL('images/' + svgFileName + '.svg', function(objects, options) {
    var loadedObject = fabric.util.groupSVGElements(objects, options);

    loadedObject.set({
        left : x,
        top : y,
        angle : 0,
        padding : 0
    });
    loadedObject.setCoords();

    fabricCanvas.add(loadedObject);
});

svgFileName은 파일 이름을 나타내는 문자열입니다. loadSVGFromURL() 메서드의 첫 번째 매개 변수는 SVG 파일에 대한 경로입니다. 두 번째 매개 변수는 SVG 파일에서 가져온 요소의 배열을 검색하는 성공 콜백 함수입니다. fabric.util.groupsvgelements는 SVG 파일에서 요소를 그룹화하는 데 사용됩니다. setCoords() 메서드는 모서리 위치 좌표를 설정합니다. 마지막으로 fabricCanvas.add() 함수는 캔버스에 SVG 이미지를 그립니다.  

애플리케이션 종료

샘플 애플리케이션은 종료될 수 있습니다. 이러한 기능을 제공하려면 다음을 수행해야 합니다.

  • config.xml 파일에서 application.read 기능을 추가합니다.
"http://tizen.org/api/application.read" required="true"/>
  • 이러한 방법 등으로 Exit 버튼을 index.html에 추가합니다.
"submit" id="close" value="Close" class="top-menu-button"/>
  • 종료 버튼으로 종료 메서드를 바인딩합니다.
$("#close").unbind().click(function(event) {
    tizen.application.exit();
});

요약

이 문서에서는 Canvas API 및 fabric.js를 사용하여 캔버스에 간단한 2D 셰이프를 그릴 수 있는 방법, fabric.js 프레임워크를 사용하여 캔버스를 저장하고 파일로 여는 방법, 마지막으로 fabric.js를 사용하여 SVG 이미지를 캔버스에 삽입하는 방법을 설명합니다. 보시다시피 Tizen에 이러한 기능을 구현하는 것은 어렵지 않습니다. 이 문서가 Tizen 웹 앱에서 간단한 2D 게임과 애니메이션을 만드는 데 도움이 되기를 바랍니다.

첨부 파일: