Skip to content

Instantly share code, notes, and snippets.

@alandipert
Last active March 7, 2016 04:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alandipert/17101e8fc9b5d0fcf2aa to your computer and use it in GitHub Desktop.
Save alandipert/17101e8fc9b5d0fcf2aa to your computer and use it in GitHub Desktop.
Hoplon dataflow positioning example http://tailrecursion.com/~alan/tmp/css5000/
(page "index.html"
(:require [tailrecursion.hoplon.reload :refer [reload-all]]
[inputs :refer [slider]])
(:refer-hoplon :exclude [center]))
(reload-all)
(defn px [x] (str (.floor js/Math x) "px"))
(defn xp [x] (int (.slice x 0 -2)))
(defelem manage* [{:keys [css] :as attrs} [child]]
(let [css-cell (cell= (merge css {:position "absolute"}))]
;; Here we box up a cell of an element's style attributes,
;; hiding it "in" the element using specify! + IMeta. Later,
;; we'll be able to create formulas of this element's style
;; attribute map by extracting this cell with the meta function.
((specify! child cljs.core/IMeta (-meta [_] css-cell)) :css css-cell)))
(defn managed
"Takes an element constructor function ctor and returns a managed instance."
[ctor]
(fn [& args] (apply manage* (concat args [(ctor)]))))
(defn center! [in elem]
(let [[in-cell elem-cell] (map meta [in elem])
elem-left (cell= (+ (- (/ (xp (:width in-cell)) 2)
(/ (xp (:width elem-cell)) 2))
(xp (:left in-cell))))]
(manage* :css (cell= (merge elem-cell {:left (px elem-left)})) elem)))
(defn bottom! [of elem]
(let [[of-cell elem-cell] (map meta [of elem])
elem-top (cell= (+ (- (xp (:height of-cell)) (xp (:height elem-cell)))
(xp (:top of-cell))))]
(manage* :css (cell= (merge elem-cell {:top (px elem-top)})) elem)))
(html
(head (link :rel "stylesheet" :type "text/css" :href "css/reset.css"))
(body
(let [size (cell 200)
large ((managed div) :css (cell= {:width (px size)
:height (px size)
:left (px (/ size 5))
:top (px 30)
:background-color "blue"}))
small ((managed div) :css (cell= {:width (px 50)
:height (px 50)
:background-color "black"}))]
(center! large small)
(bottom! large small)
(div
;; small appears centered on and flush with the bottom of
;; large, even when large changes position. Notice that small
;; is not a child of large; the presentation relationship was
;; established non-structurally using the center! and bottom!
;; functions.
large
small
(slider :to size)
(a :href "https://gist.github.com/alandipert/17101e8fc9b5d0fcf2aa" "Source")))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment