Click here to Skip to main content
15,886,026 members
Articles / Web Development / HTML5

HTML5, JavaScript, Knockout, JQuery, Guide for Recovering Silverlight/WPF/C# Addicts. Part 2 - Solar System Animation built with SVG, Knockout and MVVM Pattern.

Rate me:
Please Sign up or sign in to vote.
4.98/5 (32 votes)
26 Sep 2012CPOL16 min read 80.3K   1.4K   70  
Creating Solar System animation in HTML5/JavaScript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Solar System</title>
</head>
<body style="background-color:black;">

<!-- top panel containing "toggleAnimation" button and selected solar system body information -->
<div style="position:fixed">

    <!-- button to stop and restart the animation -->
    <button id="toggleAnimationButton" data-bind="click:toggleAnimation">Toggle Animation</button>

     <!-- warning text to show in case the browser does not support SVG animations -->
     <span id="browserDoesNotSupportSVGAnimationsText" style="display:none;color:Red;font-weight:bold; font-size:30px">Your browser does not support SVG animations</span>
     
     <!-- warning text to show in case the browser does not support SVG -->
     <span id="browserDoesNotSupportSVGText" style="display:none;color:Red;font-weight:bold; font-size:30px">Your browser does not support SVG</span>
    
    <!-- displays information about selected solar system body -->
    <span  id="selectedSolarSystemBodyInfo" style="margin:0px 50px;color:White;" >
        <span style="color:Aqua; font-weight:bold" data-bind="text:selectedSolarSystemBody().name"></span>:&nbsp;
        <span data-bind="text:selectedSolarSystemBody().details"></span>
    </span>
</div>
<svg id="solarSystem" overflow="auto" height="1300" width="1300">

    <!-- foreach binding creates a visual element for each
         item within the View Model's observable array -->
    <svg data-bind="foreach:solarSystemObjects">
        <!-- orbit circle -->
        <!-- fill="none" make it possible to click-through the svg control see point events-->
        <circle cx="500" cy="305" data-bind="attr:{r: radius}" stroke="yellow" stroke-width="1" fill="none"/> 

        <!-- svg group tag (groups element under it). It allows applying transforms and animations to
             all the grouped element at the same time -->
        <g>
            <!-- this is built-in SVG transform animation. It animates rotation (see the "type" attribute).
                 "from" and "to" attributes for "rotation" consist of angle in degrees followed by 
                 the x and y coordinates of the rotation center.
                 "begin" attribute states that the rotation should start right away.
                 "repeatCount" set to "indefinite" means that the rotation should continue for ever.
                 Knockout bindings bind 
                 the rotation duration ("dur" attribute) to "fullCircleDuration" property of the 
                    individual solar system body View Model.
                 Also we use animationControl custom binding connected to "runAnimation" property on
                 the whole solar system View Model to control the animation start and stop -->
            <animateTransform attributeName="transform" 
                              type="rotate"
                              from="0 500 305" 
                              to="360 500 305" 
                              begin="0s"
                              data-bind="attr:{dur: fullCircleDuration}, animationControl: $parent.runAnimation"
                              repeatCount="indefinite"/>

            <!-- this svg tag groups the elements under it and shifts them horizontally by 475 pixels 
                 to align them with the center of the orbits-->
            <svg x="475">
                 <!-- this svg tag groups the elements under it and shifts them vertically by 280 pixels 
                        to align them with the center of the orbits. Also it shifts the individual solar system body 
                        visual objects along axis x. The shift is determined by the radius of its orbit 
                        (see data-bind="attr:{x: radius}") -->
                <svg y="280" data-bind="attr:{x: radius}">
                    <!-- solar system body image to be displayed. -->
                    <image data-bind="click:$parent.setSelected, xlinkHref:imagePath" width="20" height="20" x="15" y="15" />

                    <!-- yellow circle around the selected image. Displays only for the image that has been selected -->
                    <circle data-bind="visible: ($parent.selectedSolarSystemBody()) && (name === $parent.selectedSolarSystemBody().name)" cx="25" cy="25" r="23" stroke="yellow" stroke-width="2" fill-opacity="0" /> 
                </svg>
            </svg>
        </g>

    </svg>
</svg>
</body>
</html>
<script src="../Scripts/jquery-1.8.1.min.js" type="text/javascript"></script>
<script src="../Scripts/knockout-2.1.0.debug.js" type="text/javascript"></script>
<script src="../Scripts/XlinkHrefCustomBinding.js" type="text/javascript"></script>
<script src="../Scripts/AnimationControlBinding.js" type="text/javascript"></script>
<script src="../Scripts/SolarSystem.js" type="text/javascript"></script>

<script type="text/javascript">
    $(function () { // Code within the curly brackets, is executed right after the document has been loaded

        // if SVG is not supported by a browser, display only the browserDoesNotSupportSVGText warning text
        // and make everything else invisible
        if (!document.createElementNS) { 
            browserDoesNotSupportSVGText.style.display = "inline";
            toggleAnimationButton.style.display = "none";
            selectedSolarSystemBodyInfo.style.display = "none";
            solarSystem.style.display = "none";
            return;
        }

        var animationTransform = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");

        // if SVG animations are not supported by the browser, display 
        // browserDoesNotSupportSVGAnimationsText warning text
        if (!animationTransform.beginElement) // check if the browser does not supports SVG animations
        {
            toggleAnimationButton.style.display = "none";
            browserDoesNotSupportSVGAnimationsText.style.display = "inline";
        }

        // create the knockout bindings
        ko.applyBindings(solarSys.vm);
    });
</script>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect AWebPros
United States United States
I am a software architect and a developer with great passion for new engineering solutions and finding and applying design patterns.

I am passionate about learning new ways of building software and sharing my knowledge with others.

I worked with many various languages including C#, Java and C++.

I fell in love with WPF (and later Silverlight) at first sight. After Microsoft killed Silverlight, I was distraught until I found Avalonia - a great multiplatform package for building UI on Windows, Linux, Mac as well as within browsers (using WASM) and for mobile platforms.

I have my Ph.D. from RPI.

here is my linkedin profile

Comments and Discussions