README.md
March 7, 2020 ยท View on GitHub
Quamolit: a tiny animation library
Demo(check browser compatibility first) http://repo.tiye.me/Quamolit/quamolit/
Features:
- declarative component markups for Canvas
- animation abstractions
- persistent data by default with ClojureScript
Still prototype... Quamolit requires
ctx.addHitRegion(opts), which is an experimental technology.
Design
Quamolit is trying to combine two things:
- declarative programming experience like React
- pixels manipulating and animations in HTML5 Canvas

Usage
[quamolit "0.1.6"]
Browser docs/ for a little more details.
You may require Quamolit with higher level APIs:
(quamolit.core/render-page store states-ref target)
(quamolit.core/configure-canvas target)
(quamolit.core/setup-events target dispatch)
(ns quamolit.main
(:require [quamolit.core :refer [render-page
configure-canvas
setup-events]]
[quamolit.util.time :refer [get-tick]]
[quamolit.updater.core :refer [updater-fn]]
[devtools.core :as devtools]))
(defonce store-ref (atom []))
(defonce states-ref (atom {}))
(defonce loop-ref (atom nil))
(defn dispatch [op op-data]
(let [new-tick (get-tick)
new-store (updater-fn @store-ref op op-data new-tick)]
(reset! store-ref new-store)))
(defn render-loop []
(let [target (.querySelector js/document "#app")]
(render-page @store-ref states-ref target)
(reset! loop-ref (js/requestAnimationFrame render-loop))))
(defn -main []
(let [target (.querySelector js/document "#app")]
(configure-canvas target)
(setup-events target dispatch)
(render-loop)))
(set! js/window.onload -main)
(set! js/window.onresize configure-canvas)
(defn on-jsload []
(js/cancelAnimationFrame @loop-ref)
(js/requestAnimationFrame render-loop)
(.log js/console "code updated..."))
Also you may use lower level APIs directly by copy/paste this Gist:
(defn init-state [arg1 arg2])
(defn update-state [old-state state-arg1 state-arg2])
(defn init-instant [args state at-place?])
(defn on-tick [instant tick elapsed])
(defn on-update [instant old-args args old-state state])
(defn on-unmount [instant tick])
(defn remove? [instant])
(defn render [arg1 arg2]
(fn [state mutate instant tick]))
(create-comp :demo render)
(create-comp :demo init-state update-state render)
(create-comp :demo init-instant on-tick on-update on-mount remove? render)
(create-comp :demo init-state update-state init-instant on-tick on-update on-mount remove? render)
(mutate state-arg1 state-arg2)
(dispatch op op-data)
(defn updater-fn [old-store op op-data op-id])
(quamolit.util.iterate/iterate-instant instant :x :x-velovity elapsed [lower-bound upper-bound])
(quamolit.util.iterate/tween [40 60] [0 1000] 800)
Component Specs
Shape records:
namekeywordpropsa hashmap of:-
stylea hashmap of styles used in Canvas API
-
eventa hashmap of events, mainly:clickevents
-
attrsa hashmap
childrensorted hashmap with values of child nodes
Component record:
namekeywordcoorda vector of numbers(maybe also keywords and strings)argsprops of components are passed in a list, not hashmapstateany type frominit-stateinstantany type frominit-instant, mainly hashmapsinit-statefunction to initilize component stateupdate-statefunction to transform component stateinit-instantfunction to initilize component animation stateon-tickfunction to update animation state at every tickon-updatefunction to update animation state on every store or states changeon-unmountfunction to update animation state when component removed(not destroyed yet)remove?function to detect if component totally removed(or destroyed)renderfunction to rendertreecached from render treefading?boolean, whether component unmounted(waiting to be destroyed)
Paint Elements
(line {:style {
:x0 0 :y0 0 :x1 40 :y1 40
:line-width 4
:stroke-style (hsl 200 870 50)
:line-cap "round"
:line-join "round"
:milter-limit 8
}})
(arc {:style {
:x 0 :y 0:r 40
:s-angle 0
:e-angle 60
:line-width 4
:counterclockwise true
:line-cap "round"
:line-join "round"
:miter-limit 8
:fill-style nil
:stroke-style nil
}})
(rect {:style {
:w 100 :h 40
:x (- (/ w 2)) :y (- (/ h 2))
:line-width 2
}})
(text {:style {
:x 0
:y 0
:fill-style (hsl 0 0 0)
:text-align "center"
:base-linee "middle"
:size 20
:font-family "Optima"
:max-width 400
:text ""
}})
(image {:style {
:src "lotus.jpg"
:sx 0
:sy 0
:sw 40
:sh 40
:dx 0
:dy 0
:dw 40
:dh 40
}})
Paint Components
(translate {:style {:x 0 :y 0}})
(scale {:style {:ratio 1.2}})
(alpha {:style {:opacity 0.5}})
(rotate {:style {:angle 30}})
(button {:style {
:x 0 :y 0
:w 100 :h 40 :text "button"
:surface-color (hsl 0 80 80) :text-color (hsl 0 0 10)
:font-family "Optima"
:font-size 20}})
(input {:style {:w 0 :h 0 :text ""}})
(comp-debug data {})
Develop
To run this project:
yarn
yarn html
yarn watch # localhost:7000
License
MIT