Black Hole explainer

Aim of the puzzle:
This puzzle uses previously taught JavaScript concepts (variables and event handlers) with previously taught D3 concepts (transition method, duration method, and attributes).

Specifically, you’ll use an event handler and a variable to animate the changing 'cx' and 'cy' attributes of SVG circles.

Walk through of solution:
In the code that you start off with, there are two variable declarations, x and y, a function, collapse, a blackHole, and an event handler. The x and y variables are some number between 0 and 200 and are used as values for the 'cx' and 'cy' attributes of blackHole. The collapse function contains an incomplete animation on stars. The animation isn’t complete because it’s missing an attribute and value for stars to transition to. Below this function, there is an event handler that calls the collapse function when blackHole is tapped. Because the animation is incomplete, nothing happens when you tap the blackHole. In this puzzle, you’ll complete the animation inside the collapse function so the stars animate when you tap blackHole.

To complete the puzzle, attach .attr('cx', x) and attr('y', y) after the .duration(4000) that’s inside the collapse function. Now, when you tap the blackHole, all the stars will move into the blackHole.

Sample code solution:
(Tap below to reveal)

let x = pickRandom(200)
let y = pickRandom(200)

function collapse() {
    stars.transition()
            .duration(4000)
            .attr('cx', x)
            .attr('cy', y)
}

blackHole.attr('cx', x).attr('cy', y)
blackHole.on('click', collapse);

Javascript Concepts: Variable, Event Handler, Function
D3 Concepts: Attribute, .duration(), .transition()
Additional Code (hidden code that runs before the puzzle’s code):

for (let i =0; i<155; i++){
    let white = svg.append('circle')             
                .attr('r',.5 + Math.random()*2)
                .attr('cx',Math.random()*window.innerWidth)
                .attr('cy',Math.random()*window.innerHeight)
                .attr('fill','white')
                .attr('opacity',`${0.2*pickRandom(9)}`);
}

for (let i =0; i<5; i++){
    let yellow = svg.append('circle')             
                .attr('r',.5 + Math.random()*2)
                .attr('cx',Math.random()*window.innerWidth)
                .attr('cy',Math.random()*window.innerHeight)
                .attr('fill','yellow')
                .attr('opacity',`${0.5*pickRandom(9)}`);
}

                
for (let i =0; i<155; i++){
    let grey = svg.append('circle')             
                .attr('r',.5 + Math.random()*2)
                .attr('cx',Math.random()*window.innerWidth)
                .attr('cy',Math.random()*window.innerHeight)
                .attr('fill','grey')
                .attr('opacity',`${0.2*pickRandom(9)}`);
}
                
let stars =d3.selectAll('circle')

let blackHole =  svg.append('circle')             
                .attr('r',30 + Math.random()*2)
                .attr('fill','black')

Hi.
Short question to the collapse-function:
Why is the value of x and y available inside the function, since these are local variables (let) and only known outside the declaration?
Souldn‘t I do a function call like collapse(x,y) and hand over the values?

Hey there,

The x and y variables are declared at the top-level of the code. This means that their code block is basically the entire program, and they can be seen everywhere. This is called “global scope”.

Hope this helps! Let me know if you have any questions.
Ben

I think I did it right buts saying I didn’t where did I go wrong??

Hey there, use the variables x and y instead of strings with the text 'x' and 'y'.

Hope this helps!
Ben