Holiday Paintable Canvas Challenge

Create your best holiday image in the paintable canvas and share it here.

Example:
I was able to create a Santa Clause in the paintable canvas by simply tracing an image using the techniques outlined in this tutorial:
Paintable Canvas Hacks Post #1

Result:

Repaint Event Code:

from java.awt import BasicStroke
from java.awt.geom import Arc2D, GeneralPath

graphics = event.graphics
graphics.stroke = BasicStroke(2)
graphics.color = system.gui.color('red')

# Scale graphics to actual component size
dX = (event.width-1)/230.0
dY = (event.height-1)/275.0
graphics.scale(dX,dY)

###################
# Paint Red HAT
###################
hat = GeneralPath()

# Top of hat
hat.append(Arc2D.Double(20, 5, 185, 180, 360, 178, Arc2D.OPEN), True)

# Top of hat brim
hat.append(Arc2D.Double(-60, 75, 330, 230, 121, -59, Arc2D.OPEN), True)

# Right of hat brim
hat.append(Arc2D.Double(117, 69, 70, 76, 30, -60, Arc2D.OPEN), True)

# Beard Border
hat.append(Arc2D.Double(121, 105, 64, 62, 30, -40, Arc2D.OPEN), True)

# Top of ball on hat
hat.append(Arc2D.Double(171, 138, 53, 52, 114, -34, Arc2D.OPEN), True)

# Hat tail 
hat.append(Arc2D.Double(-39, -20, 245, 257, 348, 18, Arc2D.OPEN), True)

hat.closePath()
graphics.fill(hat)

###################
# Paint White Hat Brim
###################
graphics.color = system.gui.color(245, 245, 235)
hatBrim = GeneralPath()

# Top of hat brim
hatBrim.append(Arc2D.Double(-60, 75, 330, 230, 62, 59, Arc2D.OPEN), True)

# Left of hat brim
hatBrim.append(Arc2D.Double(12, 80, 70, 61, 144, 65, Arc2D.OPEN), True)

# Bottom of hat brim
hatBrim.append(Arc2D.Double(-60, 110, 320, 230, 121, -61, Arc2D.OPEN), True)

# Right of hat brim
hatBrim.append(Arc2D.Double(117, 69, 70, 76, 330, 60, Arc2D.OPEN), True)

hatBrim.closePath()
graphics.fill(hatBrim)

###################
# Paint White Hat Ball
###################

graphics.color = system.gui.color(245, 245, 235)
graphics.fillOval(171, 138, 53, 52)

###################
# Paint White Beard
###################
beard = GeneralPath()
graphics.color = system.gui.color(235, 240, 245)

# Beard Shapes starting at the left and moving clockwise
beard.append(Arc2D.Double(10, 115, 64, 62, 145, 50, Arc2D.OPEN), True)
beard.append(Arc2D.Double(4, 146, 58, 53, 142, 102, Arc2D.OPEN), True)
beard.append(Arc2D.Double(16, 182, 58, 53, 152, 118, Arc2D.OPEN), True)
beard.append(Arc2D.Double(46, 208, 50, 53, 183, 108, Arc2D.OPEN), True)
beard.append(Arc2D.Double(75, 216, 50, 54, 214, 108, Arc2D.OPEN), True) # Bottom of beard
beard.append(Arc2D.Double(108, 208, 50, 53, 240, 121, Arc2D.OPEN), True)
beard.append(Arc2D.Double(128, 182, 58, 53, 273, 118, Arc2D.OPEN), True)
beard.append(Arc2D.Double(134, 146, 58, 53, 309, 99, Arc2D.OPEN), True)
beard.append(Arc2D.Double(121, 105, 64, 62, 330, 50, Arc2D.OPEN), True)

# Bottom of hat brim
beard.append(Arc2D.Double(-60, 110, 320, 230, 60, 61, Arc2D.OPEN), True)

beard.closePath()
graphics.fill(beard)

###################
# Paint Face
###################
face = GeneralPath()
graphics.color = system.gui.color(255, 224, 189)

# Right cheek
face.append(Arc2D.Double(33, 75, 130, 150, 330, 55, Arc2D.OPEN), True)

# Bottom of hat brim
face.append(Arc2D.Double(-60, 110, 320, 230, 65, 50, Arc2D.OPEN), True)

# left cheek
face.append(Arc2D.Double(33, 75, 130, 150, 155, 55, Arc2D.OPEN), True)


face.closePath()
graphics.fill(face)

###################
# Paint Mouth
###################

graphics.color = system.gui.color('pink')
graphics.fillOval(79, 150, 38, 41)

###################
# Paint Eyebrows
###################
graphics.color = system.gui.color(225, 230, 235)

rightEyeBrow = GeneralPath()
rightEyeBrow.moveTo(137, 113)
rightEyeBrow.lineTo(138, 122)
rightEyeBrow.lineTo(114, 111)
rightEyeBrow.closePath()
graphics.fill(rightEyeBrow)

leftEyeBrow = GeneralPath()
leftEyeBrow.moveTo(57, 115)
leftEyeBrow.lineTo(56, 122)
leftEyeBrow.lineTo(80, 112)
leftEyeBrow.closePath()
graphics.fill(leftEyeBrow)

###################
# Paint Mustash
###################
LeftStash = GeneralPath()
LeftStash.append(Arc2D.Double(61, 145, 75, 64, 114, 50, Arc2D.OPEN), True)
LeftStash.append(Arc2D.Double(28, 141, 36, 41, 349, -164, Arc2D.OPEN), True)
LeftStash.append(Arc2D.Double(28, 128, 70, 70, 185, 174, Arc2D.OPEN), True)
LeftStash.closePath()
graphics.fill(LeftStash)

RightStash = GeneralPath()
RightStash.append(Arc2D.Double(98, 128, 70, 70, 185, 174, Arc2D.OPEN), True)
RightStash.append(Arc2D.Double(133, 141, 36, 41, 1, -166, Arc2D.OPEN), True)
RightStash.append(Arc2D.Double(61, 145, 75, 64, 16, 50, Arc2D.OPEN), True)
RightStash.closePath()
graphics.fill(RightStash)

###################
# Paint Nose
###################

graphics.color = system.gui.color(225, 150, 150)
graphics.fillOval(82, 140, 31, 22)

###################
# Draw Santa outline and facial details over filled shapes
###################
graphics.stroke = BasicStroke(2)
graphics.color = system.gui.color('black')

# Top of hat
graphics.drawArc(20, 5, 185, 180, 360, 178)

# Top of hat brim
graphics.drawArc(-60, 75, 330, 230, 62, 59)

# Bottom of hat brim
graphics.drawArc(-60, 110, 320, 230, 60, 61)

# Left of hat brim
graphics.drawArc(12, 80, 70, 61, 144, 65)

# Right of hat brim
graphics.drawArc(117, 69, 70, 76, 330, 60)

# Crease between hat tail and hat
graphics.drawArc(95, 40, 86, 106, 10, 24)
graphics.drawArc(95, 40, 86, 106, 40, 24)

# Hat tail
graphics.drawArc(-39, -19, 245, 257, 348, 18)

# Ball on end of hat tail
graphics.drawArc(171, 138, 53, 52, 245, 238)

# Beard counterclockwise
graphics.drawArc(121, 105, 64, 62, 330, 50)
graphics.drawArc(134, 146, 58, 53, 309, 99)
graphics.drawArc(128, 182, 58, 53, 273, 118)
graphics.drawArc(108, 208, 50, 53, 240, 121)
graphics.drawArc(75, 216, 50, 54, 214, 108) # Bottom of beard
graphics.drawArc(46, 208, 50, 53, 183, 108)
graphics.drawArc(16, 182, 58, 53, 152, 118)
graphics.drawArc(4, 146, 58, 53, 142, 102)
graphics.drawArc(10, 115, 64, 62, 145, 50)

# Left Cheek
graphics.drawArc(33, 75, 130, 150, 155, 45)

# Right Cheek
graphics.drawArc(33, 75, 130, 150, 340, 45)

# Nose
graphics.drawOval(82, 140, 31, 22)

# left and right  eyes
graphics.fillOval(59, 121, 24, 24)
graphics.fillOval(113, 121, 24, 24)

# left and right pupils
graphics.color = system.gui.color('white')
graphics.fillOval(68, 126, 11, 11)
graphics.fillOval(117, 126, 11, 11)

# Left Eyebrow
graphics.color = system.gui.color('black')
graphics.drawLine(57, 115, 56, 122)
graphics.drawLine(56, 122, 80, 112)

# Right Eyebrow
graphics.color = system.gui.color('black')
graphics.drawLine(137, 113, 138, 122)
graphics.drawLine(138, 122, 114, 111)

# Right stash
graphics.drawArc(61, 145, 75, 64, 16, 50)
graphics.drawArc(133, 141, 36, 41, 195, 166)
graphics.drawArc(98, 128, 70, 70, 185, 174)

# Left Stash
graphics.drawArc(61, 145, 75, 64, 114, 50)
graphics.drawArc(28, 141, 36, 41, 185, 164)
graphics.drawArc(28, 128, 70, 70, 185, 174)

# Mouth
graphics.drawArc(79, 150, 38, 41, 240, 60)
6 Likes

I bet it'd be fun to have a procedurally generated tree with randomly placed lights, tinsel, ornaments?

No nerd sniping, Justin! There's end of year deadlines to think of!

4 Likes

I've made Christmas trees before: :slight_smile: Traced Christmas Tree Example

Traced Christmas Tree

For more fun:
Add a running timer component to the window. Then, put a custom property on the canvas called value and bind it to the value property of the timer to drive animations in the canvas.

Example: (Using the Santa repaint event code above)
Modify the part of the code where the eyes and pupils are drawn, so they change with the timer value:

# left and right  eyes
graphics.fillOval(59, 121, 24, 24)
if event.source.value % 2:
	graphics.fillOval(113, 121, 24, 24)
else:
	graphics.drawLine(113, 132, 133, 132)

# left and right pupils
graphics.color = system.gui.color('white')
graphics.fillOval(68, 126, 11, 11)
if event.source.value % 2:
	graphics.fillOval(117, 126, 11, 11)

Result:
SantaWinking

8 Likes

Thanksgiving Turkey

Repaint Event Script

from java.awt import BasicStroke

graphics = event.graphics
graphics.stroke = BasicStroke(1)

dX = (event.width-1)/225.0
dY = (event.height-1)/225.0
graphics.scale(dX,dY)

bodyColor = system.gui.color(139, 69, 19)		# brown
chestColor = system.gui.color(120, 60, 20)		# darker brown
legColor = system.gui.color(255, 140, 0)		# orange
beakColor = system.gui.color(255, 165, 0)		# lighter orange
black = system.gui.color('black')
white = system.gui.color('white')

tailColors = [
	system.gui.color(160, 82, 45),				# sienna
	system.gui.color(205, 92, 92),				# indian red
	system.gui.color(222, 184, 135),			# tan
	system.gui.color(210, 105, 30),				# chocolate
	system.gui.color(184, 134, 11),				# dark gold
	bodyColor									# brown
	]

# Draw tail feathers behind the body
baseX = 38
baseY = 80
diameter = 130
arcSpan = 25
overlap = 5
totalArc = (arcSpan - overlap) * len(tailColors) 
for iteration in xrange(1, 3):
	startAngle = 208 + (totalArc * iteration)
	for index, color in enumerate(tailColors):
		graphics.color = color
		graphics.fillArc(baseX, baseY, diameter, diameter, startAngle + (index * (arcSpan - overlap)), arcSpan)


##################### 
# Neck & Head
#####################
# Neck
graphics.color = bodyColor
graphics.fillRoundRect(95, 80, 20, 30, 10, 10)
graphics.color = black
graphics.drawRoundRect(95, 80, 20, 30, 10, 10)

# Head
graphics.color = bodyColor
graphics.fillOval(90, 55, 30, 30)
graphics.color = black
graphics.drawArc(90, 55, 30, 30, 0, 231)

##################### 
# Face
##################### 

# Eye
graphics.color = white
graphics.fillOval(100, 63, 10, 10)

# Pupil
graphics.color = black
graphics.fillOval(104, 67, 4, 4)

# Beak
graphics.color = beakColor
beakX = [118, 135, 118]
beakY = [70, 78, 86]
graphics.fillPolygon(beakX, beakY, 3)
graphics.color = black
graphics.drawPolygon(beakX, beakY, 3)

# Wattle
graphics.color = system.gui.color(200, 0, 0)
graphics.fillOval(112, 75, 8, 15)

# Body
graphics.color = black
graphics.drawArc(75, 90, 60, 70, 110, 320)
graphics.color = bodyColor
graphics.fillOval(75, 90, 60, 70)

# Chest
graphics.color = chestColor
graphics.fillOval(75, 105, 60, 45)

# Feet & Legs
graphics.stroke = BasicStroke(3)
graphics.color = legColor

# Legs
graphics.drawLine(95, 155, 95, 185)
graphics.drawLine(115, 155, 115, 185)

# Left Foot
graphics.drawLine(95, 185, 85, 190)
graphics.drawLine(95, 185, 105, 190)
graphics.drawLine(95, 180, 95, 190)

# Right Foot
graphics.drawLine(115, 185, 105, 190)
graphics.drawLine(115, 185, 125, 190)
graphics.drawLine(115, 180, 115, 190)
3 Likes

You forgot the potatoes and the gravy.

edit: I hope you made functions for these drawings. I'm imagining calls to cook_turkey(), bake_potatoes()...

4 Likes

I make a really good Easter egg, but somebody will have to find it before I'll be willing to give up the recipe:
Easter Egg Challenge

I earnestly spent a while once trying to cheat and find the easter egg just looking at the code and couldn't, so hats off (or I'm particularly blind).

1 Like

The power of obfuscation :upside_down_face: I knew somebody would take that approach, so I went out of my way to use ambiguous and misleading variable names to conceal it.

Hint: The vast majority of my functions are meticulously commented.