williamngan/pts

can't get noise resizing work

jaro-io opened this issue · 5 comments

heyho 🦚✨
i am just starting with pts, so my question might be a little strange. but maybe it will help someone in the future as well. also, this is not bug-related. i just need some help. thank you.


so, i have an array of percentage-based x and y position pairs. something like [[15, 36], [22, 59], [55, 47], [45, 36], [35, 47]], where the first point is at 15% on the x axis and 36% on the y axis of the space. i wrote a little function to convert my array into Pts. i bet this is not the most elegant solution, but it works fine. my function looks like this:

function getPath(points, space) {

    let pts = [];
    let size  = space.width / 100;

    points.forEach(xy => {

        pts.push(new Pt(size * xy[0], size * xy[1]));
    });

    return pts;
}

to make my line move, i created noise points from my returned array of Pts. this also works fine. ueeey.

space.add({

    start: function() {

        line = getPath(pts, space);
        noiseLine = Create.noisePts(line, 0, 0.5);
    },

    animate: function() {

        form.scope(this); // i am using the svg canvas

        // generate noise in line
        let nps = noiseLine.map((p) => {

            p.step(0, 0.0025);
            return p.$add(p.noise2D() * space.center.y / 5 * multiplier, p.noise2D() * space.center.y / 3);
        });

        form.strokeOnly('#78809E', 2).line(Curve.bspline(nps, 20));
    }
});

now, to my problem. when resizing the browser window, the space is resizing (resize: true on setup), but not the points inside of it. i tried various solutions, but i could only make it work with a repaint of the whole noise line which results in a jump because the new line looks different than the one before.

it took me days already to get to here, so it would be super lovely to get some help with this. maybe also with general improvement of my code.

thank you so much!
jaro
🗻

Hi @jaro-io -- try adding a resize(bound, evt) callback into your player, and use the bound value to recalculate the positions. See the source code in these demos:

https://ptsjs.org/demo/edit/?name=canvasspace.resize
https://ptsjs.org/demo/?name=svgform.scope

Something like this should work (though I haven't tested it).

let scales = [[0.15, 0.36], [0.22, 0.59], [0.55, 0.47], ...];
...
space.add({
  animate: ...,
  resize: function (bound, evt) {
    let line = scales.map( s => bound.size.$multiply( s ) );
    let noiseLine = ...
  }
})

Hope this helps. Please feel free to open issues if you get stuck :)

Oops, made an error in the code above. Just edited.

@williamngan thank you so much for all your help. i deeply appreciate that. first of all, using map() and $multiply() works like a charm. so thank your for this tip already. its a lot shorter than what i did.


but about resizing: i still get the same results as before. the lines do adapt to the new canvas size, but generating the noise values again and again with every resized pixel is causing weird jumps. i actually would just like to see my animation scale up or down accordingly.

to illustrate my problem, i created another pen to play around with and a little video to show whats happening.

https://codepen.io/jaro_io/pen/BaLZGBP

pts_resizing.mp4

again, thank you for standing by!
🍃 🦘

I see what you're trying to achieve now. In this case, you may not need the resize callback. It can be as straightforward as creating noise from your original points first, and then multiplying them with space.size. Snippet:

start: function() {
  noise = Create.noisePts(points, 0, 0.5);
},

animate: function() {
  ...
  let nps = noise.map((p) => {
    p.step(0, 0.004);
    let np = p.$add(0, p.noise2D() * space.center.y / 3);
    return space.size.$multiply( np ).$multiply(0.01);
  });

Btw, if you define your initial percentage as 0.35 etc instead of 35 etc, then you can remove the $multiply(0.01) operation too.

@williamngan wow, beautiful. that did the trick! thank you so so much!