Есть ли способ прочитать цвет определенной точки холста?Haskell Threepenny Gui: Чтение цвета с холста в определенном месте?
Что-то вроде:
getColor :: Canvas -> Point -> Color
Я проверил документацию на Graphics.UI.Threepenny.Canvas, но не смог найти какую-либо функцию для этого. Может быть, я просто этого не видел, потому что я не так долго использовал Haskell.
Если у вас есть какие-либо намеки на меня, пожалуйста, дайте мне знать.
спасибо заранее, Клем
EDIT: Благодаря ответ Генрих Apfelmus' Я был в состоянии написать рабочее решение и хотел поделиться в случае, если кто-то нуждается в ту же функцию. Конечно, если вы используете его и внести изменения, не стесняйтесь поделиться ею :)
неimport qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core
import Codec.Picture.Types
-- to UI (PixelRGB8) is also possible just change from fst to snd after the return
getCanvCol :: UI.Canvas -> UI.Point -> UI (UI.Color)
getCanvCol canvas (x,y) = do
-- str returns a string with comma separated values i.e. "255,0,255"
str <- callFunction $ ffi ("(%1.getContext('2d').getImageData(%2,%3,1,1).data[0])+\
\\",\"+(%1.getContext('2d').getImageData(%2,%3,1,1).data[1])+\
\\",\"+(%1.getContext('2d').getImageData(%2,%3,1,1).data[2])")
canvas x y
return $ fst $ tripleToCol $ lsToRGB $ wordsWhen (==',') str
where
-- could also use splitOn
wordsWhen :: (Char -> Bool) -> String -> [String]
wordsWhen p s = case dropWhile p s of
"" -> []
s' -> w : wordsWhen p s''
where (w, s'') = break p s'
-- take a list of strings and make a triple of ints
lsToRGB :: [String] -> (Int,Int,Int)
lsToRGB (a:b:c:xs) = (read a, read b, read c)
lsToRGB _ = (0,0,0)
-- make a triple of Int to Color needed
tripleToCol :: (Int,Int,Int) -> (UI.Color, PixelRGB8)
tripleToCol (r,g,b) = ((UI.RGB r g b),(PixelRGB8 r' g' b'))
where (r',g',b') = (fromIntegral r,fromIntegral g,fromIntegral b)
Большое спасибо за быстрый ответ! Мне удалось заставить его работать (см. EDIT в сообщении выше). Хотя это может быть и не идеально, сейчас это достаточно хорошо для меня :) 3penny-gui действительно потрясающе, спасибо за это. –
Мое удовольствие. :-) Если вы чувствуете себя странно, вы также можете попробовать «Value» в качестве возвращаемого типа для маршала, это объект объекта JavaScript из библиотеки 'aeson'; Я думаю, что у модулей Graphics.UI.Threepenny.Event есть примеры для этого. Но поскольку ваш код работает, его не нужно менять. –