diff --git a/js/fox-america.js b/js/fox-america.js deleted file mode 100644 index 572ef0a..0000000 --- a/js/fox-america.js +++ /dev/null @@ -1,118 +0,0 @@ -const Chance = require('chance') -const colors = require('./constants/colors.js') - -const hsl = function (h, s, l) { - return 'hsl(' + h + ',' + s + '%, ' + l + '%)' -} - -const Fox = function (IMG_WIDTH, IMG_HEIGHT, seed) { - const chance = seed ? new Chance(seed) : new Chance() - - // origin: head top left corner - const kappa = chance.floating({min: 0.2, max: 0.45}) - - chance.bool() - chance.bool() - - const headColor = (function () { - const level = chance.floating({min: 0, max: 1}) - const result = [] - const min = colors.head.brick - const max = colors.head.yellow - for (let i = 0; i < min.length; i++) { - result.push(min[i] + (max[i] - min[i]) * level) - } - return hsl.apply(null, result) - })() - - const head = { - width: 0.6 * IMG_WIDTH, - height: 0.6 * IMG_HEIGHT, - kappa: kappa, - color: headColor - } - - const origin = {x: IMG_WIDTH / 2 - head.width / 2, y: 0.5 * IMG_HEIGHT - head.height / 2} - - const ears = (function (origin, headWidth, headHeight, headColor) { - const offsetX = chance.floating({min: 0.17 * headWidth, max: 0.2 * headWidth}) - const angle = chance.floating({min: 0.05 * Math.PI, max: 0.2 * Math.PI}) - return { - color: headColor, - kappa: 0.9 * kappa, - left: { - x: origin.x + (headWidth / 2) - offsetX, - y: origin.y + (0.15 * headHeight), - angle: angle, - width: 0.4 * headWidth, - height: 0.8 * headHeight - }, - right: { - x: origin.x + (headWidth / 2) + offsetX, - y: origin.y + (0.15 * headHeight), - angle: -angle, - width: 0.4 * headWidth, - height: 0.8 * headHeight - } - } - }(origin, head.width, head.height, head.color)) - - const eyes = (function (origin, headWidth, headHeight) { - // TODO: color - const offsetY = chance.floating({min: -0.05 * headHeight, max: -0.025 * headHeight}) - const offsetX = chance.floating({min: 0.13 * headWidth, max: 0.25 * headWidth}) - - const eyeHeight = chance.floating({min: 0.08 * headHeight, max: 0.13 * headHeight}) - - return { - height: eyeHeight, - width: eyeHeight / 2, - style: 'ellipse', - // style: chance.pickone(['ellipse', 'smiley']), - left: { - x: origin.x + (headWidth / 2) - offsetX, - y: origin.y + (headHeight / 2) + offsetY - }, - right: { - x: origin.x + (headWidth / 2) + offsetX, - y: origin.y + (headHeight / 2) + offsetY - } - } - }(origin, head.width, head.height)) - - const nose = { - x: origin.x + (head.width / 2), - y: (eyes.left.y + chance.floating({min: 0.2, max: 0.4}) * (origin.y + head.height - eyes.left.y)), - width: chance.floating({min: 0.03, max: 0.04}) * head.width, - height: chance.floating({min: 0.03, max: 0.04}) * head.width - } - - const mouth = { - x: origin.x + (head.width / 2), - y: (nose.y + chance.floating({min: 0.2, max: 0.35}) * (origin.y + head.height - nose.y)), - width: chance.floating({min: 0.08, max: 0.15}) * head.width, - height: chance.floating({min: 0.03, max: 0.06}) * head.width, - style: chance.pickone(['smirk', 'cat', 'none']) - } - - const mask = { - width: chance.floating({min: 0.5 * IMG_WIDTH, max: IMG_WIDTH}), - height: chance.floating({min: 1.7 * (IMG_HEIGHT - eyes.left.y), max: 1.85 * (IMG_HEIGHT - eyes.left.y)}) - } - head.mask = mask - - return { - canvas: { - height: IMG_HEIGHT, - width: IMG_WIDTH, - color: chance.pickone(Object.keys(colors.bg).map(function (key) { return colors.bg[key] })) - }, - head: head, - ears: ears, - eyes: eyes, - nose: nose, - mouth: mouth - } -} - -module.exports = Fox diff --git a/js/fox.js b/js/fox.js index 42cf85b..572ef0a 100644 --- a/js/fox.js +++ b/js/fox.js @@ -1,4 +1,5 @@ const Chance = require('chance') +const colors = require('./constants/colors.js') const hsl = function (h, s, l) { return 'hsl(' + h + ',' + s + '%, ' + l + '%)' @@ -10,15 +11,25 @@ const Fox = function (IMG_WIDTH, IMG_HEIGHT, seed) { // origin: head top left corner const kappa = chance.floating({min: 0.2, max: 0.45}) - const hue = chance.integer({min: 5, max: 50}) - const saturation = chance.integer({min: 70, max: 90}) - const lightness = chance.integer({min: 40, max: 60}) + chance.bool() + chance.bool() + + const headColor = (function () { + const level = chance.floating({min: 0, max: 1}) + const result = [] + const min = colors.head.brick + const max = colors.head.yellow + for (let i = 0; i < min.length; i++) { + result.push(min[i] + (max[i] - min[i]) * level) + } + return hsl.apply(null, result) + })() const head = { width: 0.6 * IMG_WIDTH, height: 0.6 * IMG_HEIGHT, kappa: kappa, - color: hsl(hue, saturation, lightness) + color: headColor } const origin = {x: IMG_WIDTH / 2 - head.width / 2, y: 0.5 * IMG_HEIGHT - head.height / 2} @@ -94,11 +105,7 @@ const Fox = function (IMG_WIDTH, IMG_HEIGHT, seed) { canvas: { height: IMG_HEIGHT, width: IMG_WIDTH, - color: hsl( - chance.integer({min: 0, max: 360}), - chance.integer({min: 0, max: 100}), - chance.integer({min: 10, max: 100}) - ) + color: chance.pickone(Object.keys(colors.bg).map(function (key) { return colors.bg[key] })) }, head: head, ears: ears, diff --git a/js/render-fox.js b/js/render-fox.js index ee51983..4a64ef6 100644 --- a/js/render-fox.js +++ b/js/render-fox.js @@ -1,7 +1,9 @@ const renderFox = function (canvas, opts) { const width = opts.canvas.width const height = opts.canvas.height - const ctx = canvas.getContext('2d') + const ctx = canvas.getContext('2d', { + pixelFormat: 'RGB16_565', + }) ctx.fillStyle = opts.canvas.color ctx.fillRect(0, 0, width, height) diff --git a/package.json b/package.json index e4bb160..3661d48 100644 --- a/package.json +++ b/package.json @@ -18,18 +18,18 @@ }, "homepage": "https://github.com/Patreon/foxy-moxy#readme", "dependencies": { - "canvas": "^1.6.2", - "chance": "^1.0.4", + "canvas": "^2.0.1", + "chance": "^1.0.16", "connect-datadog": "*", - "express": "^4.14.0", + "express": "^4.16.4", "express-cluster": "0.0.4", - "node-gyp": "^3.4.0", + "node-gyp": "^3.8.0", "sanitize-filename": "^1.6.1", - "uuid": "^3.0.1" + "uuid": "^3.3.2" }, "devDependencies": { - "mocha": "^3.4.2", - "sharp": "^0.18.1", - "supertest": "^3.0.0" + "mocha": "^5.2.0", + "sharp": "^0.18.4", + "supertest": "^3.3.0" } } diff --git a/server.js b/server.js index 4565568..da9ba1f 100644 --- a/server.js +++ b/server.js @@ -5,22 +5,12 @@ const sanitize = require('sanitize-filename') const Canvas = require('canvas') const Fox = require('./js/fox.js') -const FoxAmerica = require('./js/fox-america.js') const renderFox = require('./js/render-fox.js') function composeImage (width, height, seed, version) { seed = seed || uuid() - let fox - switch (version) { - case 2: - // America-color bg and fox - fox = FoxAmerica(width, height, seed) - break - default: - // original fox - fox = Fox(width, height, seed) - } - const canvas = new Canvas(width, height) + const fox = Fox(width, height, seed) + const canvas = Canvas.createCanvas(width, height) renderFox(canvas, fox) return canvas } @@ -30,7 +20,7 @@ function getFox (req, res, version) { if (width > 400) width = 400 const seed = sanitize(req.params.seed) || uuid() const canvas = composeImage(width, width, seed, version) - const buffer = canvas.toBuffer() + const buffer = canvas.toBuffer('image/png') res.set('Cache-Control', 'max-age=' + cacheTimeout) res.set('Content-length', buffer.length) res.type('png') @@ -46,11 +36,11 @@ app.get('/healthcheck', (req, res) => { }) app.get('/:width/:seed', (req, res) => { - getFox(req, res, 1) + getFox(req, res) }) app.get('/2/:width/:seed', (req, res) => { - getFox(req, res, 2) + getFox(req, res) }) module.exports = app