开发者

SVG in Clojurescript

开发者 https://www.devze.com 2023-04-11 03:36 出处:网络
What\'s the best way to add SVG elements to the dom in Clojurescript ? The Twitterbuzz example uses Google Closure lib\'s Graphics objects, but say I didn\'t care about IE compatibility, is there a wa

What's the best way to add SVG elements to the dom in Clojurescript ? The Twitterbuzz example uses Google Closure lib's Graphics objects, but say I didn't care about IE compatibility, is there a way I could add elements the way html is (dom/build [:svg [:g [:text "something like this ?"]]]) I tried Closure's graphics lib but I don't get to use a lot of handy SVG features. I tried Apogee, but that serializes the SVG code and I would prefer direct DO开发者_开发问答M manipulation.


dom/build constructs DOM elements without the namespace. You need to either enhance dom/build or write one for SVG. I use the following code to create SVG elements.

(defn element-ns
  "Create a namespaced dom element"
  [namespace tag & args]
  (let [[tag attrs children] (normalize-args tag args)
        parent (. js/document createElementNS namespace (name tag))
        [parent children] (if (string? (first children))
                            [(set-text (element-ns namespace tag attrs) (first children))
                             (rest children)]
                            [parent children])]
    (doseq [[k v] attrs]
      (. parent setAttributeNS nil (name k) v))
    (apply append parent children)))

(defn build-svg
  "Build up a svg element from nested vectors."
  [x]
  (if (vector? x)
    (let [[parent children] (if (keyword? (first x))
                          [(apply element-ns "http://www.w3.org/2000/svg" (take-while element-arg? x))
                           (drop-while element-arg? x)]
                          [(first x) (rest x)])
       children (map build-svg children)]
       (apply append parent children))
    x))


You might be interested in my cljs-d3 library, which is a ClojureScript wrapper for the D3 JavaScript library. D3 is an excellent tool for manipulating an SVG DOM.


What about using Enlive for SVG? This is what I plan to use for several real time projects.


If you want to load svg as an external asset try loading it as text and appending it to a div leveraging cljs-d3:

(defn load-svg-as-text []
 (fn []
   (let [on-complete (fn [error externalSVGText]
    (-> d3
     (.select "#viewport")
     (.html externalSVGText))
    )]
  (-> d3
    (.text "images/smartcity.svg" on-complete)))))

I got the idea from AmeliaBR nice answer in this js thread and then ported it to ClojureScript

0

精彩评论

暂无评论...
验证码 换一张
取 消