Added santa hat, refactored drawing
This commit is contained in:
parent
14250af1e2
commit
bf2584ca8c
2 changed files with 61 additions and 47 deletions
BIN
SantaHat.png
Normal file
BIN
SantaHat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
102
index.js
102
index.js
|
@ -12,20 +12,7 @@ var config = require("./config");
|
||||||
|
|
||||||
var cache = {};
|
var cache = {};
|
||||||
|
|
||||||
templates = {
|
templates = config.templates;
|
||||||
bee: {
|
|
||||||
template: "./BeeTemplate.png",
|
|
||||||
leftOffset: 475,
|
|
||||||
widthTarget: 600,
|
|
||||||
bottomTarget: 530
|
|
||||||
},
|
|
||||||
turtle: {
|
|
||||||
template: "./TurtleTemplate.png",
|
|
||||||
leftOffset: 210,
|
|
||||||
widthTarget: 150,
|
|
||||||
bottomTarget: 150
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(templateName in templates) {
|
for(templateName in templates) {
|
||||||
const data = templates[templateName];
|
const data = templates[templateName];
|
||||||
|
@ -33,6 +20,14 @@ for(templateName in templates) {
|
||||||
data.image.src = data.template;
|
data.image.src = data.template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawing: we keep the image fixed in its default position and draw the template on top/below it
|
||||||
|
|
||||||
|
// calculates the x or y position of the template to be drawn
|
||||||
|
// size = width or height of the template/image
|
||||||
|
// anchor = the corresponding anchor config
|
||||||
|
function calculatePosition(scale, anchor, imageSize) {
|
||||||
|
return imageSize * anchor.position / 100 - anchor.offset * scale;
|
||||||
|
}
|
||||||
|
|
||||||
function render(template, img, size) {
|
function render(template, img, size) {
|
||||||
var width = img.width;
|
var width = img.width;
|
||||||
|
@ -46,45 +41,65 @@ function render(template, img, size) {
|
||||||
if (!size.height) height = height * size.width / img.width;
|
if (!size.height) height = height * size.width / img.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateScale = width / template.widthTarget; // scale the template to fit the image
|
const xScale = width / template.anchor.x.size;
|
||||||
|
const yScale = width / template.anchor.y.size;
|
||||||
|
const templateScale = Math.min(xScale || 1, yScale || 1);
|
||||||
|
|
||||||
|
let templateOffsetX = calculatePosition(templateScale, template.anchor.x, width);
|
||||||
|
let templateOffsetY = calculatePosition(templateScale, template.anchor.y, height);
|
||||||
|
|
||||||
let resultingWidth = template.image.width * templateScale;
|
let imageOffsetX = 0;
|
||||||
let resultingHeight = template.image.height * templateScale;
|
let imageOffsetY = 0;
|
||||||
|
let resultingWidth = width; // start with the image boundaries as defined by the image
|
||||||
|
let resultingHeight = height;
|
||||||
|
|
||||||
let imgTop = template.bottomTarget * templateScale - height; // naive top center position
|
if(templateOffsetX < 0) {
|
||||||
|
resultingWidth -= templateOffsetX;
|
||||||
if (imgTop < 0) {
|
imageOffsetX = -templateOffsetX;
|
||||||
resultingHeight -= imgTop;
|
templateOffsetX = 0;
|
||||||
imgTop = 0;
|
}
|
||||||
|
if(templateOffsetY < 0) {
|
||||||
|
resultingHeight -= templateOffsetY;
|
||||||
|
imageOffsetY = -templateOffsetY;
|
||||||
|
templateOffsetY = 0;
|
||||||
|
}
|
||||||
|
if(template.image.width * templateScale > resultingWidth) {
|
||||||
|
resultingWidth = template.image.width * templateScale;
|
||||||
|
}
|
||||||
|
if(template.image.height * templateScale > resultingHeight) {
|
||||||
|
resultingHeight = template.image.height * templateScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resultingImgTop = imgTop;
|
const toDraw = [{
|
||||||
const resultingImgLeft = template.leftOffset * templateScale - width / 2.0;
|
z: 1,
|
||||||
|
image: img,
|
||||||
if(resultingImgLeft + width > resultingWidth) {
|
x: imageOffsetX,
|
||||||
resultingWidth = resultingImgLeft + width;
|
y: imageOffsetY,
|
||||||
}
|
h: height,
|
||||||
|
w: width,
|
||||||
const resultingTemplateTop = resultingHeight - template.image.height * templateScale;
|
name: "image"
|
||||||
const resultingTemplateLeft = 0.0;
|
}, {
|
||||||
|
z: template.z || 0,
|
||||||
|
image: template.image,
|
||||||
|
x: templateOffsetX,
|
||||||
|
y: templateOffsetY,
|
||||||
|
h: template.image.height * templateScale,
|
||||||
|
w: template.image.width * templateScale,
|
||||||
|
name: "template "+template.template
|
||||||
|
}].sort((u,v) => u.z > v.z);
|
||||||
|
|
||||||
var canvas = new Canvas(resultingWidth, resultingHeight);
|
var canvas = new Canvas(resultingWidth, resultingHeight);
|
||||||
var ctx = canvas.getContext("2d");
|
var ctx = canvas.getContext("2d");
|
||||||
console.log("Drawing template "+template.template)
|
|
||||||
|
for(let i=0;i<toDraw.length;++i) {
|
||||||
|
const subject = toDraw[i];
|
||||||
|
console.log("Drawing "+subject.name)
|
||||||
try {
|
try {
|
||||||
ctx.drawImage(template.image, resultingTemplateLeft, resultingTemplateTop, template.image.width * templateScale, template.image.height * templateScale);
|
ctx.drawImage(subject.image, subject.x, subject.y, subject.w, subject.h);
|
||||||
console.log("Drawing done.")
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(JSON.stringify({ status: 400, error: "Invalid template" }))
|
|
||||||
}
|
|
||||||
console.log("Drawing image")
|
|
||||||
try {
|
|
||||||
ctx.drawImage(img, resultingImgLeft, resultingImgTop, width, height);
|
|
||||||
console.log("Drawing done.")
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
throw new Error(JSON.stringify({ status: 400, error: "Invalid image" }))
|
throw new Error(JSON.stringify({ status: 400, error: "Invalid template" }))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the image and cache it
|
// return the image and cache it
|
||||||
|
@ -104,7 +119,7 @@ app.get("/:templateName/", async function (req, res) {
|
||||||
res.setHeader('Content-Type', 'image/png');
|
res.setHeader('Content-Type', 'image/png');
|
||||||
return canvas.pngStream().pipe(res);
|
return canvas.pngStream().pipe(res);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err.message);
|
console.log(err);
|
||||||
return res.status(400).end(err.message);
|
return res.status(400).end(err.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -135,7 +150,6 @@ client.login(config.discord.token).catch(function (error) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function findEmoji(str) {
|
function findEmoji(str) {
|
||||||
const discordEmote = /<:(\w+):(\d+)>/g.exec(str)
|
const discordEmote = /<:(\w+):(\d+)>/g.exec(str)
|
||||||
if (discordEmote) {
|
if (discordEmote) {
|
||||||
|
|
Reference in a new issue