Created
May 28, 2015 01:31
-
-
Save nvbn/581ff6a88a805bd2a7ab to your computer and use it in GitHub Desktop.
svg animation
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
(ns ^:figwheel-always svg-image-example.core | |
(:require-macros [cljs.core.async.macros :refer [go-loop]]) | |
(:require [cljs.core.async :refer [<! timeout]] | |
[om.core :as om :include-macros true] | |
[om-tools.core :refer-macros [defcomponent]] | |
[om-tools.dom :as dom])) | |
(enable-console-print!) | |
(defcomponent rotated-rect-rect | |
[{:keys [x y width height]} owner] | |
(init-state [_] {:angle 0}) | |
(will-mount [_] | |
(go-loop [] | |
(om/update-state! owner :angle #(-> % inc (mod 360))) | |
(<! (timeout 10)) | |
(recur))) | |
(render-state [_ {:keys [angle]}] | |
(let [center-x (+ x (/ width 2)) | |
center-y (+ y (/ height 2))] | |
(dom/rect {:width width | |
:height height | |
:fill "red" | |
:transform (str "rotate(" angle ", " center-x ", " center-y ")") | |
:x x | |
:y y})))) | |
(defcomponent scene-1 | |
[_ _] | |
(render [_] | |
(dom/svg {:width "100%" :height "100%"} | |
(om/build rotated-rect-rect {:x 50 | |
:y 50 | |
:width 100 | |
:height 100})))) | |
(defcomponent scene-2 | |
[_ owner] | |
(init-state [_] {:x 0}) | |
(will-mount [_] | |
(go-loop [] | |
(om/update-state! owner :x #(-> % inc (mod 600))) | |
(<! (timeout 10)) | |
(recur))) | |
(render-state [_ {:keys [x]}] | |
(dom/svg {:width "100%" :height "100%"} | |
(om/build rotated-rect-rect {:x x | |
:y 50 | |
:width 100 | |
:height 100})))) | |
(defcomponent sprite | |
[{:keys [x y img-width img-height scale sprite-x sprite-y sprite-w sprite-h href]} _] | |
(render-state [_ _] | |
(let [id (gensym)] | |
(dom/g (dom/defs {:dangerouslySetInnerHTML {:__html (str " | |
<pattern id='" id "' | |
patternUnits='userSpaceOnUse' | |
x='" x "' | |
y='" y "' | |
width='" sprite-w "' | |
height='" sprite-h "'> | |
<image x='" (- 0 sprite-x) "' | |
y='" (- 0 sprite-y) "' | |
xlink:href='" href "' | |
width='" img-width "' | |
height='" img-height "' | |
transform='scale(" scale ")' /> | |
</pattern>")}}) | |
(dom/rect {:x x :y y :width sprite-w :height sprite-h | |
:fill (str "url(#" id ")")}))))) | |
(defcomponent scene-3 | |
[_ _] | |
(render [_] | |
(dom/svg {:width "100%" :height "100%"} | |
(om/build sprite {:img-width 406 | |
:img-height 1507 | |
:scale 2 | |
:sprite-w 40 | |
:sprite-h 80 | |
:href "mario.png" | |
:sprite-x 214 | |
:sprite-y 240})))) | |
(defn mario-sprite | |
[& opts] | |
(om/build sprite (assoc (apply hash-map opts) | |
:img-width 406 | |
:img-height 1507 | |
:scale 2 | |
:sprite-w 40 | |
:sprite-h 80 | |
:href "mario.png"))) | |
(def sprites | |
{:right {:run [328 320] | |
:run-1 [354 320] | |
:run-2 [378 320] | |
:jump [335 240] | |
:stand [214 240]} | |
:left {:run [60 320] | |
:run-1 [34 320] | |
:run-2 [8 320] | |
:jump [54 240] | |
:stand [174 240]}}) | |
(defcomponent mario | |
[{:keys [x y]} owner] | |
(init-state [_] {:state :stand | |
:direction :left}) | |
(will-mount [_] | |
(go-loop [] | |
(let [state (om/get-props owner :state) | |
direction (om/get-props owner :direction) | |
drawing-state (om/get-state owner :state) | |
drawing-direction (om/get-state owner :direction) | |
next-state (if (and (= direction drawing-direction) (= state :run)) | |
(condp = drawing-state | |
:run :run-1 | |
:run-1 :run-2 | |
:run) | |
state)] | |
(om/set-state! owner :state next-state) | |
(om/set-state! owner :direction direction)) | |
(<! (timeout 100)) | |
(recur))) | |
(render-state [_ {:keys [state direction]}] | |
(let [[sx sy] (get-in sprites [direction state])] | |
(mario-sprite :x x | |
:y y | |
:sprite-x sx | |
:sprite-y sy)))) | |
(defcomponent scene-4 | |
[_ _] | |
(render [_] | |
(dom/svg {:width "100%" :height "100%"} | |
(om/build mario {:x 10 :y 10 :state :stand :direction :right}) | |
(om/build mario {:x 60 :y 10 :state :run :direction :right}) | |
(om/build mario {:x 110 :y 10 :state :jump :direction :right}) | |
(om/build mario {:x 10 :y 100 :state :stand :direction :left}) | |
(om/build mario {:x 60 :y 100 :state :run :direction :left}) | |
(om/build mario {:x 110 :y 100 :state :jump :direction :left})))) | |
(defcomponent scene-5 | |
[_ owner] | |
(init-state [_] {:mario-state :stand | |
:mario-x 20 | |
:mario-y 10 | |
:mario-direction :right}) | |
(will-mount [_] | |
(go-loop [] | |
; Stand a half | |
(om/set-state! owner :mario-state :stand) | |
(<! (timeout 500)) | |
; Jump | |
(om/set-state! owner :mario-state :jump) | |
(dotimes [_ 20] | |
(<! (timeout 5)) | |
(om/update-state! owner :mario-y dec)) | |
(dotimes [_ 20] | |
(<! (timeout 5)) | |
(om/update-state! owner :mario-y inc)) | |
; Stand a half | |
(om/set-state! owner :mario-state :stand) | |
(<! (timeout 500)) | |
; Go right | |
(om/set-state! owner :mario-state :run) | |
(dotimes [_ 300] | |
(<! (timeout 5)) | |
(om/update-state! owner :mario-x inc)) | |
; Stand a second | |
(om/set-state! owner :mario-state :stand) | |
(<! (timeout 500)) | |
(om/set-state! owner :mario-direction :left) | |
(<! (timeout 500)) | |
; Jump | |
(om/set-state! owner :mario-state :jump) | |
(dotimes [_ 20] | |
(<! (timeout 5)) | |
(om/update-state! owner :mario-y dec)) | |
(dotimes [_ 20] | |
(<! (timeout 5)) | |
(om/update-state! owner :mario-y inc)) | |
;Stand a half | |
(om/set-state! owner :mario-state :stand) | |
(<! (timeout 500)) | |
; Go back | |
(om/set-state! owner :mario-state :run) | |
(dotimes [_ 300] | |
(<! (timeout 5)) | |
(om/update-state! owner :mario-x dec)) | |
; Stand a half | |
(om/set-state! owner :mario-direction :right) | |
(<! (timeout 500)) | |
(recur))) | |
(render-state [_ {:keys [mario-state mario-direction mario-x mario-y]}] | |
(dom/svg {:width "100%" :height "100%"} | |
(om/build mario {:x mario-x | |
:y mario-y | |
:state mario-state | |
:direction mario-direction}) | |
(dom/rect {:fill "green" | |
:x 0 | |
:y 70 | |
:width 400 | |
:height 20})))) | |
(defn ^:export main | |
[n] | |
(let [scene (nth [scene-1 scene-2 scene-3 scene-4 scene-5] (dec n))] | |
(om/root scene {} {:target (.getElementById js/document "main")}))) |
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
<html> | |
<body> | |
<div id="main"></div> | |
<script src="result.js"></script> | |
<script> | |
var scene = parseInt(location.hash[1], 10); | |
if (scene) svg_image_example.core.main(scene); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment