Chapter 3.2 - Homework


Warmup

To get a bit of practice with functions and objects, create a function called convertFahrenheitToCelsius that accepts an object that contains a fahrenheit field, converts it to Celsius and saves to celsius field, and returns the whole object. Your function should look like this:

function convertFahrenheitToCelsius(temperature) {
    // your code goes here
}

Once you implement it, if we run the following code:

let temp = { fahrenheit: 100 }
temp = convertFahrenheitToCelsius(temp)
console.log(temp.celsius)

it will print the temperature in Celsius!

Animations using JavaScript libraries

Go to this link to complete this assignment. We are going to be using the I2Djs framework to create a fun animation!

Picture of animation using JS

JavaScript can be used as a drawing tool, bringing HTML and CSS elements to life on a web browser screen. Being able to make static pages look more appealing with graphical elements is a key part of web development, so learning how to make the most out of JavaScript’s drawing capabilities is critical.

First, we are going to create some variables in the global scope. For the purpose of this assignment, we will not modify the HTML nor the CSS files.

var renderer_ = i2d.svgLayer('#MySVG', { });
var parallelChain = i2d.chain.parallelChain().loop(10)
var circlesCount = 100
var radius = 100

Here, we created an SVG layer by invoking the svgLayer method with ContainerID "#mySvg". It returns the SVG renderer instance and saves a reference point to the variable renderer_. Then, we created an instance of a parallelChain() which is used to perform one or more animations simultaneously. The .loop(10) specification changes configures the animation to run 10 times. circlesCount set the number of circles created to 100 and their radius to 100 pixels.

var g = renderer_.createEl({
    el: 'group',
    attr: {
        transform: {
            translate: [renderer_.width / 2, renderer_.height / 2]
        }
    }
})

.createEl({...}) is used to create the Element of type el with attr attributes. The element is saved to the var g.

g.createEls((new Array(circlesCount)).fill().map(function(d, i) {
        return i
    }), {
        el: 'circle',
        attr: {
            r: 5,
            cx: 0,
            cy: 0
        },
        style: {
            fill: function(d) {
                return 'hsl(' + ((d % 50) / 50) * 360 + ',70%, 50%)'
            }
        }
    })
    .exec(animateEachCircle)

The .createEls function is used to create more than one element fo type g based on the information given in the form of an array.

function animateEachCircle(d) {
    parallelChain.add(this.animateExe({
        duration: 2000,
        delay: (d % 50) * 30,
        ease: 'easeInOutSin',
        attr: function(f) {
            this.setAttr({
                cx: radius * Math.cos(f * Math.PI * 2 + Math.PI * Math.floor(d / 50)) + (-radius + Math.floor(d / 50) * radius * 2),
                cy: radius * Math.sin(f * Math.PI * 2 + Math.PI * Math.floor(d / 50))
            })
        }
    }))
}

We define a function animateEachCircle that takes an element d and animates it using the parallelChain we defined earlier. This is not imperative that you undestand in great detail since the assignment is only meant to demonstrate a high level function-usage to you.

Ensure your animation runs by adding this at the bottom of your code:

parallelChain.start()

Here is what the complete code should look like:

var renderer_ = i2d.svgLayer('#MySVG', { });
var parallelChain = i2d.chain.parallelChain().loop(10)
var circlesCount = 100
var radius = 100

var g = renderer_.createEl({
    el: 'group',
    attr: {
        transform: {
            translate: [renderer_.width / 2, renderer_.height / 2]
        }
    }
})

g.createEls((new Array(circlesCount)).fill().map(function(d, i) {
        return i
    }), {
        el: 'circle',
        attr: {
            r: 5,
            cx: 0,
            cy: 0
        },
        style: {
            fill: function(d) {
                return 'hsl(' + ((d % 50) / 50) * 360 + ',70%, 50%)'
            }
        }
    })
    .exec(animateEachCircle)

function animateEachCircle(d) {
    parallelChain.add(this.animateExe({
        duration: 2000,
        delay: (d % 50) * 30,
        ease: 'easeInOutSin',
        attr: function(f) {
            this.setAttr({
                cx: radius * Math.cos(f * Math.PI * 2 + Math.PI * Math.floor(d / 50)) + (-radius + Math.floor(d / 50) * radius * 2),
                cy: radius * Math.sin(f * Math.PI * 2 + Math.PI * Math.floor(d / 50))
            })
        }
    }))
}

parallelChain.start()