Использование HTML Canvas из ReasonML с использованием React Hooks - PullRequest
0 голосов
/ 04 ноября 2019

Я ищу быстрый пример того, как начать использовать следующие технологии вместе:

Чтобы начать, мне нужен фрагмент кода, который отлично подойдет для следующего:

  • Элегантно и правильно управляет ссылкой на элемент HTML5 Canvas
  • Является простым компонентом реакции
  • Очищает холст и что-то рисует

У меня уже есть базовый ReasonMLРеагировать на настройку проекта.

1 Ответ

0 голосов
/ 04 ноября 2019

Вот пример, который показывает один способ собрать все вместе:


// Helper type to pass canvas size
type dimensions = {
  width: float,
  height: float,
};

// Actual drawing happens here, canvas context and size as parameters.
let drawOnCanvas =
    (context: Webapi.Canvas.Canvas2d.t, dimensions: dimensions): unit => {
  open Webapi.Canvas.Canvas2d;
  clearRect(context, ~x=0., ~y=0., ~w=dimensions.width, ~h=dimensions.height);

  setFillStyle(context, String, "rgba(0,128,169,0.1)");
  fillRect(context, ~x=10.0, ~y=10.0, ~w=30.0, ~h=30.0);
};

// Extract canvas dimensions from canvas element
let canvasDimensions = (canvasElement: Dom.element): dimensions =>
  Webapi.Canvas.CanvasElement.{
    width: float_of_int(width(canvasElement)),
    height: float_of_int(height(canvasElement)),
  };

// An adapter to give nicer parameters to drawOnCanvas above
let drawOnCanvasElement = (canvasElement: Dom.element): unit =>
  Webapi.Canvas.CanvasElement.(
    drawOnCanvas(
      getContext2d(canvasElement),
      canvasDimensions(canvasElement),
    )
  );

[@react.component]
let make = () => {
  open React;
  let canvasElementRef: Ref.t(option(Dom.element)) = useRef(None);

  useLayoutEffect0(() => {
    Ref.current(canvasElementRef)
    |> Belt.Option.map(_, drawOnCanvasElement)
    |> ignore;
    None;
  });

  <canvas
    width="200"
    height="100"
    ref={ReactDOMRe.Ref.callbackDomRef(elem =>
      React.Ref.setCurrent(canvasElementRef, Js.Nullable.toOption(elem))
    )}
  />;
};

Вот несколько случайных ссылок, которые я использовал, когда узнал, как это сделать. (Добавляя их сюда, если они полезны и для других.):

Код содержит чуть больше объявлений типов, чем необходимо, и некоторые операторы open могут быть добавлены, но мне нравятся мои ответы на многословной стороне для большей поучительности.

Сократить код должно быть относительно легко.

Промежуточные функции canvasDimensions и drawOnCanvasElement, на мой взгляд, добавляют немного структуры к коду, но я не уверен, что онисделайте образец более или менее понятным для читателей или если будет более элегантный способ работы с размером холста.

...