Animated SVG Background, from Javascript to Clojurescript

I was quite fond of the animated background I developed earlier, as I saw it as an oppertunity to distract myself from some personal matters (might write about those later, or not).
The goal was to Clojure-ify the code, and here is the first result:
(ns hemsida.svg.random-curves-bg
  (:require [hemsida.interop :as i :refer [get-element-by-id]]))

(def path-names (->> (range 1 7)
                     (map (fn [i] (str "svg-path-" i)))))

(defn randit [size half]
  (- (* (.random js/Math) size) half))

(defn q-point [size half]
  (str "q "
       (randit size half) " "
       (randit size half) " "
       (randit size half) " "
       (randit size half) " "))

(defn path [size half x y]
  (let [x1 (+ x (randit size half))
        y1 (+ y (randit size half))
        x2 (+ x1 (randit size half))
        y2 (+ y1 (randit size half))]
    (str "M " x1 " " y1 " "
         (q-point size half) " "
         (q-point size half) " "
         (q-point size half) " "
         (q-point size half) " "
         "Q " x1 " " y1 " " x2 " " y2 " Z")))

(defn create-animation [path]
  (let [animation (.createElementNS js/document "" "animate")
        duration (str (int (+ 5 (* (.random js/Math) 7))) "s")]
    (doto animation
      (.setAttributeNS nil "attributeName" "d")
      (.setAttributeNS nil "to" path)
      (.setAttributeNS nil "dur" duration)
      (.setAttributeNS nil "fill" "freeze"))

(defn animate-element [size half x y id]
  (let [svg (get-element-by-id id)
        path (path size half x y)
        animation (create-animation path)]
      (.appendChild svg animation)
      (.beginElement animation)
      (catch :default e
        ; IE and Edge are not that modern...
        (.setAttribute svg "d" path)))))

(defn animate-elements []
  (let [size (int (.max js/Math
                        (.-innerWidth js/window)
                        (.-innerHeight js/window)))
        an-fn (partial animate-element size (int (/ size 2)) 0 (.-pageYOffset js/window))]
    (doseq [name path-names]
      (an-fn name))))

(defn set-paths []
  (let [size (int (.max js/Math
                        (.-innerWidth js/window)
                        (.-innerHeight js/window)))
        half (int (/ size 2))
        y (.-pageYOffset js/window)]
    (doseq [name path-names]
      (-> (i/get-element-by-id name)
          (.setAttribute "d" (path size half 0 y))))))

(defn start! []
  (.setInterval js/window animate-elements 30000))
<svg id="svg">
    <path id="svg-path-1" d="" fill-opacity="0.10" fill="#993333"></path>
    <path id="svg-path-2" d="" fill-opacity="0.10" fill="#339933"></path>
    <path id="svg-path-3" d="" fill-opacity="0.10" fill="#333399"></path>
    <path id="svg-path-4" d="" fill-opacity="0.10" fill="#339999"></path>
    <path id="svg-path-5" d="" fill-opacity="0.10" fill="#993399"></path>
    <path id="svg-path-6" d="" fill-opacity="0.10" fill="#999933"></path>
Some obvious improvments are to not use id's to retrieve the separate paths, but instead iterate the children of the svg and apply updates on all.
One other is to inject the svg with code to the dom-tree instead of it residing in index.html.
I will probably do both in the future, but at least now there is less non-Clojurescript code on my homepage. ☺
2017-11-28Kenneth HedmanClojurescriptEnglishgraphicsprogrammingweb