Holiday Paintable Canvas Challenge

Old Glory

Perfect for Memorial Day, Independence Day, and other patriotic American holidays

Add this code to the paintable canvas's repaint event handler:
Note: The canvas will need to be a size of at least 345 x 182 to see the entire flag

graphics = event.graphics

## The original width and height of this paintable canvas in the designer
#unscaledWidth = ???
#unscaledHeight = ???

## (Optional) Allow the canvas to be resized and scale the flag automatically
#dX = (event.width - 1) / unscaledWidth
#dY = (event.height - 1) / unscaledHeight
#graphics.scale(dX,dY)

# Iterate through the 13 stripes that represent the 13 colonies and paint them
for stripe in xrange(13):
	if stripe % 2: # Alternate red and white
		graphics.color = system.gui.color('white')
	else:
		graphics.color = system.gui.color(179, 25, 66)	# Old glory red
	
	# Proper flag dimensions were calculated using this website (pixels were substituted for inches):
	# https://www.inchcalculator.com/american-flag-size-proportions-calculator/
	stripeHeight = 14
	flagWidth = 345
	graphics.fillRect(0, (stripeHeight * stripe), flagWidth, stripeHeight)

# Create a blue rectangle for the 50 stars
graphics.color = system.gui.color(10, 49, 97)	# Old glory blue
graphics.fillRect(0, 0, 138, 97)

# Define all the points needed to make a single star in the top left corner of the canvas
# When making eyeball adjustments to the star size and shape,
# ...the coordinates are much easier to visualize written like this
# ..instead of already split into the X and Y lists that the fillPolygon method requires
points = [
	(4, 0),	# Top outer point
	(5, 3),	# Upper right inner point
	(8, 3),	# Upper right outer point
	(5, 5),	# Lower right inner point
	(7, 8),	# Bottom right outer point
	(4, 7),	# Bottom inner point
	(1, 8),	# Bottom left outer point
	(2, 5),	# Lower left inner point
	(0, 3),	# Upper left outer point
	(3, 3)]	# Upper left inner point

# Separate the x and y coordinates for the top left star into seperate lists for the fillPolygon method,
# ...and inset the star by an arbitrary margin (This was originally done directly in the points set,
# ...but once the star shape was perfected, these variables were added to make tinkering with the insets easier to do
topMargin = leftMargin = 4
xCoordinates = [coordinateSet[0] + leftMargin for coordinateSet in points]
yCoordinates = [coordinateSet[1] + topMargin for coordinateSet in points]

# Switch to white for the stars
graphics.color = system.gui.color('white')

# These arbitrary spacing parameters were precisely calculated using trial and error
horizontalSpacing = 24	# The space betwenn the left edge of a star and the left edge of its neighboring star to the right
verticalSpacing = 10	# The space between the top edge of a row, and the top edge of the row below it

# The american flag currently has 5 rows of 6 stars and 4 rows of 5 stars for a total 9 rows
for row in xrange(9):
	starCount = 5 if row % 2 else 6		# Alternate between rows of 6 and 5 stars
	starInset = 12 if row % 2 else 0	# Inset the rows of 5, so the stars appear evenly staggared
	
	# Iterate through each star in the given row,
	# ...and calculate a list of X and Y coordinates for each star to pass into the fillPolygon method
	for star in xrange(starCount):
		starSpecificXCoords = [xCoordinate + starInset + (star * horizontalSpacing) for xCoordinate in xCoordinates]
		starSpecificYCoords = [yCoordinate + (row * verticalSpacing) for yCoordinate in yCoordinates]
		
		# https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics.html#fillPolygon-int:A-int:A-int-
		#graphics.fillPolygon(int[] xPoints, int[] yPoints, int numberOfPoints)
		graphics.fillPolygon(starSpecificXCoords, starSpecificYCoords, len(xCoordinates))
		
# Paint a small border around the flag, so it will look complete against white backgrounds.
graphics.color = system.gui.color('black')
graphics.drawRect(0, 0, flagWidth, (13 * stripeHeight))