As I mentioned in my introductory post, I’m not just a Dart developer; I’m also a computer graphics enthusiast. I’ve been meaning to break out of the realm of purely academic Dart code and give you some examples of graphics code. As a first step towards that goal, today I wrote a tiny Dart app that runs in any web browser. I compiled it to JavaScript using dart2js. And here are the results!

Regular Polygons Screenshot

Well–actually that’s just a screenshot. But you can run the app for yourself right here!

I know it’s not much, but we have to start somewhere. All I’m doing is grabbing a CanvasRenderingContext2D instance out of an HTML document, resizing it, and then drawing some regular polygons on it.

Starting with the HTML

I’m working off of the Stagehand template that IntelliJ generated for me. I just made some small modifications to index.html to add a small canvas at the center of the page.

<!DOCTYPE html>

<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="scaffolded-by" content="https://github.com/google/stagehand">
    <title>regular_polygon</title>
    <link rel="stylesheet" href="styles.css">
    <script defer src="main.dart.js"></script>
</head>

<body>

    <div id="canvas_container" style="width: 100%; text-align: center;">
        <p><a href="https://www.dartographer.com">Dartographer</a> © 2018 Aaron Barrett</p>
        <canvas id="canvas" width="100" height="100"></canvas>
    </div>

</body>
</html>

Now onward, to the Dart!

Here’s my main.dart.

import "dart:html";

import "canvas_tools.dart";
import "regular_polygon.dart";

void main() {
  var canvas = CanvasTools.configureSquareCanvas();
  var context = canvas.getContext("2d") as CanvasRenderingContext2D;

  var canvasSize = canvas.width;
  var radius = canvasSize * 0.15;
  var gridSize = canvasSize / 3;

  var sidesCount = 3;
  for (var yIndex = 0; yIndex < 3; yIndex++) {
    for (var xIndex = 0; xIndex < 3; xIndex++) {
      new RegularPolygon(sidesCount, radius)
        ..centerX = (xIndex + 0.5) * gridSize
        ..centerY = (yIndex + 0.5) * gridSize
        ..red = (xIndex / 2.0 * 255).round()
        ..blue = (yIndex / 2.0 * 255).round()
        ..draw(context);

      sidesCount++;
    }
  }
}

This might not be the most elegant way to structure a project, but it works fine for a quick web page. And look at that beautiful cascade syntax!

First I pull out the canvas element using the CanvasTools class that I wrote. Here’s canvas_tools.dart:

import "dart:html";
import "dart:math";

class CanvasTools {
  static CanvasElement configureSquareCanvas(
      {String elementId = "canvas", num maxSizeProportion = 0.8}) {
    CanvasElement canvas = querySelector("#$elementId");

    var smallerDimension = min(window.innerWidth, window.innerHeight);
    var size = (smallerDimension * maxSizeProportion).round();

    canvas.width = size;
    canvas.height = size;

    return canvas;
  }
}

For compatibility reasons, Dart’s canvas implementation has to be built on top of JavaScript’s, which is pretty limited and clunky to work with. The good news is that Dart lets you build up your own class structures so you can abstract away as much of the clunkiness as you please.

Here’s my regular_polygon.dart:

import "dart:html";
import "dart:math";

class RegularPolygon {
  double centerX = 0.0;
  double centerY = 0.0;

  int red = 0;
  int green = 0;
  int blue = 0;

  double radius;
  int sidesCount;

  RegularPolygon(this.sidesCount, this.radius);

  void draw(CanvasRenderingContext2D context) {
    context.setFillColorRgb(red, green, blue);
    context.beginPath();
    context.moveTo(centerX + radius, centerY);

    for (var sideIndex = 0; sideIndex < sidesCount; sideIndex++) {
      var angle = 2.0 * pi * (sideIndex + 1.0) / sidesCount;
      context.lineTo(
          centerX + cos(angle) * radius, centerY + sin(angle) * radius);
    }

    context.fill();
  }
}

Nothing fancy here. I’m just passing in the context object so I can draw on it. With a little bit of math, I’m drawing the sides one by one. At the end I fill in the path. And tada!

Just the beginning

That’s it for today’s super-simple code example, but I can assure you I’ll have much more interesting web graphics code to share soon. Stay tuned! I’ve posted the code for this project on GitHub–please feel free to share and modify it!