[blazor] 시그니처 패드 넣기 js > c# 메소드 호출, c# > js 메소드 호출

코찔찔이·2023년 7월 6일
0

blazor강의 따라하기

목록 보기
10/23
  • javascript로 만들어진 Signaturpad를 razor 페이지에서 rendering 하기
  • c# 코드에서 javascript 메소드 호출 하기.
  • javascript에서 C# 메소드 호출하기
    js에서 C#메소드는 정적인 메소드만 호출 가능 하며 [JSInvokable] 어노테이션을 메소드에 적용 하면됨.

SignaturePad 가져오기

razor에서 만든 canvas를 SignaturePad 적용

  1. google에서 signature_pad검색
  2. 시그니처패드 깃허브경로에서 소스 다운로드
  3. 다운 받은 소스중 css,js를 복사 하여 blazor소스 파일에 붙여넣기.

  4. 기존 SignaturePad.js 이름을 BlazorSignaturePad.js로 변경.
  5. _Host.cshtml 파일에 <link rel="stylesheet" href="_content/ChartJs.Blazor/ChartJSBlazor.css" /> javascript 호출 추가.
  6. c#에서 canvas id를 받아 해당 canvas를 SignaturePad로 변경 하는 함수
    SignaturePad함수는 기존 SignaturePad.js에 정의되어 있는 함수
window.BlazorSignaturePad = function (id) {
    var canvas = document.getElementById(id);


    var signaturePad = new SignaturePad(canvas, {
        // It's Necessary to use an opaque color when saving image as JPEG;
        // this option can be omitted if only saving as PNG or SVG
        backgroundColor: 'rgb(255, 255, 255)'
    });
}
  1. SignaturePad.razor에서 javascript에서 만든 BlazorSignaturePad메소드를 호출 하여 canvas를 signaturpad적용.
@page "/SignaturePad"
@inject IJSRuntime js

<h3>SignaturePad</h3>

<canvas width="300" height="300" id="theCanvas" style="border: 1px solid red;">
    </canvas>

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if(firstRender)
        {
            await js.InvokeAsync<object>("BlazorSignaturePad", "theCanvas");
        }
    }
}


SignaturePad.razor 페이지

  1. GetImageDataAsync메소드는 JSInvokable어노테이션을 적용 하여
    js에서 호출할 수 있으며 js에서 이미지 데이터를 받아오는 메소드.
  2. 가져오기 버튼을 누르면 js에서 받은 이미지 데이터(ImageDataSrc)를
    image로 아래 복사하기.
  3. 지우기 버튼을 누르면 canvas를 초기화 하여 이미지를 지우기.
@page "/SignaturePad"
@inject IJSRuntime js

<h3>SignaturePad</h3>

<canvas width="300" height="300" id="theCanvas" style="border: 1px solid red;">
    </canvas>
<hr />
<input type="text" @bind="ImageData" id="txtSignature" />
<hr />
<img src="@ImageDataSrc" />
<hr />
<input type="button" value="가져오기" @onclick="GetImageData" />
<input type="button" value="지우기" @onclick="DeleteData" />

@code {
    //랜더링 완료 후 호출 되는 함수
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        //처음 랜더링 될때만 firstRender매게변수가 true가 됨.
        if(firstRender)
        {
            await js.InvokeAsync<object>("BlazorSignaturePad", "theCanvas");
        }
    }

    string ImageData = "";

    private string ImageDataSrc = "";

    public void GetImageData()
    {
        ImageDataSrc = SignaturePad.GetImageSrc();
    }

    //canvas 초기화
    public async Task DeleteData()
    {
        await js.InvokeAsync<object>("BlazorSignaturePad", "theCanvas");
    }

    public static string GetImageSrc()
    {
        return ImageDataFromJavaScript;
    }


    private static string ImageDataFromJavaScript = "";
    //js에서 호출되어 이미지 정보 전달받음.
    [JSInvokable]
    public static void GetImageDataAsync(string imageData)
    {
        ImageDataFromJavaScript = imageData;
    }
}

SignaturePad.js 수정

  1. _strokeEnd함수는 원래 정의가 되어 있었으며 그리기가 끝나면 .razor페이지에 이미지 데이터 전송하기위해 아래 추가된 부분에 2개의 메소드 추가.
  2. document.getElementById("txtSignature").value = this.toDataURL();
    id가 txtSignature 객체에 value값으로 이미지 데이터 전송.(base64)
  3. DotNet.invokeMethodAsync("BlazorApp", "GetImageDataAsync", this.toDataURL());
    .net에서 작성된 정적 메소드를 호출 하여 이미지 데이터 전송(base64)
 _strokeEnd(event) {
            this._strokeUpdate(event);
            this.dispatchEvent(new CustomEvent('endStroke', { detail: event }));

            //추가된부분=========================================================================================
            //this.toDataURL()함수가 정의 되어 있으며 그리다가 마우스를 놓는 순간 이미지를 base64형식으로 반환.
            //id가 txtSignature인 컨트롤러에 이미지 데이터 입력.
            document.getElementById("txtSignature").value = this.toDataURL();

            //js에서 c#에서 생성한 메소드 호출 매개변수 (프로젝트명, 함수 이름, 매개변수)
            DotNet.invokeMethodAsync("BlazorApp", "GetImageDataAsync", this.toDataURL());
            //추가된부분=========================================================================================
        }

//추가된부분=========================================================================================
//블레이저에서 canvas를 SignaturePad로 변환하기위해 호출 함.
window.BlazorSignaturePad = function (id) {
    var canvas = document.getElementById(id);


    var signaturePad = new SignaturePad(canvas, {
        // It's Necessary to use an opaque color when saving image as JPEG;
        // this option can be omitted if only saving as PNG or SVG
        backgroundColor: 'rgb(255, 255, 255)'
    });
}
//추가된부분=========================================================================================

실행 화면 및 정리

  1. 그리기를 완료하면 아래 input박스에 이미지 정보가 base64로 인코딩된 string 형태로 받게됨. 2번째 이미지 참조.
    js에서 document.getElementById("txtSignature").value = this.toDataURL(); 함수를 통해 id = txtSignature 인 객체에 데이터를 입력해준다.
    razor text 박스 <input type="text" @bind="ImageData" id="txtSignature" />
    하지만 바인딩된 ImageData변수에는 값이 들어가지 않는것을 확인할 수 있다. 3번째 이미지 참조.
    blazor에서는 js에서 호출된 함수이기때문에 변화를 감지하지 못하고 js 에서도 해당하는 id의 value값만 수정 하기 때문이다.
  2. js에서 DotNet.invokeMethodAsync("BlazorApp", "GetImageDataAsync", this.toDataURL()); 해당 함수를 호출 할때는 c#에서 생성한 메소드를 호출 함 으로 이미지 데이터를 정상적 으로 받을 수 있다.
  3. 결론은 c# 에서 js 함수 호출 및 js에서 c# 메소드 호출이 가능 하다!.

0개의 댓글