By msandersen
Sunday, 30. March 2008, 18:15:36
Possible to modify SVG patterns in Javascript?
I'm experimenting with SVGs produced with Inkscape and adding some Javascript. While I can manipulate an object successfully, I'd like to be able to alter patterns, eg the rotation or scale, not just the object. But it seems like it's not possible, or I don't know how. I don't know of a good reference for Javascript methods in SVG. W3C documentation is not easy.Here's what I've been experimenting with:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:tb="http://www.treebuilder.de/extensions/slider"
xmlns:xlink="http://www.w3.org/1999/xlink" onload="init()" >
<defs>
<!-- 30% black screen (24lpi round dot) -->
<pattern id="30pc_screen_round_black"
patternUnits="userSpaceOnUse"
width="90"
height="90"
patternTransform="translate(1.5,1.5) scale(0.06,0.06)">
<!-- Width 39.4. Scaled down to 24 lpi screen -->
<circle style="fill:black;stroke:none;" cx="19.7" cy="19.7" r="19.7"/>
<circle style="fill:black;stroke:none;" cx="64.7" cy="64.7" r="19.7"/>
</pattern>
<pattern id="30pcscreen2"
xlink:href="#30pc_screen_round_black"
patternTransform="scale(0.2,0.2)" />
</defs>
<!-- <script xlink:href="gsc.js"/> -->
<script><![CDATA[
svgns="http://www.w3.org/2000/svg"
function scrollBar(x,y,w,h,func,id,min,max){
this.w=w
this.h=h
this.x=x
this.y=y
this.value=min
var g = document.createElementNS(svgns,"g")
var re = document.createElementNS(svgns,"rect")
var ci = document.createElementNS(svgns,"circle")
// Rectangle
re.setAttribute("x",x)
re.setAttribute("y",y)
re.setAttribute("width",w)
re.setAttribute("height",h)
// Circle slider
ci.setAttribute("cx",x + w/2)
ci.setAttribute("cy",y + w/2)
ci.setAttribute("r",w/2)
ci.setAttribute("fill","red")
var svg=this
this.ci=ci
g.appendChild(re)
g.appendChild(ci)
this.svg=g
this.startSlide= function(){
document.documentElement.addEventListener("mousemove",svg.slide,false)
document.documentElement.addEventListener("mouseup",svg.stopSlide,false)
}
this.stopSlide= function(){
document.documentElement.removeEventListener("mousemove",svg.slide,false)
document.documentElement.removeEventListener("mouseup",svg.stopSlide,false)
}
this.slide = function(evt){
try{var m=svg.ci.parentNode.getScreenCTM()
}catch(e){
var m=getScreenCTM(svg.ci.parentNode)}
var p=document.documentElement.createSVGPoint()
p.x=evt.clientX
p.y=evt.clientY
p=p.matrixTransform(m.inverse())
if(p.y <= (y + h - w/2) && p.y >= y + w/2){
svg.ci.setAttribute("cy",p.y)
ra=Math.floor((min + (p.y - y - w/2)*(max-min) / (h-w))*100)/100
func(ra,id)
svg.value=ra
}
}
this.setSlider=function (x){
if(min<max){
if(x<min){x=min}
if(x>max){x=max}
}else{
if(x>min){x=min}
if(x<max){x=max}
}
py=((x-min)*(h-w))/(max-min)+w/2+y
svg.ci.setAttribute("cy",py)
func(x,id)
svg.value=x
}
ci.addEventListener("mousedown",this.startSlide,false)
}// end scrollBar function
var trans = {
rotate: 0,
scale: 1
}
function change(val,id){
document.getElementById(id).firstChild.nodeValue=val
switch(id){
case "tx":
if (val!=0) val=val/100
document.getElementById("star").setAttribute("fill-opacity",val)
break;
case "tx2":
trans['rotate'] = val
// val=val/100
// document.getElementById("30pcscreen2").setAttribute("patternTransform","scale("+val+","+val+")")
document.getElementById("star").setAttribute("transform","rotate("+val+") scale("+trans['scale']+")")
break;
case "tx3":
trans['scale'] = val
document.getElementById("star").setAttribute("transform","rotate("+trans['rotate']+") scale("+val+")")
}
}
function init(){
sl=new scrollBar(50,25,16,100,change,"tx",0,100)
document.getElementById("ip").appendChild(sl.svg)
sl2=new scrollBar(100,25,16,150,change,"tx2",0,360)
document.getElementById("ip").appendChild(sl2.svg)
sl3=new scrollBar(150,25,16,200,change,"tx3",0.2,6)
document.getElementById("ip").appendChild(sl3.svg)
}
function test(){
sl.setSlider(sl.value-10)
}
]]></script>
<g id="ip" transform="rotate(15) translate(50 50)">
<text x="180" y="50">Opacity</text><text id="tx" x="240" y="50">x</text>
<text x="180" y="80">Rotate</text><text id="tx2" x="240" y="80">x</text>
<text x="180" y="110">Scale</text><text id="tx3" x="240" y="110">x</text>
</g>
<rect x="0" y="0" width="10" height="10" onclick="test()"/>
<g id="layer1" transform="translate(800 300)">
<path id="star"
style="fill:url(#30pcscreen2);stroke:#000560;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;overflow:visible;"
d="M 58.588852,80.595437 L -0.70965691,41.901601 L -59.450025,81.437595 L -40.974248,13.084309 L -96.726985,-30.563807 L -26.009817,-34.114626 L -1.7265354,-100.62664 L 23.503301,-34.46788 L 94.263931,-31.926449 L 39.13966,12.512732 L 58.588852,80.595437 z" />
</g>
</svg>