The code from the Devcards introduction video
(ns hello-there.core | |
(:require | |
[devcards.core :as dc :include-macros true] | |
[sablono.core :as sab :include-macros true] | |
[om.core :as om :include-macros true]) | |
(:require-macros | |
[devcards.core :refer [defcard is are= are-not=]]) | |
) | |
(devcards.core/start-devcard-ui!) | |
(devcards.core/start-figwheel-reloader!) | |
(defn my-hello [nm] | |
(sab/html [:div | |
[:h1 "Well hello there, " nm "!!!"]])) | |
(defn pixel-pos [x] | |
(str (+ 15 (* x (+ 106 15))) "px")) | |
(defn pos-translate [top left] | |
(str "translate3d(" (pixel-pos left) "," | |
(pixel-pos top) ", 0px)")) | |
(defn board-cell [{:keys [top left id v highlight reveal]}] | |
(let [trans (pos-translate top left)] | |
(sab/html | |
[:div.cell-pos { :style { "-webkit-transform" trans | |
"-moz-transform" trans | |
"transform" trans } | |
:key (str (name id)) } | |
[:div { :class (str "cell cell-num-" v " highlight") } v]]))) | |
(defcard inspect-board-cell | |
(dc/sab-card | |
[:div {:style {:height 120 | |
:position "relative"}} | |
(board-cell {:id :t5 :top 0 :left 0 :v 1024})])) | |
(defn background-cells [] | |
(for [top (range 4) left (range 4)] | |
(sab/html | |
[:div.cell-pos.cell-empty | |
{ :style { :top (pixel-pos top) | |
:left (pixel-pos left)}}]))) | |
(defcard inspect-background-cells | |
(dc/sab-card | |
[:div {:style {:height 500 | |
:position "relative"}} | |
(background-cells)])) | |
(defn game-board [data] | |
(sab/html | |
[:div.board-area | |
[:div.background (background-cells)] | |
[:div.cells (map board-cell data)]])) | |
(defcard board-style | |
(dc/sab-card (game-board []))) | |
(defcard board-with-cells | |
(dc/sab-card | |
(game-board [{ :top 0 :left 0 :v 2 :id :t1} | |
{ :top 0 :left 1 :v 4 :id :t2} | |
{ :top 0 :left 2 :v 8 :id :t3} | |
{ :top 0 :left 3 :v 16 :id :t4} | |
{ :top 1 :left 0 :v 32 :id :t5} | |
{ :top 1 :left 1 :v 64 :id :t6} | |
{ :top 1 :left 2 :v 128 :id :t7} | |
{ :top 1 :left 3 :v 256 :id :t8} | |
{ :top 2 :left 0 :v 512 :id :t9} | |
{ :top 2 :left 1 :v 1024 :id :t10} | |
{ :top 2 :left 2 :v 2048 :id :t11}]))) | |
(defcard data-structure-ex | |
(dc/markdown-card | |
"# 2048 Data Structures | |
### Main data structure: a map | |
A map of tiles indexed by their ids. These | |
tiles hold positions, values, and ids." | |
(dc/mkdn-data | |
{:t1 { :top 0 :left 0 :v 2 :id :t1} | |
:t2 { :top 1 :left 0 :v 2 :id :t2} | |
:t3 { :top 2 :left 0 :v 8 :id :t3} | |
:t4 { :top 3 :left 0 :v 4 :id :t4}} | |
) | |
"### Vector based positional view | |
Where positions are converted into actual positions in a 2d array. | |
This view of the data will facilitate making the left, right, up | |
and down moves." | |
(dc/mkdn-data | |
[[{:v 2, :id :t1} :_ :_ :_] | |
[{:v 8, :id :t2} :_ :_ :_] | |
[{:v 4, :id :t3} :_ :_ :_] | |
[{:v 4, :id :t4} :_ :_ :_]]))) | |
(def blank-board [[:_ :_ :_ :_] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_]]) | |
(defn map-view->board-view [map-view] | |
(reduce | |
(fn [accum {:keys [top left] :as tile}] | |
(assoc-in accum [top left] (dissoc tile :top :left))) | |
blank-board | |
(vals map-view))) | |
(defn board-view->map-view [board-view] | |
(into {} | |
(map (juxt :id identity) | |
(keep identity | |
(for [top (range 4) left (range 4)] | |
(let [res (get-in board-view [top left])] | |
(when (map? res) | |
(assoc res :top top :left left)))))))) | |
(defcard map-to-board-view-tests | |
(dc/test-card | |
"## Testing data view conversions" | |
(are= (map-view->board-view {:t1 {:id :t1 :top 0 :left 0 :v 4}}) | |
[[{:id :t1 :v 4} :_ :_ :_] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_]]) | |
(are= (board-view->map-view [[{:id :t1 :v 4} :_ :_ :_] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_]]) | |
{:t1 {:id :t1 :top 0 :left 0 :v 4}}) | |
(are= (map-view->board-view | |
(board-view->map-view [[{:id :t1 :v 4} :_ :_ :_] | |
[:_ :_ :_ {:id :t2 :v 4}] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_]])) | |
[[{:id :t1 :v 4} :_ :_ :_] | |
[:_ :_ :_ {:id :t2 :v 4}] | |
[:_ :_ :_ :_] | |
[:_ :_ :_ :_]]) | |
)) | |
(def fibs | |
(map first (iterate (fn [[a b]] [b, (+ a b)]) [0, 1]))) | |
(def fib (partial nth fibs)) | |
(defn counter-app [data-atom] | |
(sab/html | |
[:div | |
[:h1 "Fibonacci Counter " (str (fib (:count @data-atom)))] | |
[:div [:a {:onClick #(swap! data-atom update-in [:count] inc)} "inc"]] | |
(dc/edn->html @data-atom) | |
])) | |
(defcard inspect-counter | |
(dc/react-runner-card | |
counter-app | |
{:initial-state {:count 0}})) | |
(defn om-counter [data owner] | |
(reify | |
om/IRenderState | |
(render-state [_ {:keys [count]}] | |
(sab/html | |
[:div | |
[:h1 "Fibonacci counter " (str (fib (:count data)))] | |
[:div [:a {:onClick #(om/transact! data :count inc)} "inc"]] | |
(dc/edn->html data)])))) | |
(defcard om-root-example | |
(dc/om-root-card om-counter {:count 0})) |
.two-zero.board-area { | |
background-color: rgb(187,173,160); | |
width: 499px; | |
height: 499px; | |
border-radius: 6px; | |
position: relative; | |
/* initialize as 3d */ | |
-webkit-transform: translate3d(0,0,0); | |
-moz-transform: translate3d(0,0,0); | |
transform: translate3d(0,0,0); | |
} | |
.board-area-one-row { | |
height: 136px; | |
} | |
.one-row-board .board-area { | |
height: 136px; | |
overflow: hidden; | |
} | |
.cell-pos { | |
height: 106px; | |
width: 106px; | |
position:absolute; | |
border-radius: 4px; | |
-webkit-transition: all 0.12s; | |
transition: all 0.12s; | |
/* initialize as 3d */ | |
-webkit-transform: translate3d(0,0,0); | |
-moz-transform: translate3d(0,0,0); | |
transform: translate3d(0,0,0); | |
} | |
.cell-empty { | |
background-color: rgb(205,193,180); | |
} | |
.cell { | |
background-color: rgb(205,193,180); | |
height: 106px; | |
width: 106px; | |
/* position: relative; */ | |
border-radius: 4px; | |
font-family: "Helvetica Neue", Arial, sans-serif; | |
font-size: 55px; | |
line-height: 102px; | |
font-weight: bold; | |
text-align: center; | |
vertical-align: middle; | |
/* initialize as 3d */ | |
-webkit-transform: translate3d(0,0,0); | |
-moz-transform: translate3d(0,0,0); | |
transform: translate3d(0,0,0); | |
} | |
.cell.highlight { | |
-webkit-animation: highlight 0.1s; | |
} | |
@-webkit-keyframes highlight { | |
0% { -webkit-transform: scale3d(1.2,1.2,1.0); | |
opacity: 0.7;} | |
100% { -webkit-transform: scale3d(1.0,1.0,1.0); | |
opacity: 1.0;} | |
} | |
.cell.reveal { | |
-webkit-animation: reveal 0.1s; | |
} | |
@-webkit-keyframes reveal { | |
0% { -webkit-transform: scale3d(0.1,0.1,1.0); | |
opacity: 0.1; | |
} | |
100% { -webkit-transform: scale3d(1.0,1.0,1.0); | |
opacity: 1.0;} | |
} | |
.cell-num-2 { | |
background-color: rgb(238, 228,218); | |
color: rgb(110,102,93); | |
} | |
.cell-num-4 { | |
background-color: rgb(237, 224,200); | |
color: rgb(119,110,101); | |
} | |
.cell-num-8 { | |
background-color: rgb(242, 177, 121); | |
color: rgb(249,246,242); | |
} | |
.cell-num-16 { | |
background-color: rgb(245, 149, 99); | |
color: rgb(249,246,242); | |
} | |
.cell-num-32 { | |
background-color: rgb(245, 124, 95); | |
color: rgb(249,246,242); | |
} | |
.cell-num-64 { | |
background-color: rgb(246, 94, 59); | |
color: rgb(249,246,242); | |
} | |
.cell-num-128 { | |
background-color: rgb(237, 207,114); | |
color: rgb(249,246,242); | |
font-size: 48px; | |
} | |
.cell-num-256 { | |
background-color: rgb(237, 204, 97); | |
color: rgb(249,246,242); | |
font-size: 48px; | |
border: 1px solid rgba(238, 228, 218, 0.5); | |
box-shadow: 0 0 25px 5px rgb(237, 204, 97); | |
} | |
.cell-num-512 { | |
background-color: rgb(237, 204, 97); | |
color: rgb(249,246,242); | |
font-size: 48px; | |
border: 1px solid rgba(238, 228, 218, 0.5); | |
box-shadow: 0 0 25px 5px rgb(237, 204, 97); | |
} | |
.cell-num-1024 { | |
background-color: rgb(237, 204, 97); | |
color: rgb(249,246,242); | |
font-size: 40px; | |
border: 1px solid rgba(238, 228, 218, 0.5); | |
box-shadow: 0 0 25px 5px rgb(237, 204, 97); | |
} | |
.cell-num-2048 { | |
background-color: rgb(237, 204, 97); | |
color: rgb(249,246,242); | |
font-size: 40px; | |
border: 1px solid rgba(238, 228, 218, 0.5); | |
box-shadow: 0 0 25px 5px rgb(237, 204, 97); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment