Elm에서 port나 네이티브 모듈을 사용하지 않고 JS와 통신하는 방법

6264 단어 어둠의 마술Elm


Elm에서 웹 브라우저의 API를 직접 두드리는 것은 공식 패키지뿐이며, 타사 패키지에서는 네이티브 모듈이나 port도 사용할 수 없습니다. 그렇지만, joaquin/elm canvas 라고 하는 패키지가 존재하고 있어 공식적으로 대응하고 있지 않을 것인 Canvas API를 두드리고 있는 것입니다. 어쩔 수 없어! 라고 생각해 조사했으므로, 어떤 방법으로 하고 있는지 간단하게 소개해 둡니다.

1. 외부로 보내고 싶은 데이터를 property 를 사용해 요소의 "cmds"라는 프로퍼티에 돌입


commands : Commands -> Attribute msg
commands list =
    list
        |> Encode.list identity
        |> property "cmds"

기존의 프로퍼티가 아니면 어떤 이름이라도 좋을 것입니다만, em-canvas에서는 "cmds"라고 하는 프로퍼티에 돌진하고 있는 것 같습니다. 그건 그렇고,이 데이터의 내용은 다음과 같은 느낌의 JSON이되었습니다.
[
    {type: "function", name: "restore", args: []},
    {type: "function", name: "fill", args: ["nonzero"]},
    {type: "field", name: "fillStyle", value: "rgba(0%,0%,0%,0.3)"},
    ...

2. elm-canvas라는 Custom Elements 그리기


toHtml : ( Int, Int ) -> List (Attribute msg) -> List Renderable -> Html msg
toHtml ( w, h ) attrs entities =
    Html.node "elm-canvas"
        [ commands (render entities) ]
        [ canvas (height h :: width w :: attrs) []
        ]

1에서 정의한 commands를 사용하여 elm-canvascmds 속성에 데이터를 넣습니다. 그런 다음 그 안쪽에 실제 그리기 대상이되는 canvas 요소도 만들고 있습니다.

3. 그 Custom Elements의 정의의 set 액세서로, Elm측으로부터 보내진 데이터를 받는다


customElements.define(
  "elm-canvas",
  class extends HTMLElement {

    ...

    set cmds(values) {
      this.commands = values;
      this.render();
    }

    ...

  }
);

JavaScript 측의 elm-canvas 요소의 정의로, cmdsset 액세서를 준비해, 거기에서 데이터를 받습니다. 그리고는 받은 데이터를 바탕으로 Canvas를 그릴 뿐입니다.

요약



그래서 Custom Elements의 속성을 넘어 데이터를 보내면 elm-canvas.js 라는 스크립트를 따로 읽을 필요는 있지만, 네이티브 모듈도 port도 사용하지 않고 Elm 패키지에서 외부 API를 두드릴 수 있다고 한다. 일을 알았습니다. 이 방법에서는 JavaScript 측에서 Elm 측으로 데이터를 보낼 수 없기 때문에 measureText 와 같은 기능은 실현할 수 없다는 제한은 있겠지만, 간단한 묘화라면 이것으로 충분할 것입니다.

……어둠의 마술잖아!

추가



… … port 총 무시로 데이터를 보낼 수 있습니다! 악의 추축! 

좋은 웹페이지 즐겨찾기