Mirror the waves on the left side with waves I have already created on the right side

Viewed 30

PROBLEM: I cannot get the waves to appear on the left side of the canvas as well.

QUESTION: How do I mirror the waves I have already created? Or I need to figure out how to draw the lines on the left side as well.

SEARCHED/TRIED: search for Googled: javascript mirror art on canvas2d. I have such a specific project which makes it hard to search.

INFO/background: The code snippet included has been modified by me. Credit goes to @Blindman67 I am under the impression that using canvas is better on your processor because it uses your graphics card. I am not sure the better method mirroring or drawing the bars on the left side.

Inspiration: YouTube: enter image description here Link to video: https://www.youtube.com/watch?v=-475XHUgkiQ&t=22782s&ab_channel=APMusic

My Original Code: from CodePen.io enter image description here Link to codepen.io: https://codepen.io/ac0ua/pen/BaReZEx

    const barsDefault = {  // colors  Must be 4 char CSS hash color eg `#F00` is red
        count: 60,
        meanSize: 16,         // number of bars per mean bucket (mean is used for bg glows)
        glowDecay: 0.3,       // pulls down mean bucket values
    glows: [
        ["#F00", "#40F", "#00F", "#00F", "#00F", "#00F"],
        ["#0F0", "#0F8", "#06F", "#00F", "#00F", "#00F"],
        ["#40F", "#00F", "#00F", "#00F"],
    ],
    centerRadius: 35,
    decay: 0.1,
    innerHeightPad: 10,        //canvas padding or wave padding/margin
    color: "#FFF",             // Must be 4 char CSS hash color
    barWidth: 0.6,             // fraction of bar space to contain bar (default:.6)
    centerBarWidth: 3,        // (default: 10) 
    centerInset: 0.9,          // as fraction of radius (default .9)
    centerInsetWidth: 0.2,     // as fraction of radius  (default .2)
    centerInsetAng: 0.5,       // as fraction of 180 deg (default .5)
    centerRotateMax: 10,       // as fraction of 180 deg (default 10)
    barFeq: 1 / 8,             // odds per frame of new position (default: 1 / 8)
    barPeakWidth: 10,          // max number of bars to spread movement. Must be whole number (default: 10)
    barPeakWidthMin: 2,        // min number of bars to spread movement. Must be whole number >= 1 (default: 2)
    barPeakSlide: 3,           // twice Max rate that level drive slides along bars
    barLevel: 1 / 12,          // Max bar volume add
    barLevelComp: 1 / 2,       // drives bar volume compressor n. Is logarithmic. Where 0 < n < Infinity, louder as nit gets smaller
    levelDriveDecay: 0.01,     // rate that level drivers decay Must be 0 < n <= 1
    levelDriveMin: 0.05,       // min level drive. Below this level driver turns off. Must be  0 < n
    glowOffsetRate: 0.001,     // as radians per frame
    glowAlpha: 0.3,           
};

// Math Helper util
//retating the center circle
const polarArg = (ang, dist, x = 0, y = 0) => ([Math.cos(ang) * dist + x | 0, Math.sin(ang) * dist + y | 0]);
const polarArgoffset = (ang, dist, x = 0, y = 0) => ([Math.cos(ang) * dist + x | 0, (Math.sin(ang) * -1) * dist + y /1 | 0]);
const eCurve   = (v, p = 2, vp) =>  v < 0 ? 0 : v > 1 ? 1 : (vp = v ** p) / (vp + (1 - v) ** p);
// const eCurve   = (v, p = 2, vp) =>  v < 0 ? 0 : v > 1 ? 1 : (vp = v ** p) / (vp + (1 - v) ** p);
const PI = Math.PI;
const TAU = PI * 2;

requestAnimationFrame(renderLoop);
const bars = Bars(canvasContainer);
addEventListener("resize", bars.resize);
function renderLoop() {
    bars.update();
    bars.draw();
    requestAnimationFrame(renderLoop);
}

function Bars(container, config = {}) {
    var bounds, w, h;
    const canvas = document.createElement("canvas")
    const ctx = canvas.getContext("2d");
    container.appendChild(canvas);

    function resize() {
        bounds = container.getBoundingClientRect();
        w = bounds.width;
        h = bounds.height;
        Object.assign(Object.assign(canvas, {
            width: w,
            height: h
            })
            .style, {
                position: "absolute",
                top: "0px",
                left:"0px"
            });
        ctx.lineCap = ctx.lineJoin = "arrow"; //endings of the wave lengths (default "round")
        centerBar = ctx.createLinearGradient(0, 0,w, 0);
        centerBar.addColorStop(0, setup.color + "0");
        centerBar.addColorStop(0.2, setup.color + "A");
        centerBar.addColorStop(0.4, setup.color + "F");
        centerBar.addColorStop(0.6, setup.color + "F");
        centerBar.addColorStop(0.8, setup.color + "A");
        centerBar.addColorStop(1, setup.color + "0");
    }

    const setup = {
        ...barsDefault,
        // ...config,
    };

    resize(); //calls resize

    const levels = new Array(setup.count).fill(0);
    const levelDrivers = [];  
    const meanSize = setup.count /setup.meanSize   | 0;
    const means = new Array(setup.count / meanSize | 0).fill(0);
    var rotate = 0, rotatePos = 0, rotateDelta = 0, totalLevel = 0, glowAng1 = 0, glowAng2 = 0;
    
    // create center bar gradient
    var centerBar;
    
    return Object.freeze({
        update() {
            // updateCenter();
            updateBars();
        },
        draw() {
            ctx.setTransform(1,0,0,1,0,0);
            ctx.clearRect(0, 0, w, h);
            ctx.fillStyle = setup.color;
            drawBars();
        },
        resize,
    });
    
    
    function updateBars() {
        var i = setup.count, pos, level, move, bPW, head = 0, tail = 0;
        const decay = 1 - setup.decay;
        totalLevel = 0;     // global to Bars
        while (i--) {
            means[i / meanSize | 0] += levels[i];
            totalLevel += levels[i];
            levels[i] *= decay;
        }
        if (Math.random() < setup.barFeq) {
            const pos = setup.count * Math.random() | 0;
            const level = Math.random() ** setup.barLevelComp * setup.barLevel;
            levelDrivers.push([
                pos,
                level,
                (Math.random() - 0.5) * setup.barPeakSlide,
                Math.random() * (setup.barPeakWidth - setup.barPeakWidthMin) + setup.barPeakWidthMin | 0,
            ]);
        }
        while (head < levelDrivers.length) {
            const lDrive = levelDrivers[head++];
            [pos, level, move, bPW] = lDrive; // bPW for bar Peak Width
            lDrive[0] = pos += move;
            pos |= 0;
            pos >= 0 && pos < setup.count && (levels[pos] = Math.min(1, levels[pos] + level));
            i = 1;
            while (i < bPW) {
                const levelAdd = eCurve(1 - i / bPW) * level;
                pos + i < setup.count && (levels[pos + i] = Math.min(1, levels[pos + i] + levelAdd));
                pos - i >= 0 && (levels[pos - i] = Math.min(1, levels[pos - i] + levelAdd));
                i++;
            }
            lDrive[1] = (level *= 1 - setup.levelDriveDecay);
            if (level > setup.levelDriveMin && pos + bPW >= 0  && pos - bPW < setup.count) {
                levelDrivers[tail++] = lDrive;
            }
        }
        levelDrivers.length = tail;
    }   

    function drawBars() 
        {
        const cw = w * 0.5, 
              ch = h * 0.5;
        var   i = setup.count, 
              j = 0,
              xl = cw - setup.centerRadius, 
              xr = cw + setup.centerRadius, 
              x = 0;
        const cr = setup.centerRadius,
              damp = setup.count * 0.3,
              xs = xl / setup.count, 
              xw = xs * setup.barWidth,
              hScale = ch - setup.innerHeightPad;
              const output = document.querySelector("h1");
        ctx.fillStyle = centerBar;

            ctx.strokeStyle = centerBar;//setup.color;
            ctx.lineWidth = xw;
            ctx.beginPath();
            while (i--) {
                const lh = (j < damp ? 1-((damp-j) / damp) ** 2 : 1) * levels[i] * hScale;
                if(lh > 0.5) {
                    setTimeout(function() { }, 1600);
                    const r = x * 4 + cr;
                    const lhr = lh / r;
                    output.innerText = (polarArgoffset(lhr + 0.0001, r, xl + cr - x * 3, ch)) + "\n";
                    output.innerText += (polarArg(lhr + 0.0001, r, xl + cr - x * 3, ch));
                // add lhr + 0.0001 to start angle to fix miter artifact
                ctx.moveTo(...polarArg(lhr + 0.0001, r, xl + cr - x * 3, ch))
                ctx.lineTo(...polarArgoffset(lhr + 0.0001, r, xl + cr - x * 3, ch))
                // ctx.arc (xl + cr - x * 3, ch, r, lhr, -lhr, true);

                // ctx.lineTo(...polarArgoffset(PI + lhr + 0.0001, r, xr - cr + x * 3, chh))
                // ctx.moveTo(...polarArg(PI + lhr + 0.0001, r, xr - cr + x * 3, ch))

                // ctx.arc (xr - cr + x * 3, ch, r, PI + lhr, PI - lhr, true);
            }
            j ++;
            x += xs;
        }
        ctx.stroke();
    }

}
#container {   
    background-image: radial-gradient(circle at 40px 40px,  rgba(157,227,255,1) 0%, rgba(60,152,240,1) 24%, rgba(44,73,105,1) 56%, rgba(12,1,66,1) 94%, rgba(0,0,1,1) 100%);
        font-family: Arial Black;
        position: absolute;
        top: 0px;
        left: 0px;
        width: 100%;
        height: 100%;
    }
    h1, h2 {
      text-align: center;
      font-size: xx-large;
    }
    h1 { color: #fff;font-size: xxx-large}
    h2 { color: #8F4}
    #canvasContainer {  
      position: absolute;    
      top: 29%;    
      left: 0px;    
      height: 70%;  
      width: 100%;
    }
    canvas {
       mix-blend-mode: lighten;
    }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <title>Document</title>
</head>
<body>
    <div id="container">
        <h1>Audio <span>Candy</span></h1>
        <h2>2D Canvas Animation</font>
        <div id="canvasContainer"></div>
        </div>
        <script src="script.js"></script>
</body>
</html>

Codereview https://codereview.stackexchange.com/questions/266300/create-random-wave-forms-using-javascript-and-css

0 Answers
Related