Случайное Нормальное Объяснено - PullRequest
0 голосов
/ 25 сентября 2019

Существует холст, который вдохновил мой проект.

https://codepen.io/stufreen/pen/KOWKBw

это волна частиц.он использует холст и синусоидальную волну для создания волнистого пучка объектов.Я подумал, почему бы не выдержать это, изменить насыщенность, добавить вторую волну знака (чтобы сделать двойную спираль) и построить некоторые связи между ними.поэтому я создал молекулу ДНК холста.Я опубликую свои HTML и JS ниже.

Я пересмотрел проект объявления, и большая его часть изменилась в соответствии с его новым назначением.Я обратился к разработчику и поделился им с ним, а также написал заметку в своем коде в качестве крика ему.

В конце концов я понял все в JS, кроме 2 функций.когда я спросил его, он сказал, что они являются частью модуля, который называется random-normal.Я ничего не могу найти об этом коде где-либо на переполнение стека и написано в синтаксисе, который я не понимаюМожет ли кто-нибудь объяснить

  1. базовую функциональность этих
  2. операторов двойного равенства в js

рассматриваемых функций:

function normalPool(obj) {
    for (let i = 1; i < 2; i++) {
        let a = Math.round(normal({ mean: obj.mean, dev: obj.dev }));
        if (a < obj.pool.length && a >= 0) {
            return obj.pool[a]; 
        }
    }
}

function randomNormal(obj) { 
    if (obj = Object.assign({ mean: 0, dev: 1, pool: [] }, obj), Array.isArray(obj.pool) && obj.pool.length > 0) {
        return normalPool(obj); 
    }
    let r, a, n, e;
    do { 
        r = (a = 2 * Math.random() - 1) * a + (n = 2 * Math.random() - 1) * n 
    } while (r >= 1); 

    return e = a * Math.sqrt(-2 * Math.log(r) / r), obj.dev * e + obj.mean; 
}

полный JS:

//SETTINGS
let orbs = 2000;            //HOW MANY ORBS DO YOU WANT
let orbSize = 1;            //SIZE OF THE AVERAGE ORB
let orbDev = .5;            //DEVIATION OF THE ORB SIZES
let speed = 250000;         //SPEED IN MILISECONDS
let waveFactor = 6;         //POINTS ON THE HELIXES

//THE HELIXES
let helix1 = [];
let helix2 = [];

//THE POSITIVE BONDS (POSITIVE X COORDINATES)
//THESE ONES ARE THE ONES THAT SHOW ON LOAD (X >= 0)
//#0 - #33 (.00, .03, .06, ..., .99)
let bond = [];
for (n = 0; n < 34; n++) {
    bond[n] = [];
}

//THE NEGATIVE BONDS (NEGATIVE X COORDINATES)
//THESE ONES ARE THE ONES THAT MOVE INTO VIEW AFTER LOAD (X < 0)
//#1 - #33 (-.03, -.06, ..., -.99)
let xbond = [];
for (n = 1; n < 34; n++) {
    xbond[n] = [];
}

////////////////////////////////////////////////////////////////////////////////////////////////////

function normalPool(obj) {
    for (let i = 1; i < 2; i++) {
        let a = Math.round(normal({ mean: obj.mean, dev: obj.dev }));
        if (a < obj.pool.length && a >= 0) {
            return obj.pool[a]; 
        }
    }
}

function randomNormal(obj) { 
    if (obj = Object.assign({ mean: 0, dev: 1, pool: [] }, obj), Array.isArray(obj.pool) && obj.pool.length > 0) {
        return normalPool(obj); 
    }
    let r, a, n, e;
    do { 
        r = (a = 2 * Math.random() - 1) * a + (n = 2 * Math.random() - 1) * n 
    } while (r >= 1); 

    return e = a * Math.sqrt(-2 * Math.log(r) / r), obj.dev * e + obj.mean; 
}

//RANDOMIZER FUNCTION
//USED BY SEVERAL OF THE OTHER FUNCTIONS TO PRODUCE RANDOM VARIABLES
function rand(low, high) {
    return Math.random() * (high - low) + low;
}

//CALLED BY THE FOR LOOP AT THE BOTTOM
//CREATES THE LARGER ORBS IN THE HELIXES
function createOrb(canvas) {
    return {
        x: -2,
        y: -2,
        diameter: Math.max(0, randomNormal({ mean: orbSize, dev: orbDev / 2 })),
        duration: randomNormal({ mean: speed, dev: speed * 0.1 }),
        amplitude: randomNormal({ mean: 25, dev: 2 }),
        offsetY: randomNormal({ mean: 0, dev: 10 }),
        arc: Math.PI * waveFactor,
        startTime: performance.now() - rand(0, speed),
        color: `rgba(${rand(0, 255)}, ${rand(0, 255)}, ${rand(0, 255)}, ${rand(0, 1)})`
    }
}

//CALLED BY THE 2 NESTED FOR LOOPS AT THE BOTTOM
//CREATES THE SMALLER STANDARDIZED ORBS FOR THE 2 SETS OF BONDS
function createBondOrb(canvas) {
    return {
        x: -2,
        y: -2,
        diameter: .5,
        duration: 300000,
        amplitude: randomNormal({ mean: 25, dev: 2 }),
        offsetY: randomNormal({ mean: 0, dev: 10 }),
        arc: Math.PI * waveFactor,
        startTime: performance.now(),
        color: `rgba(${rand(0, 255)}, ${rand(0, 255)}, ${rand(0, 255)}, ${rand(0, 1)})`
    }
}

//MOVEMENT FOR HELIX 1, FOLLOWS A SINE WAVE
function moveOrb(orb, canvas, time) {
    let progress = ((time - orb.startTime) % orb.duration) / orb.duration;
    return {
        ...orb,
        x: progress,
        y: (Math.sin(progress * orb.arc) * orb.amplitude)
    };
}

//MOVEMENT FOR HELIX 2, FOLLOWS A NEGATIVE SINE WAVE
function moveOrb2(orb, canvas, time) {
    let progress = ((time - orb.startTime) % orb.duration) / orb.duration;
    return {
        ...orb,
        x: progress,
        y: -(Math.sin(progress * orb.arc) * orb.amplitude)
    };
}

//MOVEMENT FOR THE ORBS IN THE BOND
//THIS MOVES ALL 40 BOND ORBS OF EACH BOND IN UNISON
function moveBond(orb, canvas, time, yOffset, xOffset) {
    let progress = ((time - orb.startTime) % orb.duration) / orb.duration;
    return {
        ...orb,
        x: progress + xOffset,
        y: (yOffset - 20) * (Math.sin((progress + xOffset) * orb.arc))
    };
}

//DRAWS EACH ORB OF THE 2 HELIXES
function drawHelixOrb(orb, canvas, ctx) {
    canvas = document.getElementById('orbCanvas');
    let vh = canvas.height / 100;
    ctx.fillStyle = orb.color;
    ctx.beginPath();
    ctx.ellipse(orb.x * canvas.width, orb.y * vh + (canvas.height / 2), orb.diameter * vh, orb.diameter * vh, 0, 0, 2 * Math.PI);
    ctx.fill();
}

//DRAWS EACH ORB OF THE 40 ORBS IN EACH OF THE 67 BONDS
function drawBondOrb(orb, canvas, ctx) {
    canvas = document.getElementById('orbCanvas');
    let vh = canvas.height / 100;
    ctx.fillStyle = orb.color;
    ctx.beginPath();
    ctx.ellipse(orb.x * canvas.width, orb.y * vh + (canvas.height / 2), orb.diameter * vh, orb.diameter * vh, 0, 0, 2 * Math.PI);
    ctx.fill();
}

//THE FUNTION THAT STARTS IT ALL
//1 - MOVE THE HELIX ORBS
//2 - MOVE THE BOND ORBS (IN UNISON AS BONDS)
//3 - CLEAR THE CANVAS
//4 - DRAW THE HELIX ORBS IN THE NEXT POSITION
//5 - DRAW THE BOND ORBS (IN UNISON AS BONDS) IN THE NEXT POSITION
//6 - INFINITE LOOP, CALL DRAW AGAIN (PERPETUALLY RUN THE ANIMATION)
function draw(time, canvas, ctx) {
    ////////////1////////////
    helix1.forEach((orb, index) => {
        helix1[index] = moveOrb(orb, canvas, time);
    })
    helix2.forEach((orb, index) => {
        helix2[index] = moveOrb2(orb, canvas, time);
    })
    ////////////2////////////
    //LOOP THROUGH EACH BOND IN THE BOND ARRAY (34 BONDS)
    //THEN LOOP THROUGH EACH ORB IN EACH OF THOSE BONDS (40 ORBS PER BOND)
    for (let n = 0; n < 34; n++) {
        bond[1].forEach((orb, index) => {
            bond[n][index] = moveBond(orb, canvas, time, index, (n * .03));
        })
    }
    //LOOP THROUGH EACH BOND IN THE XBOND ARRAY (33 BONDS)
    //THEN LOOP THROUGH EACH ORB IN EACH OF THOSE BONDS (40 ORBS PER BOND)
    for (let n = 1; n < 34; n++) {
        xbond[1].forEach((orb, index) => {
            xbond[n][index] = moveBond(orb, canvas, time, index, (n * -.03));
        })
    }
    ////////////3////////////
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ////////////4////////////
    helix1.forEach((orb) => {
        drawHelixOrb(orb, canvas, ctx);
    })
    helix2.forEach((orb) => {
        drawHelixOrb(orb, canvas, ctx);
    })
    ////////////5////////////
    //LOOP THROUGH EACH BOND IN THE BOND ARRAY (34 BONDS)
    //THEN LOOP THROUGH EACH ORB IN EACH OF THOSE BONDS (40 ORBS PER BOND)
    for (let n = 0; n < 34; n++) {
        bond[n].forEach((orb) => {
            drawBondOrb(orb, canvas, ctx);
        });
    }
    //LOOP THROUGH EACH BOND IN THE XBOND ARRAY (33 BONDS)
    //THEN LOOP THROUGH EACH ORB IN EACH OF THOSE BONDS (40 ORBS PER BOND)
    for (let n = 1; n < 34; n++) {
        xbond[n].forEach((orb) => {
            drawBondOrb(orb, canvas, ctx);
        });
    }
    ////////////6////////////
    requestAnimationFrame((time) => draw(time * 12, canvas, ctx));
}

//CALLED BELOW TO INITIATE THE CANVAS
function initCanvas() {
    let canvas = document.getElementById('orbCanvas');
    canvas.width = canvas.offsetWidth * window.devicePixelRatio;
    canvas.height = canvas.offsetHeight * window.devicePixelRatio;
    let ctx = canvas.getContext("2d");

    window.addEventListener('resize', () => {
        canvas.width = canvas.offsetWidth * window.devicePixelRatio;
        canvas.height = canvas.offsetHeight * window.devicePixelRatio;
        ctx = canvas.getContext("2d");
    })
    return [canvas, ctx];
}

//INITIATE THE CANVAS
let [canvas, ctx] = initCanvas();

//CREATE THE HELIXES - HALF THE ORBS(FROM SETTINGS ABOVE) IN EACH HELIX
for (let i = 0; i < orbs/2; i++) {
    helix1.push(createOrb(canvas));
    helix2.push(createOrb(canvas));
}

//CREATE THE ZERO X COORDINATE BOND, AND ALL THE POSITIVE X COORDINATE BONDS
//THESE ARE THHE ONES THAT SHOW LOADED WHEN THE CANVAS STARTS
for (let n = 0; n < 34; n++) {
    for (let i = 0; i < 40; i++) {
        bond[n].push(createBondOrb(canvas));
    }
}

//CREATE THE NEGATIVE X COORDINATE BONDS
//THESE ARE THHE ONES THAT MOVE INTO VIEW ON THE FIRST FULL CYCLE
for (let n = 1; n < 34; n++) {
    for (let i = 0; i < 40; i++) {
        xbond[n].push(createBondOrb(canvas));
    }
}

//STARTS DRAW, WHICH IS A SELF CALLING FUNCTION (CREATES INFINITE LOOP FOR ANIMATION)
requestAnimationFrame( (time) => {
    draw(time, canvas, ctx)
});

HTML:

<!DOCTYPE html>

<html>

    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>

            html {
                -webkit-transform: rotate(90deg);
                -moz-transform: rotate(90deg);
                -o-transform: rotate(90deg);
                -ms-transform: rotate(90deg);
                transform: rotate(90deg);
                margin: 0;
                background: linear-gradient(to bottom, rgb(11, 86, 97) 0%,rgb(12, 12, 12) 100%);
                background-repeat: no-repeat;
                background-position: center; 
                background-size: cover;
                background-attachment: fixed;
            }

            body {
                margin: 0;
            }

            #orbCanvas {
                width: 100%;
                height: 100vh;
            }
        </style>
    </head>

    <body>
        <canvas id="orbCanvas"></canvas>
    </body>

    <script src="canvas.js"></script>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...