This is part two of the Floating Bubbles. See the previous post, if you haven't already.
My focus was to add interactivity to the SVG elements from the previous post. I decided to have the bubbles float towards the top on clicking. First of all, it is simple to add scripting to your SVG. SVG has an element called script, just like the XHTML. However, SVG will need to have unparsed character data. So, you will just need to wrap the inside of the <script> tag with the proper encoding:
<script type="text/ecmascript"><![CDATA[ ... ]]></script>
FYI: You can use text/javascript, as well. The only other thing is the script element must be inside the SVG tag. That is all you will need to know about the script element. The actual scripting will work the same as how you use it in HTML.
Since, I am setting this up with each element needing to run separately. We need to add an event to the <circle> tag in the for loop. I am going to use 'onclick' (Do not capitalize the C, like other languages), and I need to differentiate each circle so I am adding the 'id' attribute. <circle cx="<?php echo $x; ?>" cy="<?php echo $y; ?>" r="<?php echo $size; ?>" id="b<?php echo $i; ?>" onclick="startMoveUp(evt.target)" />. And, we will need to add a function to act on the event.
<script type="text/ecmascript"><![CDATA[ const SLOWEST_SPEED = 1; const TOP_SPEED = 25; const INCREMENTAL_SPEED = TOP_SPEED / (<?php echo HEIGHT; ?> / 2); const INTERVAL_SPEED = 40; var timer = new Array(); function startMoveUp(circle) { id = circle.getAttribute('id'); cy = parseInt(circle.getAttribute('cy')); r = parseInt(circle.getAttribute('r')) + <?php echo STROKE_SIZE; ?>; moveUp(id, r, (cy - r) / 2); } function moveUp(id, r, half) { circle = document.getElementById(id); cy = parseInt(circle.getAttribute("cy")); if (cy <= r) { clearTimeout(timer[id]); return; } else { cy -= r; } move = (half - Math.abs(cy - half)) * INCREMENTAL_SPEED; if (move < SLOWEST_SPEED) { move = SLOWEST_SPEED; } if (cy - move < 0) { move = cy; } circle.setAttribute("cy", cy + r - move); timer[id] = setTimeout("moveUp('"+id+"', "+r+", "+half+")", INTERVAL_SPEED); } ]]></script>
The script will move the circle towards the top of the SVG area at an increasing speed. However, once it reaches halfway up, it will start decreasing it's speed until it has reached the top. Here is the full code:
<?php header('Content-type: image/svg+xml'); define('WIDTH', 800); define('HEIGHT', 600); define('BUBBLES', 100); define('MIN_SIZE', 5); define('MAX_SIZE', 15); define('STROKE_SIZE', 1); echo '<?xml version="1.0" standalone="no"?>'; ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="<?php echo WIDTH; ?>" height="<?php echo HEIGHT; ?>" version="1.1" xmlns="http://www.w3.org/2000/svg"> <script type="text/ecmascript"><![CDATA[ const SLOWEST_SPEED = 1; const TOP_SPEED = 25; const INCREMENTAL_SPEED = TOP_SPEED / (<?php echo HEIGHT; ?> / 2); const INTERVAL_SPEED = 40; var timer = new Array(); function startMoveUp(circle) { id = circle.getAttribute('id'); cy = parseInt(circle.getAttribute('cy')); r = parseInt(circle.getAttribute('r')) + <?php echo STROKE_SIZE; ?>; moveUp(id, r, (cy - r) / 2); } function moveUp(id, r, half) { circle = document.getElementById(id); cy = parseInt(circle.getAttribute("cy")); if (cy <= r) { clearTimeout(timer[id]); return; } else { cy -= r; } move = (half - Math.abs(cy - half)) * INCREMENTAL_SPEED; if (move < SLOWEST_SPEED) { move = SLOWEST_SPEED; } if (cy - move < 0) { move = cy; } circle.setAttribute("cy", cy + r - move); timer[id] = setTimeout("moveUp('"+id+"', "+r+", "+half+")", INTERVAL_SPEED); } ]]></script> <g style="fill-opacity:0;stroke:rgb(0,0,0);stroke-width:<?php echo STROKE_SIZE; ?>;"> <?php for ($i = 0; $i < BUBBLES; $i++) { $size = rand(MIN_SIZE, MAX_SIZE); $x = rand($size + STROKE_SIZE, WIDTH - $size - (STROKE_SIZE * 2)); $y = rand($size + STROKE_SIZE, HEIGHT - $size - (STROKE_SIZE * 2)); ?> <circle cx="<?php echo $x; ?>" cy="<?php echo $y; ?>" r="<?php echo $size; ?>" id="b<?php echo $i; ?>" onclick="startMoveUp(evt.target)" /> <?php } ?> </g> </svg>
This was a fun project that only used SVG minimally, but showcases how easy you can make your graphics in SVG interactive. If you are playing around with the script, you can always change 'onclick' to 'onload'. This will have all the bubbles float to the top on the load of the page. However, it could bog down your browser, if you are using a lot of bubbles.
Comments
Post new comment