Last active
March 7, 2016 04:17
-
-
Save alandipert/17101e8fc9b5d0fcf2aa to your computer and use it in GitHub Desktop.
Hoplon dataflow positioning example http://tailrecursion.com/~alan/tmp/css5000/
This file contains 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
(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