Reputation: 45
I’ve got a flowery pattern (http://pages.bangor.ac.uk/~abp4d9/) where user moves sliders (for inner circles and petals) and flowers change. There are 2 big problems now that I can’t manage to sort out:
1) Flower petals get cut off. I’ve tried changing width and height of SVG, pattern itself, element. Tried changing x and y. Nothing makes any difference
2) I want to randomize pattern units. My 1st stop is circles. I want the pattern to stay the same apart from circles being of random different sizes. I’ve searched everywhere and now I’m not sure if this idea is even possible? I’ve got a button ready to use and a function for taking random number from an array. The pattern would look something like this picture (this one has got randomized petals)
Here is my HTML with SVG:
<body onload="refresh()">
<header>
<h1>Create your own pattern</h1>
</header>
<div class="controls">
<table>
<tr>
<td><p>Cicle size: </p></td>
<td><input id="slider1" type="range" min="5" max="28" onchange="refresh()"/></td>
<td><p> Random Circle size: </p></td>
<td><input id="randomCicle" type="button" value="Press here to activate" onClick="randomString();"></td>
</tr>
<tr>
<td><p>Length of petals: </p></td>
<td><input id="slider2" type="range" min="18" max="60" onchange="refreshPetals()"/></td>
</tr>
<tr>
<td><p>Width of petals: </p></td>
<td><input id="slider3" type="range" min="3" max="16" onchange="refreshWidth()"/></td>
</tr>
<tr>
</tr>
</table>
</div>
<div class="square">
<svg width="520" height="520">
<defs>
<pattern id="pattern" x="5" y="5" width="140" height="140"
patternUnits="userSpaceOnUse"
patternTransform="rotate(45)">
<path d="M 0 106 156 106" stroke="black" stroke-width="2" />
<g width="140" height="140">
<ellipse id="petal" cx=60 cy=40 rx=60 ry=10 stroke="black" stroke-width="2" fill="white"/>
<ellipse id="petal1" cx=60 cy=40 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(35, 60, 40)"/>
<ellipse id="petal2" cx=60 cy=40 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(70, 60, 40)"/>
<ellipse id="petal3" cx=60 cy=40 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(105, 60, 40)"/>
<ellipse id="petal4" cx=60 cy=40 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(140, 60, 40)"/>
</g>
<circle id="circleP" cx="60" cy="40" r="10" stroke="black" stroke-width="2" fill="white"/>
</pattern>
</defs>
<rect x="10" y="10" width="500" height="500" stroke="black" stroke-width="4" fill="url(#pattern)"/>
</svg>
</div>
And JS:
function refresh(){
var slider1 = parseInt(document.getElementById("slider1").value);
document.getElementById("circleP").setAttribute("r", slider1)
}
function refreshPetals(){
var slider2 = parseInt(document.getElementById("slider2").value);
document.getElementById("petal").setAttribute("rx", slider2)
document.getElementById("petal1").setAttribute("rx", slider2)
document.getElementById("petal2").setAttribute("rx", slider2)
document.getElementById("petal3").setAttribute("rx", slider2)
document.getElementById("petal4").setAttribute("rx", slider2)
}
function refreshWidth(){
var slider3 = parseInt(document.getElementById("slider3").value);
document.getElementById("petal").setAttribute("ry", slider3)
document.getElementById("petal1").setAttribute("ry", slider3)
document.getElementById("petal2").setAttribute("ry", slider3)
document.getElementById("petal3").setAttribute("ry", slider3)
document.getElementById("petal4").setAttribute("ry", slider3)
}
function test() {
var values = [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28];
var valueToUse = values[Math.floor(Math.random() * values.length)];
}
Upvotes: 1
Views: 871
Reputation: 24587
To answer the first part of your question: the petals are being cut off because you defined a pattern area of width 140 and height 140, but instead of placing the flower drawing in the middle of this area (x=70, y=70), you placed it at (x=60, y=40). As a result, the petals are going off the top of your pattern area.
I've fixed this for you here:
function refresh(){
var slider1 = parseInt(document.getElementById("slider1").value);
document.getElementById("circleP").setAttribute("r", slider1)
}
function refreshPetals(){
var slider2 = parseInt(document.getElementById("slider2").value);
document.getElementById("petal").setAttribute("rx", slider2)
document.getElementById("petal1").setAttribute("rx", slider2)
document.getElementById("petal2").setAttribute("rx", slider2)
document.getElementById("petal3").setAttribute("rx", slider2)
document.getElementById("petal4").setAttribute("rx", slider2)
}
function refreshWidth(){
var slider3 = parseInt(document.getElementById("slider3").value);
document.getElementById("petal").setAttribute("ry", slider3)
document.getElementById("petal1").setAttribute("ry", slider3)
document.getElementById("petal2").setAttribute("ry", slider3)
document.getElementById("petal3").setAttribute("ry", slider3)
document.getElementById("petal4").setAttribute("ry", slider3)
}
function test() {
var values = [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28];
var valueToUse = values[Math.floor(Math.random() * values.length)];
}
$(refresh);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<h1>Create your own pattern</h1>
</header>
<div class="controls">
<table>
<tr>
<td><p>Cicle size: </p></td>
<td><input id="slider1" type="range" min="5" max="28" onchange="refresh()"/></td>
<td><p> Random Circle size: </p></td>
<td><input id="randomCicle" type="button" value="Press here to activate" onClick="randomString();"></td>
</tr>
<tr>
<td><p>Length of petals: </p></td>
<td><input id="slider2" type="range" min="18" max="60" onchange="refreshPetals()"/></td>
</tr>
<tr>
<td><p>Width of petals: </p></td>
<td><input id="slider3" type="range" min="3" max="16" onchange="refreshWidth()"/></td>
</tr>
<tr>
</tr>
</table>
</div>
<div class="square">
<svg width="520" height="520">
<defs>
<pattern id="pattern" x="0" y="0" width="140" height="140"
patternUnits="userSpaceOnUse"
patternTransform="rotate(45)">
<path d="M0 139H140" stroke="black" stroke-width="2" />
<g width="140" height="140">
<ellipse id="petal" cx=70 cy=70 rx=60 ry=10 stroke="black" stroke-width="2" fill="white"/>
<ellipse id="petal1" cx=70 cy=70 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(36, 70, 70)"/>
<ellipse id="petal2" cx=70 cy=70 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(72, 70, 70)"/>
<ellipse id="petal3" cx=70 cy=70 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(108, 70, 70)"/>
<ellipse id="petal4" cx=70 cy=70 rx=60 ry=10 stroke="black" stroke-width="2" fill="white" transform="rotate(144, 70, 70)"/>
</g>
<circle id="circleP" cx="70" cy="70" r="10" stroke="black" stroke-width="2" fill="white"/>
</pattern>
</defs>
<rect x="10" y="10" width="500" height="500" stroke="black" stroke-width="4" fill="url(#pattern)"/>
</svg>
</div>
You can't randomize the flower sizes, however. The pattern will only render them at one size. If you want differently sized flowers, you may as well just draw them all individually instead of using an SVG pattern. This shouldn't be too hard to do with a bit of Javascript. Have a go, and post another question here if you run into difficulties.
Upvotes: 3