Drawing a Scar on an HTML Canvas

A simple approach to drawing a “scar” with “stitches” on an HTML canvas.

The Requirments

The team was developing a simple drawing tool for use in a hospital, to replace a 3rd party application that was due to be decommissioned. One of the requirements was that the users should be able to draw a line that represents a scar. The customer wanted these lines to look similar to the ones in the old tool, something like this:

Example Scar Line

Rejected Solution

Our initial thoughts were that we that we would need to take the equation for the original line, and use some kind of algorithm to figure out the location and angle of the stitches. This would undoubtedly involve some complex mathematics.

The Final Solution

My final solution is simple and fast, and works perfectly for lines, quadratic curves and bezier curves. It hardly involve any calculation at all!

How It works

To see how it works, follow these steps:

Step 1: Draw the Initial Line

Step 2: Make the Line Wider

Step 3: Make the Line Dashed

Step 4: Draw the Line Twice, First Thin, Then Wide and Dashed

Step 5: Adjust the Dash Spacing and Dash Widths

Implementation

The code below will draw the scar depicted above:

<!DOCTYPE HTML>
<html>
<head>
	<style>
	body {
		margin: 0px;
		padding: 0px;
	}
	</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
	var scarThickness = 3;
	var stitchThickness = 1;
	var stitchSpacing = 20;
	var stitchWidth = 25;

	 var canvas = document.getElementById('myCanvas');
	 var context = canvas.getContext('2d');

		// We'll draw the scar in 2 passes over the same line.
		for(pass = 0; pass < 2; pass++) {

			// Both passes will draw this squiggle.
			context.beginPath();
			context.moveTo(100, 20);
			context.lineTo(200, 160);
			context.quadraticCurveTo(230, 200, 250, 120);
			context.bezierCurveTo(290, -40, 300, 200, 400, 150);
			context.lineTo(500, 90);

			switch(pass){
				case 0:
					// Normal line for 1st pass, which draws the base scar.
					context.lineWidth = scarThickness;
					break;
				case 1:
					// Wide dashed lines for 2nd pass to achieve stitch effect.
					context.lineWidth = stitchWidth;
					context.setLineDash([stitchThickness, stitchSpacing]);
					break;
			}

			context.strokeStyle = 'red';
			context.stroke();
		}
	 
</script>
</body>
</html> 

Leave a Reply

Your email address will not be published. Required fields are marked *