What's the code for the circle drawing feature on the "project loading" screen?

On the “project loading” screen, if you move your mouse around, it draws circles in a random color. What is the code for that and how do I implement it?

here’s the code:

html

<canvas id="background"/>

javascript

var canvas, context, canvasImage;

var cursorPosition = {
  x: undefined,
  y: undefined,
};
var color = '#e5e5e5';
var size = 30;

function randomColor() {
  var colors = [
    '#fcd1c4',
    '#abfcec',
    '#a3d9e1',
    '#fbbfff',
    '#a9ef8f',
    '#fff0b2',
    '#fff0b2',
  ];
  color = colors[Math.floor(Math.random() * colors.length)];
}

function throttle(ms, fn) {
  var lastCallTime;
  return function () {
    var now = Date.now();
    if (!lastCallTime || now - lastCallTime > ms) {
      lastCallTime = now;
      fn.apply(this, arguments);
    }
  }
}

function drawCircle(event) {
  context.beginPath();
  context.arc(cursorPosition.x, cursorPosition.y, size, 0, 2 * Math.PI);
  context.closePath();
  context.fillStyle = color;
  context.fill();
  canvasImage = context.getImageData(0, 0, window.innerWidth, window.innerHeight);
}

window.onload = function () {
  randomColor();
  canvas = document.getElementById('background');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  context = canvas.getContext('2d');

  window.onresize = throttle(100, function () {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    context.clearRect(0,0, window.innerWidth, window.innerHeight);
    canvasImage && context.putImageData(canvasImage, 0, 0);
  });

  window.onmousemove = throttle(10, function (event) {
    cursorPosition = {
      x: event.clientX,
      y: event.clientY,
    };
    drawCircle(event);
  });

  window.ontouchmove = throttle(10, function (event) {
    cursorPosition = {
      x: event.touches[0].clientX,
      y: event.touches[0].clientY,
    };
    drawCircle(event);
  });
}

@_tr Where do I put the canvas? when i put it above the code it blocks out everything.

1 Like

Something like this:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title></title>
	</head>
	<body>
		<canvas id="background"/> <!-- Right here -->

		<script>
/*
	JS code
*/
		</script>
	</body>
</html>
1 Like

And does the actual site functionality go between the canvas and script, or after?

What do you mean by “site functionality”?
Like the HTML code inside the site?

If you’re wanting to have the circle drawing for the background of a site, you’ll need to set it’s z-index to go behind the content:

<head>
    <!-- Previous head code -->
    <style>
#background {
    z-index: -1; /* Draw behind content */
    position: absolute; /* Allow other elements to take up the same space */
/* Optional - Makes it fill the whole screen.
    left: 0;
    right: 0;
    width: 100vw;
    height: 100vh;
*/
}
    </style>
</head>

Hope this helps!

Sorry, I worded it wrong. But yes, the actual HTML code of the site.

You should be able to just add it into the body. Doesn’t matter where as long as you have the style I gave in the above post.

@Haizlbliek For some reason it just covers everything, nothing else shows up. Here’s the site I’m trying on, in case you need it:

index.hbs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>{{seo.title}}</title>
  <link rel="canonical" href="{{seo.url}}" />
  <meta name="description" content="{{seo.description}}" />
  <meta property="og:title" content="{{seo.title}}" />
  <meta property="og:type" content="article" />
  <meta property="og:url" content="{{seo.url}}" />
  <meta property="og:description" content="{{seo.description}}" />
  <meta property="og:image" content="{{seo.image}}" />
  <meta name="twitter:card" content="summary" />
  <link rel="stylesheet" href="/style.css" />
  <link rel="apple-touch-icon" sizes="180x180" href="path-to-your-icon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="path-to-your-icon.png">
  
   <style>
#background {
    z-index: -1; /* Draw behind content */
    position: absolute; /* Allow other elements to take up the same space */
/* Optional - Makes it fill the whole screen.
    left: 0;
    right: 0;
    width: 100vw;
    height: 100vh;
  */
}
    </style>
</head>

<body>
  <canvas id="background"/>
    <div class="wrapper">
      <div class="content" role="main">
        <h1>ping//pong!</h1>
        <p>Simple chatroom using a {{seo.db}} database. Say hi when you show up!</p>

        <!-- Username form -->
        <h2>Set Your Username</h2>
        <input type="text" id="username" placeholder="Enter your username" required>
        <button id="save-username">Save Username</button>
        <br/><br/>

        <!-- Button to request notification permission -->
        <button id="enable-notifications">Enable Notifications</button>

        <p id="status-message"></p>
      </div>
    </div>

    <!-- Footer -->
    <footer class="footer">
      <a href="/">Home</a> | <a href="/admin">Admin</a>
      <a href="https://glitch.com/edit/#!/remix/glitch-hello-sqlite">Remix on Glitch</a>
    </footer>

  <script>
    // Function to set a cookie
    function setCookie(name, value, days) {
      const expires = new Date(Date.now() + days * 864e5).toUTCString();
      document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=/';
    }

    // Function to get a cookie
    function getCookie(name) {
      return document.cookie.split('; ').find(row => row.startsWith(name + '='))?.split('=')[1];
    }

    // Save username to cookie when button is clicked
    document.getElementById("save-username").addEventListener("click", function () {
      const username = document.getElementById("username").value;
      if (username) {
        setCookie("username", username, 7); // Save for 7 days
        document.getElementById("status-message").textContent = "Username saved!";
      }
    });

    // Request notification permission on button click
    document.getElementById("enable-notifications").addEventListener("click", function () {
      if ("Notification" in window) {
        Notification.requestPermission().then(permission => {
          if (permission === "granted") {
            document.getElementById("status-message").textContent = "Notifications enabled!";
          } else {
            document.getElementById("status-message").textContent = "Notifications denied.";
          }
        });
      }
    });

    // Check for username and notification permission on page load
    window.onload = function () {
      const username = getCookie("username");
      if (username && Notification.permission === "granted") {
        window.location.href = "/chat"; // Redirect to chat.hbs
      }
    };
    
    
    var canvas, context, canvasImage;

var cursorPosition = {
  x: undefined,
  y: undefined,
};
var color = '#e5e5e5';
var size = 30;

function randomColor() {
  var colors = [
    '#fcd1c4',
    '#abfcec',
    '#a3d9e1',
    '#fbbfff',
    '#a9ef8f',
    '#fff0b2',
    '#fff0b2',
  ];
  color = colors[Math.floor(Math.random() * colors.length)];
}

function throttle(ms, fn) {
  var lastCallTime;
  return function () {
    var now = Date.now();
    if (!lastCallTime || now - lastCallTime > ms) {
      lastCallTime = now;
      fn.apply(this, arguments);
    }
  }
}

function drawCircle(event) {
  context.beginPath();
  context.arc(cursorPosition.x, cursorPosition.y, size, 0, 2 * Math.PI);
  context.closePath();
  context.fillStyle = color;
  context.fill();
  canvasImage = context.getImageData(0, 0, window.innerWidth, window.innerHeight);
}

window.onload = function () {
  randomColor();
  canvas = document.getElementById('background');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  context = canvas.getContext('2d');

  window.onresize = throttle(100, function () {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    context.clearRect(0,0, window.innerWidth, window.innerHeight);
    canvasImage && context.putImageData(canvasImage, 0, 0);
  });

  window.onmousemove = throttle(10, function (event) {
    cursorPosition = {
      x: event.clientX,
      y: event.clientY,
    };
    drawCircle(event);
  });

  window.ontouchmove = throttle(10, function (event) {
    cursorPosition = {
      x: event.touches[0].clientX,
      y: event.touches[0].clientY,
    };
    drawCircle(event);
  });
}
  </script>
</body>
</html>

Try replacing
<canvas id="background"/>
with
<canvas id="background"></canvas>

It isn’t recognising the ending /, and ends up grouping all other nodes into the background canvas

I’d also recommend putting in the optional styling, it’ll make it fit together nicer.

Perfect, it works now! Thanks a lot!

2 Likes