{"id":72,"date":"2026-07-08T19:12:26","date_gmt":"2026-07-08T11:12:26","guid":{"rendered":"http:\/\/www.olentaqua.com\/blog\/?p=72"},"modified":"2026-07-08T19:12:26","modified_gmt":"2026-07-08T11:12:26","slug":"how-to-draw-a-voronoi-diagram-on-a-canvas-43bf-a6ab39","status":"publish","type":"post","link":"http:\/\/www.olentaqua.com\/blog\/2026\/07\/08\/how-to-draw-a-voronoi-diagram-on-a-canvas-43bf-a6ab39\/","title":{"rendered":"How to draw a Voronoi diagram on a Canvas?"},"content":{"rendered":"<p>Hey there, art enthusiasts and fellow tech lovers! I&#8217;m super stoked to share this in &#8211; depth guide on how to draw a Voronoi diagram on a Canvas. And a little about me, I&#8217;m from a Canvas supplier, and I&#8217;ve been on this amazing journey exploring the countless possibilities of Canvas. <a href=\"https:\/\/www.shengruntextile.com\/fabric\/canvas\/\">Canvas<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shengruntextile.com\/uploads\/201817142\/small\/tablecloth-with-velvet-fabric-for-dining-room27555608095.jpg\"><\/p>\n<h3>What&#8217;s a Voronoi Diagram Anyway?<\/h3>\n<p>Before we jump into the nitty &#8211; gritty of drawing, let&#8217;s quickly chat about what a Voronoi diagram is. It&#8217;s a really cool mathematical construct that divides a plane into regions based on the distance to a set of points. Each region, or cell, is made up of all the points that are closer to a specific &quot;seed&quot; point than to any other. Think of it like a bunch of neighborhoods, where each house belongs to the neighborhood whose center (the seed point) is closest.<\/p>\n<p>Voronoi diagrams have a ton of real &#8211; world applications. You can see them in things like mapping out cell phone tower coverage areas, analyzing crystal growth patterns, and even in cool graphic designs.<\/p>\n<h3>Why Use Canvas?<\/h3>\n<p>Canvas is the bomb when it comes to creating graphics on the web. It&#8217;s super flexible and gives you direct control over every single pixel on the screen. Unlike SVG, which is more about defining shapes with XML, Canvas is all about painting and drawing dynamically. You can animate, change colors on the fly, and create some seriously eye &#8211; popping visual effects.<\/p>\n<p>As a Canvas supplier, I&#8217;ve seen firsthand how it can take a simple web page and turn it into a visual masterpiece. Whether you&#8217;re a web developer looking to add some flair to your site or an artist wanting to showcase your work online, Canvas has got you covered.<\/p>\n<h3>Getting Started<\/h3>\n<p>First things first, you need to set up your HTML file. Create a basic HTML structure with a <code>&lt;canvas&gt;<\/code> element. Here&#8217;s a quick example:<\/p>\n<pre><code class=\"language-html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n\n&lt;head&gt;\n    &lt;meta charset=&quot;UTF - 8&quot;&gt;\n    &lt;meta name=&quot;viewport&quot; content=&quot;width=device - width, initial - scale=1.0&quot;&gt;\n    &lt;title&gt;Voronoi Diagram on Canvas&lt;\/title&gt;\n&lt;\/head&gt;\n\n&lt;body&gt;\n    &lt;canvas id=&quot;myCanvas&quot; width=&quot;800&quot; height=&quot;600&quot;&gt;&lt;\/canvas&gt;\n    &lt;script src=&quot;script.js&quot;&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n\n&lt;\/html&gt;\n<\/code><\/pre>\n<p>In this code, we&#8217;ve set up a canvas with an ID of <code>myCanvas<\/code> and given it a width of 800 pixels and a height of 600 pixels. The <code>script.js<\/code> file is where we&#8217;ll write all our JavaScript code to draw the Voronoi diagram.<\/p>\n<h3>Generating Seed Points<\/h3>\n<p>The next step is to generate some seed points. These are the points that will define the regions of our Voronoi diagram. You can generate them randomly within the bounds of the canvas.<\/p>\n<pre><code class=\"language-javascript\">\/\/ Get the canvas element and its 2D context\nconst canvas = document.getElementById('myCanvas');\nconst ctx = canvas.getContext('2d');\n\n\/\/ Number of seed points\nconst numPoints = 20;\n\n\/\/ Array to store the seed points\nconst points = [];\n\n\/\/ Generate random points within the canvas bounds\nfor (let i = 0; i &lt; numPoints; i++) {\n    const x = Math.random() * canvas.width;\n    const y = Math.random() * canvas.height;\n    points.push({ x, y });\n}\n<\/code><\/pre>\n<p>In this code, we first get the canvas element and its 2D context. Then we decide on the number of seed points we want (in this case, 20). We create an empty array to store the points and then use a <code>for<\/code> loop to generate random <code>x<\/code> and <code>y<\/code> coordinates within the canvas bounds. Each point is an object with <code>x<\/code> and <code>y<\/code> properties, and we push these objects into the <code>points<\/code> array.<\/p>\n<h3>Calculating Voronoi Regions<\/h3>\n<p>Now comes the tricky part &#8211; calculating the Voronoi regions. There are a few algorithms out there to do this, but one of the most common is the Fortune&#8217;s algorithm. However, for simplicity, we&#8217;ll use a brute &#8211; force approach that works well for a small number of points.<\/p>\n<p>The idea behind the brute &#8211; force approach is to loop through every pixel on the canvas and calculate the distance to each seed point. The pixel will then belong to the region of the closest seed point.<\/p>\n<pre><code class=\"language-javascript\">\/\/ Loop through every pixel on the canvas\nfor (let x = 0; x &lt; canvas.width; x++) {\n    for (let y = 0; y &lt; canvas.height; y++) {\n        let minDistance = Infinity;\n        let closestPointIndex = 0;\n\n        \/\/ Calculate the distance to each seed point\n        for (let i = 0; i &lt; points.length; i++) {\n            const dx = x - points[i].x;\n            const dy = y - points[i].y;\n            const distance = Math.sqrt(dx * dx + dy * dy);\n\n            if (distance &lt; minDistance) {\n                minDistance = distance;\n                closestPointIndex = i;\n            }\n        }\n\n        \/\/ Set the color based on the closest seed point\n        ctx.fillStyle = getColorForPoint(closestPointIndex);\n        ctx.fillRect(x, y, 1, 1);\n    }\n}\n\n\/\/ Function to get a color for each seed point\nfunction getColorForPoint(index) {\n    const colors = [\n        'red', 'blue', 'green', 'yellow', 'orange', 'purple',\n        'pink', 'brown', 'cyan', 'magenta'\n    ];\n    return colors[index % colors.length];\n}\n<\/code><\/pre>\n<p>In this code, we have two nested <code>for<\/code> loops to iterate through every pixel on the canvas. For each pixel, we calculate the distance to each seed point using the Pythagorean theorem. We keep track of the minimum distance and the index of the closest seed point.<\/p>\n<p>The <code>getColorForPoint<\/code> function is used to assign a color to each Voronoi region. It simply cycles through an array of colors based on the index of the closest seed point. Then we use <code>ctx.fillRect<\/code> to fill each pixel with the appropriate color.<\/p>\n<h3>Adding Some Style<\/h3>\n<p>Our Voronoi diagram looks pretty basic right now. Let&#8217;s add some style to make it stand out. We can add outlines to the regions, change the colors, or even add some transparency.<\/p>\n<pre><code class=\"language-javascript\">\/\/ Draw outlines for each region\nfor (let x = 0; x &lt; canvas.width; x++) {\n    for (let y = 0; y &lt; canvas.height; y++) {\n        let minDistance = Infinity;\n        let closestPointIndex = 0;\n\n        \/\/ Calculate the distance to each seed point\n        for (let i = 0; i &lt; points.length; i++) {\n            const dx = x - points[i].x;\n            const dy = y - points[i].y;\n            const distance = Math.sqrt(dx * dx + dy * dy);\n\n            if (distance &lt; minDistance) {\n                minDistance = distance;\n                closestPointIndex = i;\n            }\n        }\n\n        \/\/ Check if the pixel is on the border\n        if (isBorderPixel(x, y, closestPointIndex)) {\n            ctx.strokeStyle = 'black';\n            ctx.beginPath();\n            ctx.moveTo(x, y);\n            ctx.lineTo(x + 1, y);\n            ctx.stroke();\n        }\n    }\n}\n\n\/\/ Function to check if a pixel is on the border\nfunction isBorderPixel(x, y, closestPointIndex) {\n    const neighbors = [\n        { dx: -1, dy: 0 }, { dx: 1, dy: 0 },\n        { dx: 0, dy: -1 }, { dx: 0, dy: 1 }\n    ];\n\n    for (let i = 0; i &lt; neighbors.length; i++) {\n        const nx = x + neighbors[i].dx;\n        const ny = y + neighbors[i].dy;\n\n        if (nx &gt;= 0 &amp;&amp; nx &lt; canvas.width &amp;&amp; ny &gt;= 0 &amp;&amp; ny &lt; canvas.height) {\n            let minDistanceNeighbor = Infinity;\n            let closestPointIndexNeighbor = 0;\n\n            \/\/ Calculate the distance to each seed point for the neighbor pixel\n            for (let j = 0; j &lt; points.length; j++) {\n                const dx = nx - points[j].x;\n                const dy = ny - points[j].y;\n                const distance = Math.sqrt(dx * dx + dy * dy);\n\n                if (distance &lt; minDistanceNeighbor) {\n                    minDistanceNeighbor = distance;\n                    closestPointIndexNeighbor = j;\n                }\n            }\n\n            if (closestPointIndexNeighbor!== closestPointIndex) {\n                return true;\n            }\n        }\n    }\n\n    return false;\n}\n<\/code><\/pre>\n<p>The <code>isBorderPixel<\/code> function checks if a pixel is on the border of a Voronoi region. It does this by looking at the neighboring pixels and comparing the closest seed points. If the closest seed point of a neighbor is different from the current pixel, then the current pixel is on the border. We then draw a black stroke to outline the region.<\/p>\n<h3>Wrapping Up and Reaching Out<\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/www.shengruntextile.com\/uploads\/201817142\/small\/acrylic-grey-melange-yarn08414157663.jpg\"><\/p>\n<p>Drawing a Voronoi diagram on a Canvas is a super fun and rewarding project. It combines math, art, and web development all in one. And as a Canvas supplier, I know how important it is to have the right tools and resources to bring your creative ideas to life.<\/p>\n<p><a href=\"https:\/\/www.shengruntextile.com\/embroidery\/embroidery-fabric\/\">Embroidery Fabric<\/a> If you&#8217;re interested in using high &#8211; quality Canvas for your projects, whether it&#8217;s for this Voronoi diagram or something else entirely, I&#8217;d love to chat with you. We offer a wide range of Canvas options that are perfect for both small &#8211; scale personal projects and large &#8211; scale commercial applications. Don&#8217;t hesitate to reach out and start a conversation about your needs!<\/p>\n<h3>References<\/h3>\n<ul>\n<li>&quot;HTML5 Canvas Deep Dive&quot; by Steve Fulton and Jeff Fulton.<\/li>\n<li>&quot;JavaScript: The Definitive Guide&quot; by David Flanagan.<\/li>\n<\/ul>\n<hr>\n<p><a href=\"https:\/\/www.shengruntextile.com\/\">Shandong Shengrun Textile Co., Ltd.<\/a><br \/>With over 15 years of experience, Shandong Shengrun Textile Co., Ltd. is one of the most professional canvas manufacturers and suppliers in China. Please rest assured to buy or wholesale durable canvas in stock here from our factory.<br \/>Address: 9th Floor, Hui Ji Business Tower, Ren Cheng District, Ji Ning, Shan Dong, China<br \/>E-mail: liang@shengrungroup.com<br \/>WebSite: <a href=\"https:\/\/www.shengruntextile.com\/\">https:\/\/www.shengruntextile.com\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey there, art enthusiasts and fellow tech lovers! I&#8217;m super stoked to share this in &#8211; &hellip; <a title=\"How to draw a Voronoi diagram on a Canvas?\" class=\"hm-read-more\" href=\"http:\/\/www.olentaqua.com\/blog\/2026\/07\/08\/how-to-draw-a-voronoi-diagram-on-a-canvas-43bf-a6ab39\/\"><span class=\"screen-reader-text\">How to draw a Voronoi diagram on a Canvas?<\/span>Read more<\/a><\/p>\n","protected":false},"author":27,"featured_media":72,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[35],"class_list":["post-72","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-industry","tag-canvas-4e89-a782b5"],"_links":{"self":[{"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/posts\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":0,"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/posts\/72"}],"wp:attachment":[{"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.olentaqua.com\/blog\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}