packages feed

css-easings (empty) → 0.2.0.0

raw patch · 6 files changed

+476/−0 lines, 6 filesdep +QuickCheckdep +aesondep +basesetup-changed

Dependencies added: QuickCheck, aeson, base, blaze-markup, data-default, scientific, shakespeare, text

Files

+ CHANGELOG.md view
@@ -0,0 +1,11 @@+# `css-easings` Changelog++For a full list of changes, see the history on [GitHub](https://github.com/hapytex/css-easings).++## Version 0.2.0.0++Version ready to deploy on Hackage.++## Version 0.1.0.0++Working version.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Willem Van Onsem (c) 2020++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Willem Van Onsem nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,82 @@+# css-easings++[![Build Status of the package by Travis](https://travis-ci.com/hapytex/css-easings.svg?branch=master)](https://travis-ci.com/hapytex/css-easings)+[![Build Status of the package by Hackage](https://matrix.hackage.haskell.org/api/v2/packages/css-easings/badge)](https://matrix.hackage.haskell.org/#/package/css-easings)+[![Hackage version badge](https://img.shields.io/hackage/v/css-easings.svg)](https://hackage.haskell.org/package/css-easings)++A package that can be used to render CSS easing functions. One can use the+`Easing` type to specify how the "speed" of a certain animation should be+handled in time.++This package can be used in other items, such as objects that are then converted+to JSON to make it more safe, since it narrows the amount of possible css+strings to valid CSS easing functions.++The package documentation can be found on the [GitHub pages](https://hapytex.github.io/css-easings/).++## Easing structure++There are two types of CSS easings:++ 1. A `steps(n, jump-term)` with *n* the number of steps, and *jump-term* the type of jump; and+ 2. A `quadratic-bezier(x1, y1, x2, y2)`+    that works with a quaratic Bezier curve. Here both `x1` and `x2` need to between 0 and 1.++The type that we use for easings in this package is `Easing`.++There are four types of jumps: `jump-start`, `jump-end`, `jump-none`, and+`jump-both`. `start` and `end` are aliasses for `jump-start` and `jump-end`+respectively. The type we use in this package for these is `JumpTerm`.++Besides that, CSS has some aliasses for common easing types like `steps-start`,+`steps-end`, `ease`, `linear`, `ease-in`, `ease-out`, and `ease-in-out`.++PostCSS defines extra aliases like:++ 1. `easeInSine`, `easeOutSine`, and `easeInOutSine`;+ 2. `easeInQuad`, `easeOutQuad`, and `easeInOutQuad`;+ 3. `easeInCubic`, `easeOutCubic`, and `easeInOutCubic`;+ 4. `easeInQuant`, `easeOutQuant`, and `easeInOutQuant`;+ 5. `easeInQuint`, `easeOutQuint`, and `easeInOutQuint`;+ 6. `easeInExpo`, `easeOutExpo`, and `easeInOutExpo`;+ 7. `easeInCirc`, `easeOutCirc`, and `easeInOutCirc`; and+ 8. `easeInBack`, `easeOutBack`, and `easeInOutBack`.++These are also included as patterns in this project. When these are rendered,+for example as a JSON string, it will use the CSS equivalent.++## `ToMarkup`, `ToJSON`, and `ToJavascript` instances++Both the `JumpTerm` and `Easing` type are members of the `ToMarkup`, `ToJSON`+and `ToJavascript` type classes to convert the easings to their text equivalent.++For the `ToMarkup`, the CSS counterparts are just written to the markup stream,+and thus *not* wrapped in a string literal. Since the possible easings do not+contain any characters that need to be escaped, there is no problem with+escaping.++For both `ToJavascript` and `ToJSON` instances, the values are wrapped in a JSON+string, since in many Javascript libraries, one uses strings to update easings.++## `Arbitrary` css easings++One can generate arbitrary `Easing`s and `JumpTerm`s. It is however not advisable to+use this for anything other than for validation purposes (like with `QuickCheck`).++## `css-easings` is not *safe* Haskell++There are not extensions that are used that make the library *itself*+unsafe, but it makes use of `aeson`, `blaze-markup`, etc. and the packages are+not safe. Hence this package is not *safe Haskell*.++## Contribute++You can contribute by making a pull request on the [*GitHub+repository*](https://github.com/hapytex/css-easings).++You can contact the package maintainer by sending a mail to+[`hapytexeu+gh@gmail.com`](mailto:hapytexeu+gh@gmail.com).++---++This package is dedicated to *Nordin Allaert* (2001-2020), the son of a colleague. His life went in an `ease-in` manner, but was taken too soon.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ css-easings.cabal view
@@ -0,0 +1,37 @@+name:                css-easings+version:             0.2.0.0+synopsis:            Defining and manipulating css easing strings.+description:+  A package to define css easing strings. These can be used in Julius,+  JSON, etc. templates to limit the easings to valid ones.+homepage:            https://github.com/hapytex/css-easings#readme+license:             BSD3+license-file:        LICENSE+author:              Willem Van Onsem+maintainer:          hapytexeu@gmail.com+copyright:           2019 Willem Van Onsem+category:            webdevelopment+build-type:          Simple+extra-source-files:+    README.md+  , CHANGELOG.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:+        Css.Easing+  build-depends:+      base >=4.7 && <5+    , aeson >=1.0 && <2+    , blaze-markup >=0.8 && <0.9+    , data-default >=0.7 && <0.8+    , QuickCheck >=2.13 && <2.14+    , scientific >=0.3 && <0.4+    , shakespeare >=2.0 && <3.0+    , text >=1.1 && <1.3+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/hapytex/css-easings
+ src/Css/Easing.hs view
@@ -0,0 +1,314 @@+{-# LANGUAGE OverloadedStrings, PatternSynonyms #-}++{-|+Module      : Css.Easing+Description : Css easing strings in Haskell.+Maintainer  : hapytexeu+gh@gmail.com+Stability   : experimental+Portability : POSIX++A module to define css easing strings. These can be used in Julius, JSON, etc. templates to limit the easings to valid ones.+-}++module Css.Easing (+    -- * Easing patterns+      Easing(Steps, CubicBezier)+    , steps, steps'+    , cubicBezier, cubicBezier'+    -- * Convert to css+    , easingToCss, easingToCssWithCssAliasses, jumpTermToCss+    -- * Jump terms+    , JumpTerm(JumpStart, JumpEnd, JumpNone, JumpBoth)+    , pattern Start, pattern End+    -- * Standard easing aliasses+    , pattern StepsStart, pattern StepsEnd+    , pattern Ease, pattern Linear, pattern EaseIn, pattern EaseOut, pattern EaseInOut+    -- * PostCSS easing aliasses+    , pattern EaseInSine, pattern EaseOutSine, pattern EaseInOutSine+    , pattern EaseInQuad, pattern EaseOutQuad, pattern EaseInOutQuad+    , pattern EaseInCubic, pattern EaseOutCubic, pattern EaseInOutCubic+    , pattern EaseInQuart, pattern EaseOutQuart, pattern EaseInOutQuart+    , pattern EaseInQuint, pattern EaseOutQuint, pattern EaseInOutQuint+    , pattern EaseInExpo, pattern EaseOutExpo, pattern EaseInOutExpo+    , pattern EaseInCirc, pattern EaseOutCirc, pattern EaseInOutCirc+    , pattern EaseInBack, pattern EaseOutBack, pattern EaseInOutBack+  ) where++import Data.Aeson(Value(String), ToJSON(toJSON))+import Data.Default(Default(def))+import Data.Scientific(Scientific, scientific)+import Data.Text(Text, intercalate, pack)++import Text.Blaze(ToMarkup(toMarkup), text)+import Text.Julius(ToJavascript(toJavascript))++import Test.QuickCheck(Gen, choose, oneof)+import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary), arbitraryBoundedEnum)++-- references:+--   https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function+--   https://easings.net/en++-- | A type that describes the different types of css-easings (also known as+-- "transition timing functions"). There are basically two modes: 'Steps' and+-- 'CubicBezier's.+data Easing+    = Steps Int JumpTerm+    -- ^ Displays the transition along n stops along the transition, displaying each stop for+    -- equal lengths of time. For example, if n is 5,  there are 5 steps. Whether the transition+    -- holds temporarily at 0%, 20%, 40%, 60% and 80%, on the 20%, 40%, 60%, 80% and 100%, or+    -- makes 5 stops between the 0% and 100% along the transition, or makes 5 stops including+    -- the 0% and 100% marks (on the 0%, 25%, 50%, 75%, and 100%) depends on which of the+    -- 'JumpTerm' is used.+    | CubicBezier Scientific Scientific Scientific Scientific+    -- ^ An author defined cubic-Bezier curve, where the p1 and p3 values must+    -- be in the range of 0 to 1.+    deriving (Eq, Ord, Show)++-- | Convert an 'Easing' to its css counterpart. The css aliases like+-- @"steps-start"@ are /not/ checked. Therefore, only strings like "@steps(..)"+-- and @cubic-bezier(..)@ are returned.+easingToCss :: Easing -- ^ The given 'Easing' to convert.+    -> Text -- ^ The css counterpart of the given 'Easing'.+easingToCss (Steps n j) = "steps(" <> pack (show n) <> ", " <> jumpTermToCss j <> ")"+easingToCss (CubicBezier p1 p2 p3 p4) = "cubic-bezier(" <> intercalate ", " (map (pack . show) [p1, p2, p3, p4]) <> ")"++-- | Convert an 'Easing' to its css counterpart. The css aliases like+-- @"steps-start"@ are checked, and if they match, the alias is returned.+easingToCssWithCssAliasses :: Easing -- ^ The given 'Easing' to convert.+    -> Text  -- ^ The css counterpart of the given 'Easing'.+easingToCssWithCssAliasses StepsStart = "steps-start"+easingToCssWithCssAliasses StepsEnd = "steps-end"+easingToCssWithCssAliasses Linear = "linear"+easingToCssWithCssAliasses Ease = "ease"+easingToCssWithCssAliasses EaseIn = "ease-in"+easingToCssWithCssAliasses EaseInOut = "ease-in-out"+easingToCssWithCssAliasses EaseOut = "ease-out"+easingToCssWithCssAliasses e = easingToCss e++-- | A type that is used to describe how the jumps are done in a 'Steps'+-- construction.+data JumpTerm+    = JumpStart -- ^ In css this is denoted as @jump-start@. This denotes a left-continuous function, so that the first jump happens when the transition begins.+    | JumpEnd -- ^ In css this is denoted as @jump-end@. Denotes a right-continuous function, so that the last jump happens when the animation ends.+    | JumpNone -- ^ In css this is denoted as @jump-none@. There is no jump on either end. Instead, holding at both the 0% mark and the 100% mark, each for 1/n of the duration.+    | JumpBoth -- ^ In css this is denoted as @jump-both@. Includes pauses at both the 0% and 100% marks, effectively adding a step during the transition time.+    deriving (Bounded, Enum, Eq, Ord, Read, Show)++-- | Convert a 'JumpTerm' to its css counterpart. So 'JumpStart' is for example+-- converted to @"jump-start"@.+jumpTermToCss :: JumpTerm -- ^ The 'JumpTerm' to convert.+    -> Text -- ^ The css counterpart of the given 'JumpTerm'.+jumpTermToCss JumpStart = "jump-start"+jumpTermToCss JumpEnd = "jump-end"+jumpTermToCss JumpNone = "jump-none"+jumpTermToCss JumpBoth = "jump-both"++_validPoint :: Scientific -> Bool+_validPoint x = 0.0 <= x && x <= 1.0++-- | Constructs a 'CubicBezier' given that the first and third value are between @0.0@+-- and @1.0@. If that is the case, it returns a 'Just' that wraps the 'Easing'.+-- Otherwise 'Nothing' is returned.+cubicBezier :: Scientific -> Scientific -> Scientific -> Scientific -> Maybe Easing+cubicBezier p1 p2 p3+    | _validPoint p1 && _validPoint p2 = Just . CubicBezier p1 p2 p3+    | otherwise = const Nothing++-- | Constructs a 'CubicBezier' given the first and third value are between @0.0@+-- and @1.0@. If this is the case, it returns that 'Easing', otherwise it will+-- raise an error.+cubicBezier' :: Scientific -> Scientific -> Scientific -> Scientific -> Easing+cubicBezier' p1 p2 p3+    | _validPoint p1 && _validPoint p3 = CubicBezier p1 p2 p3+    | otherwise = error "The first and third value needs to be between 0 and 1."++-- | Constructs a 'Steps' given the first item is strictly greater than zero. If+-- that is the case, it returns the 'Easing' wrapped in a 'Just', otherwise a+-- 'Nothing' is returned.+steps :: Int -> JumpTerm -> Maybe Easing+steps n | n > 0 = Just . Steps n+        | otherwise = const Nothing++-- | Construct a 'Steps' given the first item is strictly greater than ero. If+-- that is the case, it returns the 'Easing' object, otherwise it will raise an+-- error.+steps' :: Int -> JumpTerm -> Easing+steps' n | n > 0 = Steps n+         | otherwise = error "The number of steps should be larger than 0."++-- | A pattern that defines the css alias @start@ that is equal to @jump-start@.+pattern Start :: JumpTerm+pattern Start = JumpStart++-- | A pattern that defines the css alias @end@ that is equal to @jump-end@.+pattern End :: JumpTerm+pattern End = JumpEnd++-- | A pattern that defines the css alias @steps-start@ that is equal to @steps(1, jump-start)@.+pattern StepsStart :: Easing+pattern StepsStart = Steps 1 JumpStart++-- | A pattern that defines the css alias @steps-end@ that is equal to @steps(1, jump-end)@.+pattern StepsEnd :: Easing+pattern StepsEnd = Steps 1 JumpEnd++-- | A pattern that defines the css alias @ease@ that is equal to @cubic-bezier(0.25, 0.1, 0.25, 1)@.+pattern Ease :: Easing+pattern Ease = CubicBezier 0.25 0.1 0.25 1++-- | A pattern that defines the css alias @linear@ that is equal to @cubic-bezier(0, 0, 1, 1)@.+pattern Linear :: Easing+pattern Linear = CubicBezier 0 0 1 1++-- | A pattern that defines the css alias @ease-in@ that is equal to @cubic-bezier(0.42, 0, 1, 1)@.+pattern EaseIn :: Easing+pattern EaseIn = CubicBezier 0.42 0 1 1++-- | A pattern that defines the css alias @ease-out@ that is equal to @cubic-bezier(0, 0, 0.58, 1)@.+pattern EaseOut :: Easing+pattern EaseOut = CubicBezier 0 0 0.58 1++-- | A pattern that defines the css alias @ease-in-out@ that is equal to @cubic-bezier(0.42, 0, 0.58, 1)@.+pattern EaseInOut :: Easing+pattern EaseInOut = CubicBezier 0.42 0 0.58 1++instance Default Easing where+    def = Ease++instance Default JumpTerm where+    def = JumpNone++-- PostCSS+-- | A pattern that defines the PostCSS easing pattern @easeInSine@.+pattern EaseInSine :: Easing+pattern EaseInSine = CubicBezier 0.12 0 0.39 0++-- | A pattern that defines the PostCSS easing pattern @easeOutSine@.+pattern EaseOutSine :: Easing+pattern EaseOutSine = CubicBezier 0.61 1 0.88 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutSine@.+pattern EaseInOutSine :: Easing+pattern EaseInOutSine = CubicBezier 0.37 0 0.63 1++-- | A pattern that defines the PostCSS easing pattern @easeInQuad@.+pattern EaseInQuad :: Easing+pattern EaseInQuad = CubicBezier 0.11 0 0.5 0++-- | A pattern that defines the PostCSS easing pattern @easeOutQuad@.+pattern EaseOutQuad :: Easing+pattern EaseOutQuad = CubicBezier 0.5 1 0.89 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutQuad@.+pattern EaseInOutQuad :: Easing+pattern EaseInOutQuad = CubicBezier 0.45 0 0.55 1++-- | A pattern that defines the PostCSS easing pattern @easeInCubic@.+pattern EaseInCubic :: Easing+pattern EaseInCubic = CubicBezier 0.32 0 0.67 0++-- | A pattern that defines the PostCSS easing pattern @easeOutCubic@.+pattern EaseOutCubic :: Easing+pattern EaseOutCubic = CubicBezier 0.33 1 0.68 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutCubic@.+pattern EaseInOutCubic :: Easing+pattern EaseInOutCubic = CubicBezier 0.65 0 0.35 1++-- | A pattern that defines the PostCSS easing pattern @easeInQuart@.+pattern EaseInQuart :: Easing+pattern EaseInQuart = CubicBezier 0.5 0 0.75 0++-- | A pattern that defines the PostCSS easing pattern @easeOutQuart@.+pattern EaseOutQuart :: Easing+pattern EaseOutQuart = CubicBezier 0.25 1 0.5 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutQuart@.+pattern EaseInOutQuart :: Easing+pattern EaseInOutQuart = CubicBezier 0.76 0 0.24 1++-- | A pattern that defines the PostCSS easing pattern @easeInQuint@.+pattern EaseInQuint :: Easing+pattern EaseInQuint = CubicBezier 0.64 0 0.78 0++-- | A pattern that defines the PostCSS easing pattern @easeOutQuint@.+pattern EaseOutQuint :: Easing+pattern EaseOutQuint = CubicBezier 0.22 1 0.36 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutQuint@.+pattern EaseInOutQuint :: Easing+pattern EaseInOutQuint = CubicBezier 0.83 0 0.17 1++-- | A pattern that defines the PostCSS easing pattern @easeInExpo@.+pattern EaseInExpo :: Easing+pattern EaseInExpo = CubicBezier 0.7 0 0.84 0++-- | A pattern that defines the PostCSS easing pattern @easeOutExpo@.+pattern EaseOutExpo :: Easing+pattern EaseOutExpo = CubicBezier 0.16 1 0.3 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutExpo@.+pattern EaseInOutExpo :: Easing+pattern EaseInOutExpo = CubicBezier 0.87 0 0.13 1++-- | A pattern that defines the PostCSS easing pattern @easeInCirc@.+pattern EaseInCirc :: Easing+pattern EaseInCirc = CubicBezier 0.55 0 1 0.45++-- | A pattern that defines the PostCSS easing pattern @easeOutCirc@.+pattern EaseOutCirc :: Easing+pattern EaseOutCirc = CubicBezier 0 0.55 0.45 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutCirc@.+pattern EaseInOutCirc :: Easing+pattern EaseInOutCirc = CubicBezier 0.85 0 0.15 1++-- | A pattern that defines the PostCSS easing pattern @easeInBack@.+pattern EaseInBack :: Easing+pattern EaseInBack = CubicBezier 0.36 0 0.66 (-0.56)++-- | A pattern that defines the PostCSS easing pattern @easeOutBack@.+pattern EaseOutBack :: Easing+pattern EaseOutBack = CubicBezier 0.34 1.56 0.64 1++-- | A pattern that defines the PostCSS easing pattern @easeInOutBack@.+pattern EaseInOutBack :: Easing+pattern EaseInOutBack = CubicBezier 0.68 (-0.6) 0.32 1.6++_genS :: Gen Scientific+_genS = scientific <$> arbitrary <*> arbitrary++_genBoundedS :: Gen Scientific+_genBoundedS = do+    e <- fmap abs arbitrary+    (`scientific` (-e)) <$> choose (0, 10^e)+++-- Arbitrary instances+instance Arbitrary Easing where+    arbitrary = oneof [Steps <$> choose (0, maxBound) <*> arbitrary, CubicBezier <$> _genBoundedS <*> _genS <*> _genBoundedS <*> _genS]++instance Arbitrary JumpTerm where+    arbitrary = arbitraryBoundedEnum++-- ToMarkup instances+instance ToMarkup Easing where+    toMarkup = text . easingToCssWithCssAliasses++instance ToMarkup JumpTerm where+    toMarkup = text . jumpTermToCss++-- ToJavascript instances+instance ToJavascript Easing where+    toJavascript = toJavascript . easingToCssWithCssAliasses++instance ToJavascript JumpTerm where+    toJavascript = toJavascript . jumpTermToCss++-- ToJSON instances+instance ToJSON Easing where+    toJSON = String . easingToCssWithCssAliasses++instance ToJSON JumpTerm where+    toJSON = String . jumpTermToCss