Add image drawing
This commit is contained in:
		| @@ -235,13 +235,13 @@ export const measureDominionText = async ( | |||||||
| 			} | 			} | ||||||
| 			line.width = line.pieces | 			line.width = line.pieces | ||||||
| 				.map((piece) => piece.measure.width) | 				.map((piece) => piece.measure.width) | ||||||
| 				.reduce((a, b) => a + b); | 				.reduce((a, b) => a + b, 0); | ||||||
| 			return line; | 			return line; | ||||||
| 		}), | 		}), | ||||||
| 		width: Math.max(...lines.map((line) => line.width)), | 		width: Math.max(...lines.map((line) => line.width)), | ||||||
| 		height: lines | 		height: lines | ||||||
| 			.map((line) => line.ascent + line.descent) | 			.map((line) => line.ascent + line.descent) | ||||||
| 			.reduce((a, b) => a + b), | 			.reduce((a, b) => a + b, 0), | ||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								src/draw.ts
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								src/draw.ts
									
									
									
									
									
								
							| @@ -3,25 +3,28 @@ import { | |||||||
| 	parse, | 	parse, | ||||||
| 	renderDominionText, | 	renderDominionText, | ||||||
| } from "./dominiontext.ts"; | } from "./dominiontext.ts"; | ||||||
| import { DominionCardType, DominionColor, TYPE_ACTION } from "./types.ts"; | import { DominionCardType, TYPE_ACTION } from "./types.ts"; | ||||||
| import { DominionCard } from "./types.ts"; | import { DominionCard } from "./types.ts"; | ||||||
|  |  | ||||||
| const imageCache: Record<string, HTMLImageElement> = {}; | const imageCache: Record<string, HTMLImageElement> = {}; | ||||||
| export const loadImage = ( | export const loadImage = ( | ||||||
| 	key: string, | 	src: string, | ||||||
| 	src: string | 	key?: string | ||||||
| ): Promise<HTMLImageElement> => { | ): Promise<HTMLImageElement | null> => { | ||||||
| 	return new Promise((resolve) => { | 	return new Promise((resolve) => { | ||||||
| 		if (key in imageCache && imageCache[key]) { | 		if (key && key in imageCache && imageCache[key]) { | ||||||
| 			resolve(imageCache[key]); | 			resolve(imageCache[key]); | ||||||
| 		} | 		} | ||||||
| 		const img = new Image(); | 		const img = new Image(); | ||||||
| 		img.onload = () => { | 		img.onload = () => { | ||||||
|  | 			if (key) { | ||||||
| 				imageCache[key] = img; | 				imageCache[key] = img; | ||||||
|  | 			} | ||||||
| 			resolve(img); | 			resolve(img); | ||||||
| 		}; | 		}; | ||||||
| 		img.onerror = (e) => { | 		img.onerror = (e) => { | ||||||
| 			console.log("err", e); | 			console.log("err", e); | ||||||
|  | 			resolve(null); | ||||||
| 		}; | 		}; | ||||||
| 		img.src = src; | 		img.src = src; | ||||||
| 	}); | 	}); | ||||||
| @@ -53,7 +56,7 @@ const imageList = [ | |||||||
| export const loadImages = async () => { | export const loadImages = async () => { | ||||||
| 	for (const imageInfo of imageList) { | 	for (const imageInfo of imageList) { | ||||||
| 		const { key, src } = imageInfo; | 		const { key, src } = imageInfo; | ||||||
| 		await loadImage(key, src); | 		await loadImage(src, key); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -123,6 +126,24 @@ const drawStandardCard = async ( | |||||||
| 	const h = context.canvas.height; | 	const h = context.canvas.height; | ||||||
| 	context.save(); | 	context.save(); | ||||||
| 	// Draw the image | 	// Draw the image | ||||||
|  | 	const image = await loadImage(card.image); | ||||||
|  | 	if (image) { | ||||||
|  | 		const cx = w / 2; | ||||||
|  | 		const cy = 704; | ||||||
|  | 		const windowHeight = 830; | ||||||
|  | 		const windowWidth = 1194; | ||||||
|  | 		const scale = Math.max( | ||||||
|  | 			windowHeight / image.height, | ||||||
|  | 			windowWidth / image.width | ||||||
|  | 		); | ||||||
|  | 		context.drawImage( | ||||||
|  | 			image, | ||||||
|  | 			cx - (scale * image.width) / 2, | ||||||
|  | 			cy - (scale * image.height) / 2, | ||||||
|  | 			scale * image.width, | ||||||
|  | 			scale * image.height | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
| 	// Draw the card base | 	// Draw the card base | ||||||
| 	const color = getColors(card.types).primary; // "#ffbc55"; | 	const color = getColors(card.types).primary; // "#ffbc55"; | ||||||
| 	context.drawImage(colorImage(getImage("card-color-1"), color), 0, 0); | 	context.drawImage(colorImage(getImage("card-color-1"), color), 0, 0); | ||||||
| @@ -178,7 +199,33 @@ const drawStandardCard = async ( | |||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 	// Draw the icon | 	// Draw the icon | ||||||
| 	// Draw the credit | 	// Draw the author credit | ||||||
|  | 	context.fillStyle = "white"; | ||||||
|  | 	context.font = "31pt DominionText"; | ||||||
|  | 	const authorMeasure = await measureDominionText( | ||||||
|  | 		context, | ||||||
|  | 		parse(card.author) | ||||||
|  | 	); | ||||||
|  | 	await renderDominionText( | ||||||
|  | 		context, | ||||||
|  | 		parse(card.author), | ||||||
|  | 		w - 150 - authorMeasure.width / 2, | ||||||
|  | 		2035, | ||||||
|  | 		w / 2 - 150 | ||||||
|  | 	); | ||||||
|  | 	// Draw the artist credit | ||||||
|  | 	const artistMeasure = await measureDominionText( | ||||||
|  | 		context, | ||||||
|  | 		parse(card.artist) | ||||||
|  | 	); | ||||||
|  | 	await renderDominionText( | ||||||
|  | 		context, | ||||||
|  | 		parse(card.artist), | ||||||
|  | 		155 + artistMeasure.width / 2, | ||||||
|  | 		2035, | ||||||
|  | 		w / 2 - 150 | ||||||
|  | 	); | ||||||
|  | 	// Restore the context | ||||||
| 	context.restore(); | 	context.restore(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| import { | import { | ||||||
| 	DominionCard, | 	DominionCard, | ||||||
| 	TYPE_ACTION, | 	TYPE_ACTION, | ||||||
| 	TYPE_ATTACK, |  | ||||||
| 	TYPE_REACTION, | 	TYPE_REACTION, | ||||||
| 	TYPE_TREASURE, | 	TYPE_TREASURE, | ||||||
| } from "./types.ts"; | } from "./types.ts"; | ||||||
| @@ -11,9 +10,9 @@ export const sampleCard1: DominionCard = { | |||||||
| 	title: "Title", | 	title: "Title", | ||||||
| 	description: "Hello, world.", | 	description: "Hello, world.", | ||||||
| 	types: [TYPE_ACTION, TYPE_REACTION], | 	types: [TYPE_ACTION, TYPE_REACTION], | ||||||
| 	image: "", | 	image: "https://wiki.dominionstrategy.com/images/7/76/AdventurerArt.jpg", | ||||||
| 	artist: "", | 	artist: "Dall-E", | ||||||
| 	author: "", | 	author: "John Doe", | ||||||
| 	version: "", | 	version: "", | ||||||
| 	cost: "$", | 	cost: "$", | ||||||
| 	preview: "", | 	preview: "", | ||||||
| @@ -25,8 +24,8 @@ export const sampleCard2: DominionCard = { | |||||||
| 	description: "+1 Card\n+1 Action\n+1 Buy\n+$1", | 	description: "+1 Card\n+1 Action\n+1 Buy\n+$1", | ||||||
| 	types: [TYPE_ACTION], | 	types: [TYPE_ACTION], | ||||||
| 	image: "", | 	image: "", | ||||||
| 	artist: "", | 	artist: "Leonardo DaVinci", | ||||||
| 	author: "", | 	author: "Jane Smith", | ||||||
| 	version: "", | 	version: "", | ||||||
| 	cost: "$4", | 	cost: "$4", | ||||||
| 	preview: "", | 	preview: "", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user