KnockouJS foreach + SVG
HTML
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="4cm" height="4cm" viewBox="0 0 400 400">
<!--ko foreach:pathes -->
<pre data-bind="text: 'hi'" />
<!-- /ko -->
</svg>
CSS
path {
fill: none;
stroke:blue;
stroke-width:3;
}
CoffeeScript
class Shape
constructor:->
@transformArray = ko.observableArray()
@transform = ko.computed(()=>
(t.toString() for t in @transformArray()).join(" ")
, @)
class Rotate
constructor:(param)->
@angle = param.angle ? ko.observable(0)
@x = param.x ? ko.observable(0)
@y = param.y ? ko.observable(0)
toString:->
"rotate(#{ko.utils.unwrapObservable(@angle)},#{ko.utils.unwrapObservable(@x)},#{ko.utils.unwrapObservable(@y)})"
class Path extends Shape
constructor:()->
@d = ko.observableArray()
class LineTo
constructor:(param)->
@x = param.x ? ko.observable(0)
@y = param.y ? ko.observable(0)
@toString = ()->
"L #{ko.utils.unwrapObservable(@x)} #{ko.utils.unwrapObservable(@y)}"
class MoveTo
constructor:(param)->
@x = param.x ? ko.observable(0)
@y = param.y ? ko.observable(0)
@toString = ()->
"M #{ko.utils.unwrapObservable(@x)} #{ko.utils.unwrapObservable(@y)}"
ns = "http://www.w3.org/2000/svg"
ko.bindingHandlers.shape =
init:(element, valueAccessor, allBindingsAccessor, viewModel)->
e = document.createElementNS(ns, element.localName)
for a in element.attributes
e.setAttributeNS(ns, a.localName, a.nodeValue)
$(element).after(e)
$(element).remove()
for k, v of valueAccessor()
value = ko.utils.unwrapObservable(v)
if $.isArray(value)
$(e).attr(k, (m.toString() for m in value).join(" "))
else
$(e).attr(k, value)
,
update:(element, valueAccessor, allBindingsAccessor, viewModel)->
for k in valueAccessor()
element[k] = valueAccessor()[k]
class SVGViewModel
constructor:()->
@pathes = ko.observableArray()
model = new SVGViewModel()
path = new Path()
path.d.push(new MoveTo(
x:...