JavaScript - SVG - Programmed Animation

Animated from Math

Example 35.5. Animated Drawing, the Page svg/svg98.html
<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>svg</title>
        <style>
            svg {
                border: 1px solid blue;
                margin: 0;
                padding: 0;
                width: 300px;
                height: 200px;
            }
        </style>
        <script type='module'>
            'use strict';
            import {$, parabola} from './svg98.js';
            window.addEventListener('load', function () {
                parabola($('s0'), 1, -300, 0, 400);
                parabola($('s1'), 1, -300, 20000, 200);
            });
        </script>
    </head>
    <body>
        <div>
        <svg xmlns='http://www.w3.org/2000/svg'>
                  <!-- M move to, in casu start drawing coord
                       Q quadratic bezier, first coord is control point
                                           second is end drwaing coord -->
                  <path d='M0,0 Q150,53.33 300,0'
                        fill='none' stroke='fuchsia' stroke-width='2'/>
                  <circle cx='150' cy='53.33' r='2' fill='black'/>
        </svg>
        </div>
        <div>
            <svg id='s0' xmlns='http://www.w3.org/2000/svg'>
                <!-- y = x(x-300) -->
            </svg>
        </div>
        <div>
            <svg id='s1' xmlns='http://www.w3.org/2000/svg'>
                <!-- y = (x-100)(x-200) -->
            </svg>
        </div>
    </body>
</html>

Demo this.


Example 35.6. Animated Drawing, the JavaScript svg/svg98.js
export const $ = function(foo) {
    return document.getElementById(foo);
}
/*
 * params:
 * where designates DOM placement
 * a, b, c as in y = -(a*x*x + b*x + c)
 * scaled scales depth relative to viewbox, higher is shallower
 */
export const parabola = function (where, a, b, c, scaled) {
    let xmlns = "http://www.w3.org/2000/svg";
    let vertexx = Math.abs(b) / (2 * a);
    let vertexy = Math.abs(a) * vertexx * vertexx + Math.abs(b) * vertexx + c;
    let cpy = -(a * vertexx * vertexx + b * vertexx + c) / scaled * 2;
    let x = 0;
    let timer = setInterval(function () {
        let ci = document.createElementNS(xmlns, 'circle');
        ci.setAttributeNS(null, 'cx', x);
        let y = (-(a * x * x + b * x + c) / scaled);
        ci.setAttributeNS(null, 'cy', y);
        ci.setAttributeNS(null, 'r', 1);
        ci.setAttributeNS(null, 'fill', 'fuchsia');
        where.appendChild(ci);
        x++;
        if(x > Math.abs(b)) {
            let ci = document.createElementNS(xmlns, 'circle');
            ci.setAttributeNS(null, 'cx', vertexx);
            ci.setAttributeNS(null, 'cy', cpy);
            ci.setAttributeNS(null, 'r', 2);
            ci.setAttributeNS(null, 'fill', 'black');
            where.appendChild(ci);
            clearInterval(timer);
        }
    }, 10);
}

Animated Attributes

Example 35.7. Animate Attributes, the Page svg/svg97.html
<!doctype html>
<html>
    <!-- http://thenewcode.com/943/An-SVG-Analog-Clock-In-6-Lines-of-JavaScript -->
    <head>
        <meta charset='utf-8'/>
        <title>svg</title>
        <style>
            #clock {
                height: 200px;
                margin: auto;
            }
            #face {
                stroke-width: 2px; stroke: #fff;
            }
            #hour, #min, #sec {
                stroke-width: 1px; fill: #333; stroke: #555;
            }
            #sec { stroke: #f55; }
        </style>
        <script type='module'>
            'use strict';
            import {aclock} from './svg97.js';
            window.addEventListener('load', aclock);
        </script>
    </head>
    <body>
        <div id='svg0'>
            <svg id='clock' viewBox='0 0 100 100'>
                <circle id='face' cx='50' cy='50' r='45'/>
                <g id='hands'>
                    <rect id='hour'
                          x='47.5' y='12.5' width='5' height='40'
                          rx='2.5' ry='2.55'/>
                    <rect id='min'
                          x='48.5' y='10' width='3' height='42'
                          rx='2' ry='2'/>
                    <line id='sec'
                          x1='50' y1='55' x2='50' y2='7'/>
                </g>
                <circle cx='50' cy='50' r='1.5' fill='yellow'/>
            </svg>
        </div>
    </body>
</html>

Demo this.


Example 35.8. Animate Attributes, the JavaScript svg/svg97.js
export const aclock = function () {
    setInterval(function () {

        const rndr = function (elm, deg) {
            elm.setAttribute('transform', 'rotate('+ deg +' 50 50)');
        }

        var now = new Date();
        rndr(sec, 6 * now.getSeconds());  // 1/60*360
        rndr(min, 6 * now.getMinutes());  // 1/60*360
                                        // 1/12*360
        rndr(hour, 30 * (now.getHours() % 12) + now.getMinutes() / 2);
        // https://stackoverflow.com/questions/25931810/why-is-document-getelementbyid-not-needed#25931928
        // console.log(svg0 === document.getElementById('svg0'));
    }, 1000);
}

Animated Position

Example 35.9. Animate Position Attributes, the Page svg/svg55.html
<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>svg</title>
        <link rel='stylesheet' href='./svg55.css'/>
        <script type='module'>
            "use strict";
            import {anim} from './svg55.js';

            const go = function () {
                anim('svg', 20, 3, 'vb')
            }
            window.addEventListener('load', go);
        </script>
    </head>
    <body>
        <div id='vb'>
            <svg id='svg'><use href='#image0'/></svg>
        </div>
        <div>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                sed do eiusmod tempor incididunt ut labore et dolore
                magna aliqua. Ut enim ad minim veniam, quis nostrud
                exercitation ullamco laboris nisi ut aliquip ex ea
                commodo consequat. Duis aute irure dolor in
                reprehenderit in voluptate velit esse cillum dolore eu
                fugiat nulla pariatur. Excepteur sint occaecat cupidatat
                non proident, sunt in culpa qui officia deserunt mollit
                anim id est laborum.
            </p>
        </div>
        <svg xmlns="http://www.w3.org/2000/svg">
             <symbol id='image0'>
                 <circle cx="10" cy="10" r="10" fill="blue"/>
             </symbol>
        </svg>
    </body>
</html>

Demo this.


Example 35.10. Animate Position Attributes, the JavaScript svg/svg55.js
export const $ = function (foo) {return document.getElementById(foo);}


/*
 * animate svg, params:
 * svgelm: id of svg in html
 * widx: width of animated svg
 * wp: viewport (html elm) holding the svgelm
 */
export const anim = function (svgelm, widx, dx, wp) {
    let vb = window.getComputedStyle($(wp));
    let xmax = parseInt(vb.getPropertyValue('width'));

    let timer = setInterval(function () {
        let svg = window.getComputedStyle($(svgelm));
        let left = parseInt(svg.getPropertyValue('left'));
        if (left < 0 || left + widx > xmax)
            dx *= -1;
        $(svgelm).style.left  = left + dx + 'px';
    }, 10);

}