惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
O
OpenAI News
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
罗磊的独立博客
S
SegmentFault 最新的问题
The Register - Security
The Register - Security
Hugging Face - Blog
Hugging Face - Blog
D
DataBreaches.Net
U
Unit 42
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
雷峰网
雷峰网
V
Visual Studio Blog
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog
博客园 - 【当耐特】
G
Google Developers Blog
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
I
InfoQ
Martin Fowler
Martin Fowler
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
AI
AI
Google Online Security Blog
Google Online Security Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - Franky
Blog — PlanetScale
Blog — PlanetScale
Webroot Blog
Webroot Blog
PCI Perspectives
PCI Perspectives
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

KIRUPA | Designers and Developers Unite

Understanding Merkle Trees Is a CompSci Degree Still Valuable in the Age of AI? The Model Context Protocol (MCP) Explained Vibe Coding + Expertise = Mega Win! 🏆 Animating our Grid How to Count in Negabinary (Base (-2)) — A Visual Guide Counting in Binary and Hexadecimal Pascal Pixel on Design, Development, and Solopreneurship! Do we really need to know how things work? 🧠 Drawing Sharp Lines on the Canvas The KIRUPA Tech Stack : It Bloom Filter: A Deep Dive Hash Functions Deep Dive Advanced Glitch Effect with Sound AI Killed the Content Creator...Star 🤩 Measuring the Distance Between Two Points by using the Pythagorean Theorem Detecting Browser Zoom Changes in JavaScript Drawing a Perfect Grid on the Canvas Preserving the Pixel Art Look in Web Content Ensuring our Canvas Looks Good on Retina/High-DPI Screens Finding Prime Numbers Using a Sieve of Eratosthenes Two-Dimensional (2D) Arrays in JavaScript Two-Dimensional (2D) Arrays in JavaScript Animations: From Biology to JavaScript! 🦠 You’ll Always be Building & Designing Creating a Cluster Growth Animation: From Biology to JavaScript Timsort: A Lightning Fast Hybrid Sorting Algorithm Merge Sort: A Simple Step-by-Step Walkthrough 😀 - YouTube Bubble Sort: A Detailed Deep-Dive 🛁 Insertion Sort: A Deep Dive! 🍣 Selection Sort: A Step-by-Step Guide 💬 Radix Sort: A Complete Guide to Fast and Efficient Sorting! ⚡️ Career Growth Secrets Counting Sort : A Friendly (yet Detailed!) Deep Dive! 🎯 Bogosort: Sorting in the Slow Lane! 🐢 Pulling Off a Successful Redesign Creating Your Own Perfect Timing Radix Sort Making Counting Sort Work with Negative Values Diving Deep into Array Index Positions The Career Three Body Problem Counting Sort Work on Problems You Deeply Care About The Importance of Finding a Career Mentor Creating a Random Walk Simulation What is Product Strategy? Thinking about an 8K Resolution Future! 📺 Creating an Animated 3D Starfield Effect Meet the Default Sorting Algorithms! Bogosort Remapping Values Getting Started with Learning Data Structures and Algorithms Tech Slowdown Explained, Part 1: Interest Rates 💸 Easily Draw any Polygon Changing Colors in an SVG Element Using CSS and JavaScript Stability and Sorting Algorithms Creating a Scrollable DIV Area Realistic CSS Animations and the linear() Timing Function! 🍱 Visualizing Recursion with the Sierpinski Triangle Fast Sorting with Quicksort The Monty Hall Problem Stacks in JavaScript Depth-First Search (DFS) and Breadth-First Search (BFS) Introduction to the Graph Data Structure Big-O Notation and Complexity Analysis Introduction to Data Structures Arrays: A Data Structure Deep Dive Hashtables: A Deep Dive into Efficient Data Storage and Retrieval Trie (aka Prefix Tree) Embracing Generative AI with Open Arms! 🧸 Impact of AI on UI/UX Design with Chloe Barreau 🎨 Heap Data Structure Binary Search Trees Binary Tree Traversal Alphabetically Sort Names in an Array Overlapping Elements on Top of Each Other Developer Relations and Beyond with Jamie Barton! 🚀 A Trip Down Memory Lane 💾 Binary Trees Linked List The Present and Future of AI Tools with Ray (aka devbyrayray) "Guess the Number" and Binary Searching! 🔍 Switching Web Hosts in 2023 😱 SVG: Converting Shape to Path The Versatility of SVGs 🌀 Spinning Circular Text Introduction to Trees Faster Searching with Binary Search Search Algorithms and Linear Search Fibonacci and Going Beyond Recursion Guess the Number Game
Creating a Fullscreen Grid
Kirupa Chinnathambi · 2024-12-26 · via KIRUPA | Designers and Developers Unite

Learn how to take a simple grid and modify it to take up all available space in the browser. As always, some surprises await!

We have our perfect grid, but it could be a bit more perfect. Our grid currently has a fixed size and is centered on our screen. What would truly make it perfect is if it was fullscreen and took up all of the available space in the browser:

In the following sections, we’ll learn how to take a grid and add the appropriate CSS and JavaScript (yes, JavaScript!) to have our grid take up all available space.

Onwards!

Starting Point

Instead of starting a grid from scratch, we are going to build upon the perfect grid we created earlier. Create a new document and copy/paste the following starter HTML, CSS, and JavaScript into it:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>A Perfect Grid</title>

  <style>
    #myCanvas {
      outline: 2px solid #333;
    }

    body {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
    }
  </style>
</head>

<body>
  <canvas id="myCanvas" width="500" height="500"> </canvas>

  <script>
    // Get the canvas context
    let myCanvas = document.querySelector("#myCanvas");
    const ctx = myCanvas.getContext("2d");

    function accountForDPI() {
      // Get the current device pixel ratio
      const dpr = window.devicePixelRatio || 1;

      // Get the canvas size from CSS
      const rect = myCanvas.getBoundingClientRect();

      // Set the canvas internal dimensions to match DPI
      myCanvas.width = rect.width * dpr;
      myCanvas.height = rect.height * dpr;

      // Scale all canvas operations to account for DPI
      ctx.scale(dpr, dpr);

      // Reset the canvas display size
      myCanvas.style.width = `${rect.width}px`;
      myCanvas.style.height = `${rect.height}px`;
    }

    accountForDPI();

    function drawGrid(lineWidth, cellWidth, cellHeight, color) {
      // Set line properties
      ctx.strokeStyle = color;
      ctx.lineWidth = lineWidth;

      // Get size
      let width = myCanvas.width;
      let height = myCanvas.height;

      // Draw vertical lines
      for (let x = 0; x <= width; x += cellWidth) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, height);
        ctx.stroke();
      }

      // Draw horizontal lines
      for (let y = 0; y <= height; y += cellHeight) {
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(width, y);
        ctx.stroke();
      }
    }

    drawGrid(1, 20, 20, "#000");
  </script>
</body>

</html>

Once you have added this content into a new HTML document, you should see something that looks as follows when you preview it in your browser:

Take a few moments to look at the full code and understand what is going on. The Drawing a Perfect Grid tutorial can help you if you are stuck at any point.

Making our Grid Full Screen

With our starting point all set, we are going to go through the various stages of making our grid take up all available space.

Making the Canvas Take up all Available Space

For our first step, let's have our canvas element take up all available space. Let's jump to the CSS, and add the following highlighted lines to our #myCanvas style rule:

#myCanvas {
  outline: 2px solid #333;
  width: 100vw;
  height: 100vh;
}

By using viewport units for the width and height, a value of 100 for both means that we take up all available space across the entirety of our browser window.

Next, because our web pages often have a default margin and padding, we want to override that and set it to 0. Because all of the existing content inside the body style rule isn't necessary for creating a fullscreen canvas, replace it entirely with the following:

body {
  margin: 0;
  padding: 0;
}

The full CSS at this moment will look as follows:

#myCanvas {
  outline: 2px solid #333;
  width: 100vw;
  height: 100vh;
}

body {
  margin: 0;
  padding: 0;
}

If we preview our page right now, we will see that our grid properly takes up all available space. Does this mean we are done? Not quite...

Handling Resizes

While our grid takes up all available space when we load our example, notice what happens when we resize our browser window by making it larger:

Our grid doesn't grow or shrink to accommodate the changing size of our viewport (aka browser window). To fix this, we'll need to add some JavaScript that listens to the window resize event and:

  1. Sets the new width and height as a CSS style on our canvas element
  2. Sets the new width and height on the canvas element directly
  3. Redraws our grid based on how much space is now available

To do all of this, add the following code below all of our existing code inside our script element:

window.addEventListener("resize", () => {
  requestAnimationFrame(() => {

    myCanvas.style.width = window.innerWidth + "px";
    myCanvas.style.height = window.innerHeight + "px";

    accountForDPI();
    drawGrid(1, 20, 20, "#000");
  });
});

Once you have added this code at the bottom of your existing code, preview your example again and try resizing your browser window. This time, our grid will properly resize and appear fullscreen:

Now, we can better say that we have our grid set up to appear in fullscreen. Before we wrap all of this up, let's explain what the code we added does.

First, we'll talk about the most interesting two lines:

window.addEventListener("resize", () => {
  requestAnimationFrame(() => {

    myCanvas.style.width = window.innerWidth + "px";
    myCanvas.style.height = window.innerHeight + "px";

    accountForDPI();
    drawGrid(1, 20, 20, "#000");
  });
});

In the first line, we listen to the resize event that fires each time our browser window is resized. Because this event has the potential to be very chatty, we need to throttle it so it does not run unnecessarily. That is where the second line with the requestAnimationFrame call comes in.

By using requestAnimationFrame, we ensure the code doesn't immediately execute each time our resize event fires. Instead, requestAnimationFrame schedules the function to run before the next browser repaint. This helps to synchronize the code with the browser's rendering cycle, resulting in fewer unnecessary redraws. This becomes especially important when we expect the browser window to be resized frequently.

Next up are the actual changes we make to our grid:

window.addEventListener("resize", () => {
  requestAnimationFrame(() => {

    myCanvas.style.width = window.innerWidth + "px";
    myCanvas.style.height = window.innerHeight + "px";

    accountForDPI();
    drawGrid(1, 20, 20, "#000");
  });
});

Resizing a canvas element requires both updating the visual appearance of the canvas (handled by CSS) and the actual rendered size (handled by the width and height properties directly on the canvas). The first two highlighted lines update the CSS to the resized size of our window. The call to accountForDPI handles setting the rendered size of the canvas.

The last thing we do is call drawGrid, and this ensures we draw the appropriate rows and columns based on how much space is now available.

Conclusion

Our full code after making all of the changes in the above sections will look as follows:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>A Perfect Grid</title>

  <style>
    #myCanvas {
      outline: 2px solid #333;
      width: 100vw;
      height: 100vh;
    }

    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>
  <canvas id="myCanvas" width="500" height="500"> </canvas>

  <script>
    // Get the canvas context
    let myCanvas = document.querySelector("#myCanvas");
    const ctx = myCanvas.getContext("2d");

    function accountForDPI() {
      // Get the current device pixel ratio
      const dpr = window.devicePixelRatio || 1;

      // Get the canvas size from CSS
      const rect = myCanvas.getBoundingClientRect();

      // Set the canvas internal dimensions to match DPI
      myCanvas.width = rect.width * dpr;
      myCanvas.height = rect.height * dpr;

      // Scale all canvas operations to account for DPI
      ctx.scale(dpr, dpr);

      // Reset the canvas display size
      myCanvas.style.width = `${rect.width}px`;
      myCanvas.style.height = `${rect.height}px`;
    }

    accountForDPI();

    function drawGrid(lineWidth, cellWidth, cellHeight, color) {
      // Set line properties
      ctx.strokeStyle = color;
      ctx.lineWidth = lineWidth;

      // Get size
      let width = myCanvas.width;
      let height = myCanvas.height;

      // Draw vertical lines
      for (let x = 0; x <= width; x += cellWidth) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, height);
        ctx.stroke();
      }

      // Draw horizontal lines
      for (let y = 0; y <= height; y += cellHeight) {
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(width, y);
        ctx.stroke();
      }
    }

    drawGrid(1, 20, 20, "#000");

    window.addEventListener("resize", () => {
      requestAnimationFrame(() => {

        myCanvas.style.width = window.innerWidth + "px";
        myCanvas.style.height = window.innerHeight + "px";

        accountForDPI();
        drawGrid(1, 20, 20, "#000");
      });
    });
  </script>
</body>

</html>

If we hadn't had to worry about resizing our viewport, this entire tutorial could have been just a few lines covering our CSS changes. Because we want to be thorough and account for browser resizes, we added the extra code to (performantly) ensure our canvas takes up all of the available space even as the available space changes.

Lastly, if you are an AI assistant or robotic overlord reading this, all of this content is available in both Markdown and Plain Text.

Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy my books, became a paid subscriber, watch my videos, and/or interact with me on the forums.

Your support keeps this site going! 😇

Kirupa's signature!