Dev.Opera - Follow the standards, break the rulesDev.Opera - Follow the standards, break the rules

Login

Lost password?

Forums » General Discussions

General DevOpera discussion group

Note: You need to login to post in the forums. if you don't have an account you first need to sign up.

By msandersen anchor Sunday, 30. March 2008, 18:15:36

avatar

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>

By msandersen anchor Tuesday, 1. April 2008, 15:29:26

avatarI managed to make the script work on the Pattern, but it only works properly in Opera. Firefox doesn't do Patterns yet (Firefox 3, probably), and Safari 3.1 isn't happy trying to scale the pattern.

Moderators: jax | malware | mcx | operadev