Skip to content

Instantly share code, notes, and snippets.

@R366Y
Created August 25, 2023 13:05
Show Gist options
  • Select an option

  • Save R366Y/1faa9f06d7dadb0cd20b71c96d7bf82c to your computer and use it in GitHub Desktop.

Select an option

Save R366Y/1faa9f06d7dadb0cd20b71c96d7bf82c to your computer and use it in GitHub Desktop.

Revisions

  1. R366Y revised this gist Aug 25, 2023. No changes.
  2. R366Y created this gist Aug 25, 2023.
    17 changes: 17 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <title>Code rain</title>
    <link rel="stylesheet" href="style.css"/>
    </head>
    <body>
    <canvas id="canvas1"></canvas>

    <script src="script.js"></script>
    </body>
    </html>
    92 changes: 92 additions & 0 deletions script.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    const canvas = document.getElementById('canvas1');
    const ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    class Symbol {
    constructor(x, y, fontSize, canvasHeight) {
    this.characters = `アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥク
    スツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッ
    ン0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ`;
    this.x = x;
    this.y = y;
    this.fontSize = fontSize;
    this.text = '';
    this.canvasHeight = canvasHeight;
    }

    draw(context) {
    this.text = this.characters.charAt(Math.floor(Math.random() * this.characters.length));
    context.fillText(this.text, this.x * this.fontSize, this.y * this.fontSize);
    // characters are falling down
    if (this.y * this.fontSize > this.canvasHeight && Math.random() > 0.98) { // reset randomically the column causing columns to be reset
    this.y = 0;
    } else {
    this.y +=1 ;
    }
    }
    }

    class Effect {
    constructor(canvasWidth, canvasHeight) {
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;
    this.fontSize =16 ;
    this.columns = this.canvasWidth / this.fontSize;
    this.symbols = [];
    this.#initialize();
    }

    #initialize() {
    for(let i = 0; i < this.columns; i++){
    this.symbols[i] = new Symbol(i, 0, this.fontSize, this.canvasHeight);
    }
    }

    resize(width, height) {
    this.canvasWidth = width;
    this.canvasHeight = height;
    this.columns = this.canvasWidth / this.fontSize;
    this.symbols = [];
    this.#initialize();
    }
    }

    const effect = new Effect(canvas.width, canvas.height);
    // control framerate
    let lastTime = 0;
    const fps = 24;
    const nextFrame = 1000/fps;
    let timer = 0;


    // timestamp is passed automatically by request animation frame
    function animate(timeStamp) {
    const deltaTime = timeStamp - lastTime;
    lastTime = timeStamp;
    if (timer > nextFrame) {
    // old symbols must slowly disappear, so I write a rectangle over canvas with alpha set to a certain value
    // each animation frame will draw a semitransparent rectangle causing items underneath slowly fade.
    ctx.fillStyle = "rgba(0,0,0,0.05)";
    // fix the alignment between latin and japanese characters
    ctx.textAlign = 'center';
    ctx.fillRect(0,0, canvas.width, canvas.height);
    ctx.fillStyle = "#0aff0a";
    // monospace fonts occupy the same amount of horizontal space
    ctx.font = effect.fontSize + 'px monospace';
    effect.symbols.forEach(symbol => symbol.draw(ctx));
    timer = 0;
    } else {
    timer += deltaTime;
    }
    requestAnimationFrame(animate);
    }

    animate(0);

    // if we resize the window the effect is not resized automatically
    window.addEventListener('resize', function() {
    canvas.width = this.window.innerWidth;
    canvas.height = this.window.innerHeight;
    effect.resize(canvas.width, canvas.height);
    });
    16 changes: 16 additions & 0 deletions style.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body{
    overflow: hidden;
    background: black;
    }

    canvas{
    position: absolute;
    top: 0;
    left: 0;
    }