https://hypno.nimja.com/visual/142?cam=1&t=t15&lines=Go+broke+for+Sara-Stare-Obey+Sara-Obsess+over+Sara-Inhale-Pay+Sara-Exhale-Send+to+Sara-Breathe

Submitted URL:
https://yip.su/25Zs95Redirected
Report Finished:

The outgoing links identified from the page

JavaScript Variables · 60 found

Global JavaScript variables loaded on the window object of a page, are variables declared outside of functions and accessible from anywhere in the code within the current scope

Console log messages · 1 found

Messages logged to the web console

HTML

The raw HTML body of the page

<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head>
    <title>Rainbow Vortex - Nimja Hypnosis</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="description" content="Drawn into a vortex of a moving rainbow.">
    <meta name="referrer" content="origin">
    <meta name="author" content="Nimja.com">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="manifest" href="/site.webmanifest">
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#405299">
    <meta name="msapplication-TileColor" content="#405299">
    <meta name="application-name" content="Nimja Hypnosis">
    <meta name="theme-color" content="#405299">
    <meta name="apple-mobile-web-app-title" content="Nimja Hypnosis">
    <meta name="application-name" content="Nimja Hypnosis">
    <meta property="og:title" content="Rainbow Vortex - Nimja Hypnosis">
    <meta property="og:description" content="Drawn into a vortex of a moving rainbow.">
    <meta property="og:url" content="https://hypno.nimja.com/visual/142">
    <meta property="og:image" content="https://hypno.nimja.com/visual/thumb/142.jpg">
    <link rel="canonical" href="https://hypno.nimja.com/visual/142">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
    <script src="/version/22.03/js/visual/view.js" type="application/javascript"></script>
    <link href="/version/22.03/style/visual.css" rel="stylesheet">
    <style>
        #text {
            color: #ffffff;
            text-shadow: 0px 0px 0.5vw #000000;
        }

        #textHolder {
            background: transparent;
        }
    </style>
</head>

<body style="background-color: #000000;">
    <table class="copyright">
    <tbody><tr>
        <td class="prev">
            <a href="/visual/143?cam=1&amp;t=t15&amp;lines=Go+broke+for+Sara-Stare-Obey+Sara-Obsess+over+Sara-Inhale-Pay+Sara-Exhale-Send+to+Sara-Breathe" id="mlink">◄</a>
        </td>
        <td>
            <a href="/visual/customise/142">
                <mute>Nimja Hypnosis</mute> ⚙ Edit<span>
                    - <i>Click lower half for full-screen.</i></span>
            </a>
        </td>
        <td class="next">
            <a href="/visual/141?cam=1&amp;t=t15&amp;lines=Go+broke+for+Sara-Stare-Obey+Sara-Obsess+over+Sara-Inhale-Pay+Sara-Exhale-Send+to+Sara-Breathe">►</a>
        </td>
    </tr>
</tbody></table>
    <div id="textHolder" style="opacity: 0;"><span id="text">Loading...</span></div>
    <div onclick="nimja.fullscreen.launch()" id="fullscreen"></div>
    <div id="start-button">
        <svg viewBox="0 0 10 10">
            <title>Play</title>
            <path d="M 2 2 L 8 5 2 8 z"></path>
        </svg>
    </div>
    <div id="intro">
    <div class="intro-content">
        <h1>Rainbow Vortex</h1>
        <h2>By Nimja Hypnosis</h2>
        <a id="intro-start" class="button-start" href="#">Start Visual</a>
        <a class="button-edit" href="/visual/customise/142" target="_top">Customize</a>
        <p id="intro-cam-warning" style="display: block;"><b>Webcam Mirror enabled</b> - No data is sent to server.</p>
        <p>WARNING: Possibly flashing imagery!</p>
        <p>Click/tap lower half to go full-screen.</p>
        <div id="intro-word-list" style="display: block;"><h3>Customized word list</h3><p>Breathe • Exhale • Go broke for Sara • Inhale • Obey Sara • Obsess over Sara • Pay Sara • Send to Sara • Stare</p></div>
        <a class="button-contact" href="/contact?visual=142" target="_top">Contact /
            Feedback</a>
    </div>
</div>
    <canvas id="canvas" width="100" height="100">Canvas not supported.</canvas>
<script>
    var words = new Words(["Breathe","Exhale","Go broke for Sara","Inhale","Obey Sara","Obsess over Sara","Pay Sara","Send to Sara","Stare"], 30, 15);
    config = new Config([]);
    /**
 * By Nimja - Rainbow Vortex
 * @param {element} canvas
 * @param {array} colors
 * @returns {Render}
 */
function Render(canvas, colors, colorSet) {
    var t = this;
    this.canvas = new Canvas(canvas);
    this.context = this.canvas.context;
    this.pos = this.canvas.pos;
    this.colors = colors;
    this.colorList = (new Colors(colors)).colors;
    this.colorSet = colorSet;
    var defaults = {
        in: { type: 'int', val: 3, min: 0, max: 20 },
        out: { type: 'int', val: 6, min: 0, max: 20 },
        pinch: { type: 'float', val: .2, min: 0, max: 2 },
        copies: { type: 'int', val: 1, min: 0, max: 5 },
        length: { type: 'float', val: 1, min: 0, max: 5 },
        rotate: { type: 'adjust', val: 2.1 },
        zoom: { type: 'ratio' },
        fade: { type: 'float', val: .2, min: 0, max: 1 },
        width: { type: 'ratio' },
        count: { type: 'ratio' },
        color: { type: 'adjust', val: 2 },
        spread: { type: 'adjust', val: 4 },
        speed: { type: 'ratio' },
        dir: { type: 'dir' }
    };
    this.settings = config.get(defaults);
    this.settings.color *= 180;
    this.settings.count = Math.round(this.settings.count * 17);
    this.maxAngle = 1;
    this.settings.spread *= 180;
    this.settings.length = Math.round(20 * this.settings.length) + 2;
    this.settings.spiral *= .5;
    this.settings.fade = Math.pow(this.settings.fade, 2);
    this.copyAngle = this.settings.copies > 0 ? TAU / (this.settings.copies + 1) : 0;
    this.fadeCol = new Color("#000000");
    this.pinchBase = this.settings.pinch;
    this.pinchScale = 1 - this.settings.pinch;
    this.lines = [];
    this.update = function (time, diff) {
        let ctx = t.context,
            speed = time * t.settings.speed * t.settings.dir,
            rotate = time * t.settings.rotate * 2,
            cTime = time * t.settings.color;
        t.canvas.setRotation(1, 0);
        t.canvas.fill(t.fadeCol.toRgba(this.settings.fade));
        t.canvas.style('lighter');

        let p, cur, angle, col, r;
        for (let i = 0; i < t.settings.count; i++) {
            cur = i / t.settings.count;
            angle = cur * t.maxAngle + rotate;
            p = new Point(0, 0);
            p.move(.4, speed * t.settings.in - angle);
            p.move(.6, - speed * t.settings.out - angle + HPI);
            t.lines[i].addPoint(p);
        }
        for (let i = 0; i < t.settings.count; i++) {
            cur = i / t.settings.count;
            r = t.pinchBase + t.pinchScale * cur;
            col = getIndex(t.colorList, cur).adjustHsl(cTime + cur * t.settings.spread, 0, 0);
            ctx.strokeStyle = col.toRgba(.5);
            ctx.beginPath();
            t.lines[i].draw(ctx, t.pos.radius * r);
            ctx.stroke();
        }

        t.canvas.style();
        t.canvas.setRotation(1 + Math.pow(this.settings.zoom, 2) * diff * .8, t.copyAngle);
        // t.canvas.setRotation(1, t.copyAngle);
        t.canvas.selfCopy();
    };
    this.resize = function (width, height) {
        t.canvas.resize(width, height);
        t.pos.radius = t.pos.dist * .5;
        t.context.lineWidth = t.pos.dist * .01 * t.settings.width;
    };
    this.init = function () {
        for (var i = 0; i < t.settings.count; i++) {
            this.lines.push(new LineDrawer(t.settings.length));
        }
        if (t.settings.in === 0 && t.settings.out === 0) {
            t.settings.in = 1;
        }
        t.findMaxAngle();
        console.log(t.settings.in, t.settings.out);
    }
    this.findMaxAngle = function () {
        let common = getCommonDenominator(t.settings.in, t.settings.out);
        let loops = Math.round(t.settings.in / common + t.settings.out / common);
        this.maxAngle = TAU / loops;
    }
    this.init();
}

class LineDrawer {
    constructor(length) {
        this.index = -1;
        this.length = length;
        this.points = new Array(length);
    }
    addPoint(p) {
        this.index = (this.index + 1) % this.length;
        this.points[this.index] = p;
    }
    draw(ctx, radius) {
        for (let i = 0; i < this.length; i++) {
            let index = this.index - i;
            if (index < 0) {
                index += this.length;
            }
            let p = this.points[index];
            if (!p) {
                continue;
            }
            p = p.clone().multiply(radius);
            if (i == 0) {
                ctx.moveTo(p.x, p.y);
            } else {
                ctx.lineTo(p.x, p.y);
            }
        }
    }
}

function getCommonDenominator(a, b) {
    // Get our two input numbers.
    a = Math.abs(a);
    b = Math.abs(b);
    // Make sure a is always the higher number.
    if (b > a) { let temp = a; a = b; b = temp; }
    let max = b;
    // Never iterate more than the smallest number.
    for (let i = 0; i < max; i++) {
        if (b == 0) return a;
        a %= b;
        if (a == 0) return b;
        b %= a;
    }
    // No common one found, so 1.
    return 1;
}
    var render = new Render(document.getElementById('canvas'), ["#880000","#880000","#870000","#870000","#860000","#860000","#860000","#850000","#850000","#840000","#840000","#840000","#830000","#830000","#820000","#820000","#820000","#810000","#810000","#800000","#800000","#800000","#7f0000","#7f0000","#7e0000","#7e0000","#7d0000","#7d0000","#7d0000","#7c0000","#7c0000","#7b0000","#7b0000","#7b0000","#7a0000","#7a0000","#790000","#790000","#780000","#780000","#780000","#770000","#770000","#760000","#760000","#760000","#750000","#750000","#740000","#740000","#730000","#730000","#720000","#720000","#720000","#710000","#710000","#700000","#700000","#6f0000","#6f0000","#6f0000","#6e0000","#6e0000","#6d0000","#6d0000","#6c0000","#6c0000","#6b0000","#6b0000","#6b0000","#6a0000","#6a0000","#690000","#690000","#680000","#680000","#670000","#670000","#670000","#660000","#660000","#650000","#650000","#640000","#640000","#630000","#630000","#620000","#620000","#610000","#610000","#600000","#600000","#600000","#5f0000","#5f0000","#5e0000","#5e0000","#5d0000","#5d0000","#5c0000","#5c0000","#5b0000","#5b0000","#5a0000","#5a0000","#590000","#590000","#580000","#580000","#570000","#570000","#560000","#560000","#550000","#550000","#540000","#540000","#530000","#530000","#520000","#520000","#510000","#510000","#500000","#500000","#4f0000","#4f0000","#4e0000","#4e0000","#4d0000","#4d0000","#4c0000","#4c0000","#4b0000","#4a0000","#4a0000","#490000","#490000","#480000","#480000","#470000","#470000","#460000","#460000","#450000","#440000","#440000","#430000","#430000","#420000","#420000","#410000","#400000","#400000","#3f0000","#3f0000","#3e0000","#3e0000","#3d0000","#3c0000","#3c0000","#3b0000","#3b0000","#3a0000","#390000","#390000","#380000","#370000","#370000","#360000","#360000","#350000","#340000","#340000","#330000","#320000","#320000","#310000","#300000","#300000","#2f0000","#2e0000","#2e0000","#2d0000","#2c0000","#2c0000","#2b0000","#2a0000","#2a0000","#290000","#280000","#270000","#270000","#260000","#250000","#240000","#240000","#230000","#220000"], ["#880000","#220000"]);
    resize = render.resize.bind(render);

    function perFrame(time, diff) {
        words.update();
        render.update(time, diff);
    }
    intro(words.words, function () {
        nimja.callResize();
        nanimate(animate);
    });
</script>
    


</body></html>