Playground fun and stuff

thank you so much again for the time you are spending for us grasshopper noobies =)
yeah i don’t know how i could forgot the thing with the pointers, but it’s good to have it back in my consiousness. How about function calls and object parameters, are they called by reference or by value like primitive parameters - i mean, when I for instance change the object parameter’s property values within the function, will it change the original object’s property values?

as for now and my last experiments on the grasshopper playground - i have been playing with gradients and transitions with duration (and finally with nested array bar charts). it looks like js needs a long time for calculations when calling .transition() for shapes with gradients.

if in the snippet shown below, you click on the upper background, the balls will elasticly move around and have a new position and size and (instead of color) a new color gradient. so far so good, the size and position transition works indeed fine, but the new gradients are shown only after the balls have reached their new size and position, no matter i use a second .transition() and .duration(0) or not.

if i dont call .transition() a second time it’s even worse: the balls will disapear immediately for 5000 milliseconds (the duration time i choosed) and then will suddently appear again at their new position with new size and gradient - no transition will be seen. the second duration(0) call is also needed since without, the transition of position and size can be seen but after the balls have reached their final position (and have their new size), they would simply disapear for another 5000 milliseconds, and then suddenly appear again with their new color gradients.

the best result i could get is with a second call of .transition() and .duration(0) before the call of attr('fill', ...). it seems there is simply no smooth transition of gradients, whereas simple color transitions (without gradient) work fine.

4 Likes

Once again, very nice work! I’m in awe!

While I can’t be totally sure without playing with the code myself, the issue is probably some complication with having a transition inside a for loop. There’s a relevant stack overflow post about it here.

You can also dig into the D3 docs here on Github.

Good luck!
Ben

1 Like

Thx for answering.

As for the ‘relevant overflow post’ you linked - the code there works fine here, i only added “http:” in the -tag. And of course i shifted var now=d3.select('#cc'); one line above the loop - but it even works fine when i let it in the loop (what makes no sense).

Of course I can let you play with the code, i only fear you have no time… here we go:
EDIT#1: I don’t know why but the spoiler does not work proper, maybe the code is too long…
EDIT#2: if you use it in a html-doc you will need a div element with id=“gernots-svg-container”:

<div id="gernots-svg-container"></div>

    if (document.getElementById('gernots-svg-container') === null) 
      disableLimits();                                                  // disable the 500 function call limit
    // ---------------------------------------------------------------------------------------
    const scrWidth = 230;	                                            // screen width at learn.grasshopper.app
    const scrHeight = 400;	                                            // screen height at learn.grasshopper.app
    const rMax = 10;		                                            // max radius of the balls
    const rMin = 6;		                                                // min radius of the balls
    const number = 20;                                                  // number of balls
    const time = 5000;     	                                            // duration of transition
    const colors = [                                                    // const array with color pairs for the ball's gradients
      ['orangered', 'darkred'], 
      ['pink', 'deeppink'], 
      ['orange', 'red'], 
      ['lime', 'green'], 
      ['yellow', 'orangered'],
      ['purple', 'violett']
    ];
    const scrGradient = {                                               // gradient for the screen
      type: 'linear',
      id: 'scr',
      geo: [0.2, 0, 0.8, 1],
      offset: [0, 1],
      color: ['blue', 'midnightblue'],
      opacity: [1, 1]
    }
    const ballGradient = {                                              // Template, which holds the const properties
      type: 'radial',
      id: '',                                                           // id is not constant and will get assign unique values to
      geo: [0.35, 0.35, 0.65],
      offset: [0, 1],
      color: [],                                                        // color is not constant and will store a unique pair of colors
      opacity: [1, 0.5]
    }
    // -------------------------------------------------------------------------------------------------------------------------------------
    if (document.getElementById('gernots-svg-container') !== null) {
      var svg = d3
        .select('#gernots-svg-container').append('svg')
        .attr('width', scrWidth).attr('height', scrHeight);
    }
    var defs = svg.append('defs');
    var fillBall = [];
    var balls = [];
    var gradients = [];                                                 // nested array to store the gradientID
    var gradientsAssigned = 0;                                          // until now gradients never been assigned
    // -------------------------------------------------------------------------------------------------------------------------------------
    function addGradient(gradient) {                                    // add a gradient to defs of svg
      let newGradient = defs
          .append(gradient.type + 'Gradient')
          .attr('id', gradient.id);
      if (gradient.type === 'radial') {                                 // if gradient.type is 'radial'
        newGradient                                                     // set x- and y-center and the radius of the gradient
          .attr('cx', gradient.geo[0])
          .attr('cy', gradient.geo[1])
          .attr('r', gradient.geo[2])  
      } else if (gradient.type === 'linear') {                          // if gradient.type is 'linear'
        newGradient                                                     // set start- and end-points of the gradient
          .attr('x1', gradient.geo[0])
          .attr('y1', gradient.geo[1])
          .attr('x2', gradient.geo[2])
          .attr('y2', gradient.geo[3])
      }
      for (let i = 0; i < gradient.offset.length; i++) {                // for every given stop
        newGradient.append('stop')                                      // add the stop to the new gradient
          .attr('offset', gradient.offset[i])                           // store their attr values
          .attr('stop-color', gradient.color[i])
          .attr('opacity', gradient.opacity[i]);
      }
      return 'url(#' + gradient.id + ')';                               // RETURN VALUE is used to call .attr('fill', RETURN VALUE)
    }
    // -------------------------------------------------------------------------------------------------------------------------------------
    function addBallGradients() {
    // every element in the const array 'colors' (see const declaration section above) is a unique pair of colors for the balls. for every
    // element in 'colors' a unique gradient will be created, where the property 'color' will hold the unique pair of colors, and 'id' will
    // hold a unique identifier (a letter followed by a counter). the other properties will stay constant for every gradient.
    // the gradient will be added to 'svg.defs' and a string "'url(#' + id + ')'" will be stored in the var array 'fillBall'
      var gradient = ballGradient;                                      // assign the const values to the properties
      for (let c = 0; c < colors.length; c++) {                         // assign the unique values to:
        gradient.id = 'ball' + c;                                       //   - the 'id' property
        gradient.color = colors[c];                                     //   - the 'color' property
        fillBall[c] = addGradient(gradient);                            // append the gradient to svg.defs and add the returned string
      }                                                                 // to the var array 'fillBall'. string pattern is "'url(#' + id + ')'"
    }
    // -------------------------------------------------------------------------------------------------------------------------------------
    var scr =                                                           // variable 'scr' will be used to create a click event handler
        svg.append('rect')                                            // inside the svg-container draw the background rectangle
        .attr('width', scrWidth).attr('height', scrHeight)            // use const scrWidth and scrHeight declared above
        .attr('fill', addGradient(scrGradient));                      // use const scrGradient declared above

    addBallGradients();
    var gradientID;
    var ball;
    var r;
    gradients[0] = [];                                                // 1. element of array 'gradients' is an empty array

    for (let i = 0; i < number; i++) {

      r = rMin + Math.floor(Math.random() * (rMax - rMin) );          // pick random radius r in the range rMin - rMax
      gradientID = Math.floor(Math.random() * colors.length);         // pick a random member of the var array 'fillBall' and ...
      ball = svg.append('circle')                                     // inside the svg-container draw a ball with ...
        .attr('cx',r + Math.floor(Math.random() * (scrWidth - 2 * r)))// ... random x coordinate of center and ...
        .attr('cy',r + Math.floor(Math.random() * (scrHeight - 2 * r)))// ... random y coordinate of center and with ...
        .attr('r', r)                                                 // the random radius r
        .attr('fill',fillBall[gradientID]);                           // ... fill the ball with that color gradient
      gradients[0][i] = gradientID;                                   // store the used gradient index in gradients[0][i]

      balls[i] = ball;                                                // add the ball to the array variable 'balls'
    }

    gradientsAssigned = 1;                                            // gradients were assigned once until now

    scr.on('click', () => {                                           // event handler

      gradients.push([]);                                             // add a new element (empty array) to array variable 'gradients'

      for (let i = 0; i < number; i++) {

        r = rMin + Math.floor(Math.random() * (rMax - rMin) );        // pick random radius r in the range rMin - rMax
        do {
          gradientID = Math.floor(Math.random() * colors.length);     // pick a random member of the var array 'fillBall' and
        } while (gradientID === gradients[gradientsAssigned - 1][i]); // make sure that it's not the same as before the click
        balls[i].transition().duration(time).ease(d3.easeElastic)
          .attr('cx',r + Math.floor(Math.random() * (scrWidth - 2 * r)))// ... random x coordinate of center and ...
          .attr('cy',r + Math.floor(Math.random() * (scrHeight - 2 * r)))// ... random y coordinate of center and with ...
          .attr('r', r)                                               // the random radius r
          .transition().duration(0)
          .attr('fill',fillBall[gradientID]);
        gradients[gradientsAssigned][i] = gradientID;                 // store the used gradient index in gradients[gradientsAssigned][i]
      }
      gradientsAssigned++;                                            // gradients were assigned one more time
    });
3 Likes

Thanks! I’ll take a look at it when I find some free time.

2 Likes

I deleted grasshopper because it was misbehaving and I believed if I reinstalled it, my progress would return. Well… it didn’t and am in animations pls help I can’t start again

I am not getting this recursive code

@Grasshopper_Ben can you please explain it

1 Like

Hey, @Grasshopper_Ben
I made this all by myself. Do you like it?

1 Like

Can anyone help me out.

I use mobile and I can’t figure out what I’m supposed to do in place of the drawbox( ) function in the code playground

I’d like to note the drawbox ( ) function does not show up in the list of functions when trying to use them

Hey, @Aliyah.
Who don’t you look at my post?
I created the biggest rainbow using drawBoxes().
To do this, insert drawBoxes() and choose any letter as colors you want.
Hope that help!
Pummarin

Hey, @charism. Very nice and cool program! This is not a memory problem, thought you’re hit a limit function call. At very top of the 1st code line, use disableLimits(); code to disable limit.

Hope that helps! If you have any questions then you can ask me.
Pummarin



Hey there, @Grasshopper_Ben. I did this today. Do you like it? (The project name is Basketball Game.) (Made with SVG and used .on() method to dunk a ball to the hoop.)

1 Like

Pretty bouncy, huh :grin:

1 Like



Hey, @Grasshopper_Ben. I did this today. Do you like it? (The project name is Flying Bird.) (Made with SVG and used .on() method to make a bird fly to the finish lane.)

In my new snippet, it will create a blue circle. Once it is clicked, the circle’s color will be changed to others.

I used my mobile phone and Grasshopper Gallery to make this. Here is a link of this snippet:

I hope you liked it, @Grasshopper_Ben!

Can anybody tell me whats wrong with it

Hi there guys here is

let Geo;
Geo = 'hebrew';
let BubbleShooter;
let bubble;
let shooter;
let shotgun;
let ellipse;

BubbleShooter = 'bbbbbbb bcbbbbb cccbbbb bcbbbbb bbbbbbb';
bubble = 'ddctcdd bbbbbbb bbbbbbb';
shooter = 'shot down gun';
shotgun = 'mini';

if (BubbleShooter === 'puzzle') {
   print('Shoot up guns');
} else {
   print('shoot to aim');
}

function shoot() {
   print('use minigun or minigame');
}

shoot();
let blocks = 126;
let fillings = [red, green, blue, white, yellow, orange, black];
blocks + fillings;
if (blocks === 6666) {
   print('ARRGH MY GUNS DESTROYED');
} else {
  print('let us kill zombies and bubble and blocks');
}
let fireBalls = 'red and orange filled';
if (fireBalls === red) {
   print('no bullets');
} else {
   print('fire ball bullets');
}

So here’s a name expmale:

QKGJ 1347

:frowning:

//ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz134567890`~!@
//#$%^&*()<>,.:;'"/?{}[]_-+=

How about this