Artelice Pâtisserie

Sample the flavors of Artelice Pâtisserie.

Tap or hover over a tab to view a pastry. Tap/click and hold to see the flavor profile.

Source Code for this Sketch

class Flavor {
	constructor(name, pct, hue, sat, lum){
		this.name = name
		this.pct = pct
		this.hue = hue
		this.sat = sat
		this.lum = lum
	}
}

let yums = [
	{
		name: "Exotic",
		image: "Exotic.jpg",
		mask: "ExoticMask.png",
		color: [46, 95, 49],
		description: "Pistachio sponge, mango, banana and passion fruit insert with Caribbean cocktail pineapple, coconut, lemon and passion fruit mousse",
		flavors: [
			new Flavor("Lemon", 5, 52, 95, 51),
			new Flavor("Mango", 20, 38, 93, 62),
			new Flavor("Pineapple", 10, 51, 95, 63),
			new Flavor("Passion Fruit", 40, 346, 71, 49),
			new Flavor("Coconut", 10, 38, 93, 97),
			new Flavor("Banana", 5, 48, 87, 58),
			new Flavor("Pistachio", 10, 67, 59, 49)
		]
	},
	{
		name: "Saint Honore",
		image: "Saint_Honore.jpg",
		mask: "Saint_HonoreMask.png",
		color: [34, 95, 49],
		description: "Caramelized puff pastry filled with Madagascar vanilla pastry cream and salted caramel topped with 24h infused Madagascar vanilla ganache",
		flavors: [
			new Flavor("Caramel", 20, 34, 95, 49),
			new Flavor("Vanilla Cream", 40, 54, 66, 97),
			new Flavor("Puff Pastry", 40, 40, 98, 73),
		]
	},
	{
		name: "Tiramisu",
		image: "Tiramisu.jpg",
		mask: "TiramisuMask.png",
		color: [28, 89, 28],
		description: "Lady finger sponge soaked in coffee and rum syrup and mascarpone mousse",
		flavors: [
			new Flavor("Mascarpone", 45, 48, 87, 95),
			new Flavor("Rum", 10, 23, 89, 53),
			new Flavor("Coffee", 20, 23, 69, 15),
			new Flavor("Lady Finger", 25, 38, 70, 66),
		]
	},
	{
		name: "Valentino",
		image: "Valentino.jpg",
		mask: "ValentinoMask.png",
		color: [4, 93, 33],
		description: "Dark chocolate mousse, raspberry insert, coconut sponge",
		flavors: [
			new Flavor("Raspberry", 50, 349, 63, 42),
			new Flavor("Dark Chocolate", 40, 13, 35, 27),
			new Flavor("Coconut", 10, 38, 93, 97),
		]
	}
]

const buttonPadding = 10
let tangerine
let buttonSize
let selected

function preload() {
	yums.forEach((yum) => {
		yum.imageData = loadImage(yum.image)
		yum.maskData = loadImage(yum.mask)
	})
	tangerine = loadFont("Tangerine-Bold.ttf")
}

function setup() {
	// 415x415px for images
	// 30 px row for buttons
	// 60 px row for description
	createCanvas(415, 505, P2D, canvas)
	chrisDefaults()

	frameRate(8)

	textFont(tangerine)

	let totalTextWidth = 0
	yums.forEach((yum) => {
		// figure out how wide each button should be
		yum.rawWidth = textWidth(yum.name)
		totalTextWidth += yum.rawWidth


		yum.maskTop = width
		yum.maskBottom = 0

		// find the top and bottom of the mask
		yum.maskData.resize(width, 0)
		yum.maskData.loadPixels()
		for (let i = 0; i < yum.maskData.pixels.length; i += 4) {
			if (yum.maskData.pixels[i+3] > 50) {
				// get the current Y position in the mask image
				let currentRow = Math.floor(i / width / 4)

				// set top to the first value we find, and leave it
				if (currentRow < yum.maskTop) {
					yum.maskTop = currentRow
				}

				// set bottom to the last value we find
				yum.maskBottom = currentRow
			}
		}

		// draw the Flavors stack
		//
		// 1. Create a buffer canvas we can draw on
		// 2. Draw a vertical "bar chart" of flavor data from yum.flavors
		// 3. Apply the mask
		// 4. Stuff the image data into the yum

		let buffer = createGraphics(width, width)
		buffer.colorMode(HSL)
		buffer.strokeWeight(0)

		yum.maskHeight = yum.maskBottom - yum.maskTop
		let top = yum.maskTop
		yum.flavors.forEach(flavor => {
			buffer.fill(flavor.hue, flavor.sat, flavor.lum)
			let flavorHeight = flavor.pct/100 * yum.maskHeight
			buffer.rect(0, top, width, flavorHeight)
			top += flavorHeight
		})

		yum.flavorData = createImage(width, width)
		yum.flavorData.copy(buffer, 0, 0, width, width, 0, 0, width, width)
		yum.flavorData.mask(yum.maskData)
	})

	let left = 0
	yums.forEach((yum) => {
		yum.width = yum.rawWidth*((width-buttonPadding*8)/(totalTextWidth))+buttonPadding*2

		// pre-calculate the button size for mouse checks
		yum.rect = [left, width, yum.width, 30]
		left += yum.width
	})
	// Set button text size to a % based on the calculated width
	buttonSize = yums[0].width / yums[0].rawWidth

	textAlign(LEFT, TOP)

	selected = 0
}

function draw() {
	strokeWeight(0)

	// button row
	textSize(30)
	textAlign(LEFT, TOP)
	yums.forEach((yum, index) => {
		if(UI.inRect(yum.rect[0], yum.rect[1], yum.rect[2], yum.rect[3])) {
			selected = index
		}
		// Button
		fill(yum.color[0], yum.color[1], yum.color[2])
		rect(yum.rect[0], yum.rect[1], yum.rect[2], yum.rect[3])

		// Button text
		if(yum.color[2] > 45) {
			fill(0)
		} else {
			fill(100)
		}
		text(yum.name, yum.rect[0]+buttonPadding, width+2)
	})

	// Selected image
	image(yums[selected].imageData, 0, 0, width, width)

	if (mouseIsPressed) {
		textAlign(CENTER, CENTER)
		// Draw the masked flavor layers
		image(yums[selected].flavorData, 0, 0, width, width)

		// Place flavor text on each layer
		let top = yums[selected].maskTop
		yums[selected].flavors.forEach(flavor => {
			// Put text inside
			fill(0)
			let textHeight = (flavor.pct/100) * yums[selected].maskHeight
			text(flavor.name, width/2, top+textHeight/2)
			top += textHeight
		})
	}

	// Selected description box
	fill(yums[selected].color[0], yums[selected].color[1], yums[selected].color[2])
	rect(0, 445, width, 60)

	// Selected description text
	if(yums[selected].color[2] > 45) {
		fill(0)
	} else {
		fill(100)
	}
	textSize(18)
	textAlign(LEFT, TOP)
	text(yums[selected].description, 10, 455, width-20)
}

You may use all or part of the p5 code seen on this page for your own creations, without restriction. Attribution is appreciated but not required.

This sketch also includes the following sources: p5common.js . Sources are available under their respective licenses.

See all p5.js sketches