Трипенни GUI - Использование раковины с холстом - PullRequest
3 голосов
/ 08 января 2020

Я учусь использовать Threepenny GUI, я подключился к потоку событий щелчка с холста, сопоставил этот поток событий с потоком Point и применил accumB к [] и тому Event Point, чтобы получить Behaviour [Point]

, где Point:

data Point = Point {
  x :: Int,
  y :: Int
}

и код для сопоставления потока клика Event с Behaviour [Point]:

let pointStream = uncurry Point <$> UI.mousedown canvas

let pointsStream = fmap (:) pointStream

let pointsAccumB = accumB [] pointsStream

pointsBehaviour <- pointsAccumB

Затем я хотел бы нарисовать эти точки в элементе холста, который я добавил в тело HTML в методе setup.

Мне удалось нарисовать точки из поведение выглядит так:

on UI.click drawButton $ const $ do
  UI.clearCanvas canvas

  points <- currentValue pointsBehaviour

  -- Draw the points here

Но проблема в том, что я хотел бы, чтобы точки рисовались на холсте каждый раз, когда пользователь нажимает на холст, не требуя от пользователя go и нажатия кнопки. , Или, другими словами, я хотел бы объединить функцию рисования точек в потоке точек.

Из моего исследования видно, что sink может быть функцией, которую мне нужно использовать для t ie вместе поведение и мутация пользовательского интерфейса в стиле FRP.

Но я изо всех сил пытаюсь понять, как собрать это воедино (то есть, как будет выглядеть приложение sink для данного варианта использования?). Возможно ли вообще сделать это с Threepenny в настоящее время?

1 Ответ

1 голос
/ 09 января 2020

Оберните свой код рисования точек в WriteAttr и передайте его sink. Атрибут может быть определен следующим образом:

drawnPoints :: WriteAttr Canvas [Point]
drawnPoints = mkWriteAttr $ \canvas point -> do
  UI.clearCanvas canvas
  -- Draw the points here

Затем вы можете соединить ваши фактические точки и холст, используя sink:

element canvas # sink drawnPoints pointsBehaviour
...