Created
September 1, 2018 11:02
-
-
Save adamczykm/2f7958a8feb5077d4f92a0bc21eb0512 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module Svg2PngPrintForm where | |
| import Control.Applicative (pure, when) | |
| import Control.Bind (bind, (=<<), (>>=)) | |
| import Control.Category ((<<<)) | |
| import Data.BooleanAlgebra ((||)) | |
| import Data.Eq ((/=)) | |
| import Data.Function (($)) | |
| import Data.Int (fromString) | |
| import Data.Maybe (Maybe(..), fromMaybe) | |
| import Data.Show (show) | |
| import Data.Unit (unit) | |
| import Effect.Aff (Aff, launchAff_) | |
| import Effect.Class (liftEffect) | |
| import React.Basic (Component, component) | |
| import React.Basic.DOM (button, div, input, text) | |
| import React.Basic.DOM.Events (targetValue) | |
| import React.Basic.Events (handler, handler_) | |
| import SvgBitmapUtils (PngSrcB64, Size, SvgSrcB64, downloadPng, meanReplaceBadPixelsB64, renderSvgToPngBase64) | |
| createPng ∷ SvgSrcB64 → SvgSrcB64 → Size → Aff PngSrcB64 | |
| createPng pmSvgSrc sceneSvgSrc size = do | |
| pmPng ← renderSvgToPngBase64 size pmSvgSrc | |
| scenePng ← renderSvgToPngBase64 size sceneSvgSrc | |
| meanReplaceBadPixelsB64 pmPng scenePng | |
| svg2PngPrintForm :: String → SvgSrcB64 → Size → Component { scene ∷ SvgSrcB64 } | |
| svg2PngPrintForm displayName pixelMapSrc initialSize = component | |
| { displayName | |
| , initialState | |
| , receiveProps | |
| , render | |
| } | |
| where | |
| initialState = | |
| { outputSize: initialSize | |
| , generateOutput: Nothing | |
| , cached: | |
| { outputSize: initialSize | |
| , scene: Nothing }} | |
| receiveProps {setState, props, state} = | |
| -- we need to compare against cached values to avoid state update - render loops | |
| when (state.cached.scene /= Just props.scene || state.cached.outputSize /= state.outputSize) | |
| -- update cache and png generating function | |
| let genOutputFun = createPng pixelMapSrc props.scene state.outputSize | |
| in setState (_ | |
| { cached = {outputSize: state.outputSize, scene: Just props.scene} | |
| , generateOutput = Just genOutputFun}) | |
| render {state, props, setState} = divc | |
| [ divc [text "width", renderWidthInput] | |
| , divc [text "height" , renderHeightInput] | |
| , downloadButton ] | |
| where | |
| divc children = div {children} | |
| downloadButton = button | |
| { onClick: handler_ $ case state.generateOutput of | |
| Nothing → pure unit | |
| Just genPng → launchAff_ (genPng >>= liftEffect <<< downloadPng "pattern.png") | |
| , children: [text "Download"]} | |
| renderHeightInput = input | |
| { type: "number" | |
| , step: "1" | |
| , value: show state.outputSize.height | |
| , onChange: handler targetValue (\v → setState (\s → s{outputSize = | |
| { height: (fromMaybe s.outputSize.height (fromString =<< v)) | |
| , width: s.outputSize.width}})) | |
| } | |
| renderWidthInput = input | |
| { type: "number" | |
| , step: "1" | |
| , value: show state.outputSize.width | |
| , onChange: handler targetValue (\v → setState (\s → s{outputSize = | |
| { width: (fromMaybe s.outputSize.width (fromString =<< v)) | |
| , height: s.outputSize.height}})) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment