From d8c3f6c8254290c0fe98af20249d0adfabb2ec80 Mon Sep 17 00:00:00 2001 From: Ruben Soler Date: Tue, 26 Sep 2017 18:02:07 +0200 Subject: [PATCH 1/2] feat: image background --- app.js | 9 +++- countdown-generator/index.js | 82 +++++++++++++++++++++-------------- images/bg-image.jpg | Bin 0 -> 12022 bytes images/ex1.gif | Bin 0 -> 67549 bytes package.json | 8 ++-- public/index.html | 1 + 6 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 images/bg-image.jpg create mode 100644 images/ex1.gif diff --git a/app.js b/app.js index 3f02a61..bb8dc56 100644 --- a/app.js +++ b/app.js @@ -7,6 +7,8 @@ const path = require('path'); const tmpDir = __dirname + '/tmp/'; const publicDir = __dirname + '/public/'; +const imagesDir = __dirname + '/images/'; +const defaultBgImage = 'bg-image.jpg'; // canvas generator const CountdownGenerator = require('./countdown-generator'); @@ -41,13 +43,16 @@ app.get('/serve', function (req, res) { throw Error('Time parameter is required.'); } - CountdownGenerator.init(time, width, height, color, bg, name, frames, () => { + const imageBgSrc = `${imagesDir}${defaultBgImage}`; + + + CountdownGenerator.init(time, width, height, color, bg, name, imageBgSrc, frames, () => { let filePath = tmpDir + name + '.gif'; res.sendFile(filePath); }); }); -app.listen(process.env.PORT || 3000, function(){ +app.listen(process.env.PORT || 3500, function(){ console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env); }); diff --git a/countdown-generator/index.js b/countdown-generator/index.js index 1e778f1..3880b42 100644 --- a/countdown-generator/index.js +++ b/countdown-generator/index.js @@ -18,29 +18,40 @@ module.exports = { * @param {number} frames * @param {requestCallback} cb - The callback that is run once complete. */ - init: function(time, width=200, height=200, color='ffffff', bg='000000', name='default', frames=30, cb){ + init: function (time, width = 200, height = 200, color = 'ffffff', bg = '000000', name = 'default', imageBgSrc, frames = 30, cb) { // Set some sensible upper / lower bounds this.width = this.clamp(width, 150, 500); this.height = this.clamp(height, 150, 500); this.frames = this.clamp(frames, 1, 90); - - this.bg = '#' + bg; + + // this.bg = '#' + bg; this.textColor = '#' + color; this.name = name; - + // loop optimisations this.halfWidth = Number(this.width / 2); this.halfHeight = Number(this.height / 2); - + this.encoder = new GIFEncoder(this.width, this.height); this.canvas = new Canvas(this.width, this.height); this.ctx = this.canvas.getContext('2d'); - + + var $this = this; + // calculate the time difference (if any) let timeResult = this.time(time); - + // start the gif encoder - this.encode(timeResult, cb); + if (imageBgSrc) { + fs.readFile(imageBgSrc, function (err, image) { + if (err) throw err; + var img = new Canvas.Image; + img.src = image; + $this.encode(timeResult, img, cb); + }); + } else { + this.encode(timeResult, null, cb); + } }, /** * Limit a value between a min / max @@ -50,7 +61,7 @@ module.exports = { * @param max - maximum value number can have * @returns {number} */ - clamp: function(number, min, max){ + clamp: function (number, min, max) { return Math.max(min, Math.min(number, max)); }, /** @@ -62,12 +73,12 @@ module.exports = { // grab the current and target time let target = moment(timeString); let current = moment(); - + // difference between the 2 (in ms) let difference = target.diff(current); - + // either the date has passed, or we have a difference - if(difference <= 0){ + if (difference <= 0) { return 'Date has passed!'; } else { // duration of the difference @@ -79,37 +90,38 @@ module.exports = { * @param {string|Object} timeResult - either the date passed string, or a valid moment duration object * @param {requestCallback} cb - the callback to be run once complete */ - encode: function(timeResult, cb){ + encode: function (timeResult, image, cb) { let enc = this.encoder; let ctx = this.ctx; let tmpDir = process.cwd() + '/tmp/'; // create the tmp directory if it doesn't exist - if (!fs.existsSync(tmpDir)){ + if (!fs.existsSync(tmpDir)) { fs.mkdirSync(tmpDir); } - + let filePath = tmpDir + this.name + '.gif'; - + // pipe the image to the filesystem to be written let imageStream = enc - .createReadStream() - .pipe(fs.createWriteStream(filePath)); + .createReadStream() + .pipe(fs.createWriteStream(filePath)); // once finised, generate or serve imageStream.on('finish', () => { // only execute callback if it is a function typeof cb === 'function' && cb(); }); - + // estimate the font size based on the provided width let fontSize = Math.floor(this.width / 12) + 'px'; - let fontFamily = 'Courier New'; // monospace works slightly better - + let fontFamily = 'Roboto'; // monospace works slightly better + // set the font style ctx.font = [fontSize, fontFamily].join(' '); ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; + // start encoding gif with following settings enc.start(); enc.setRepeat(0); @@ -117,51 +129,55 @@ module.exports = { enc.setQuality(10); // if we have a moment duration object - if(typeof timeResult === 'object'){ - for(let i = 0; i < this.frames; i++){ + if (typeof timeResult === 'object') { + for (let i = 0; i < this.frames; i++) { // extract the information we need from the duration let days = Math.floor(timeResult.asDays()); let hours = Math.floor(timeResult.asHours() - (days * 24)); let minutes = Math.floor(timeResult.asMinutes()) - (days * 24 * 60) - (hours * 60); let seconds = Math.floor(timeResult.asSeconds()) - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60); - + // make sure we have at least 2 characters in the string days = (days.toString().length == 1) ? '0' + days : days; hours = (hours.toString().length == 1) ? '0' + hours : hours; minutes = (minutes.toString().length == 1) ? '0' + minutes : minutes; seconds = (seconds.toString().length == 1) ? '0' + seconds : seconds; - + // build the date string let string = [days, 'd ', hours, 'h ', minutes, 'm ', seconds, 's'].join(''); - + // paint BG ctx.fillStyle = this.bg; ctx.fillRect(0, 0, this.width, this.height); - + if (image) { + ctx.drawImage(image, 0, 0, this.width, this.height) + } // paint text ctx.fillStyle = this.textColor; ctx.fillText(string, this.halfWidth, this.halfHeight); - + // add finalised frame to the gif enc.addFrame(ctx); - + // remove a second for the next loop timeResult.subtract(1, 'seconds'); } } else { // Date has passed so only using a string - + // BG ctx.fillStyle = this.bg; ctx.fillRect(0, 0, this.width, this.height); - + // Text ctx.fillStyle = this.textColor; ctx.fillText(timeResult, this.halfWidth, this.halfHeight); enc.addFrame(ctx); } - - // finish the gif + enc.finish(); + + // finish the gif + } }; diff --git a/images/bg-image.jpg b/images/bg-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f3fbee453e36c87b962f179c077cbfecad66f6dc GIT binary patch literal 12022 zcmbW7by!s0_vi1Id)=^Bt2I;17Up&7uDlCB{nq+Su}R!T~` zyOj`ryx-rA=ed8~d-sWFKhIfbo%LCJ@3qfaXWvcVEdd^?E2}93aBu(socj%McMFhu z4p)*l(1A;`I@&#T_ON$k^%W8jWaakpLby4ys;R56s_QDLu=zGQNPL|C6u|!|IJoyV5)cwSASSsNXm|*~#Q_3w@qqtYeJ>q+e;t5FiBH8Q zBu_xCXHCeC1PO;HeUc7j-KK16E1EZUWllexCB)4xuTM? zimIBrzJZ~UvB?WlTRVFPM<;}{m$#3vpMOAL*DXD4b^o-2+nEZmmqT-U$ zvhq)L^$m@mo0?m`b#`_4^!D`+jEzrBPW_yonO$C4U0dJS+}hqbJ~=%*zxe&<^6FnM z902gYvF^|R4fcO<26!S%a8fRuRnY(fN7@_K~UNNRTBa3YXG^2gea z2OJ{sBN`jeAHke@dyzbw?~CTrgg)ZYPe@2la)jgAZ9%(!bY zc6yRpB|3FV|K1Jz^y&_)my1yATQ%lN&&dhY9d#)F`I zNdaR{DGt7Cpw7LM>7aLjVw==k%6(Yk88_^38tW6A8>mltR^)l_w0k`&G4%%*f}xAG zs?t&=ezlSJK+}{g&$UfzB;oklECZ;}KPvT$mq(xP0PX+Lb8qorRMQ=x(WX(+&L^)M zBVbu~?_QQ$%3+94&Hoe|7H^1e|9ef-ShEDblufIG7u}OTOvqxFQBnU?dmVyijp3Rt z-sCFNACyfyWIeCQF~oi5EPyZn;82?qY1C!z!J`PvmI~MJhZYI`u26F^2Zd;*23th<=yeMzRH%!EMBy!DG2E52qRB;Bx3>HlzQ6Xqp zMnZn}`Zc`i%#7v&%+n#v`!zAnFCD4WV?=Ut{T)PHyUwC+`E2$bs=5vm;Lpt4i{6j( zhy`jAe-xRG1oQsPkbeikF?QflKpH73XIazTrp2kD+uGvv9`TN5baN*{%nOZ8Y7o0D zq7sRqWiXl6Fg0KO>tmJlAj9nZENVi41A4}fmoA>|xzUV>Dm7tV{%W%cPqzTs3!ymc zxOeIHmrrtP!31N@WAc9{@}`(y>-=fye946} z^y?CwhzLt`N-wbq$)9EZ2G9ugdw6~j$%j7!l2A86*y zGpJ{)#Lfdz^+UDvDF^xMuTs_O`-`TriZH*(go2NiYSjg&Cgn@u$sg+fIQ(6+hNI~! zI5JKWi@-0=Do&MJj95Li5%--Vkk?pxtTZ}fpaPd)zpcE=PKxGri-!XK3(AXbumyJ$ zdpjEQ5^cp*T69vn@tiNVl+v*J*=#sCNN*_G@MP;`6lv5}nUF?w+0FEgFSaR9Dee=; zMuwvdchkTM|9AFbQxzMb;`0Y^d_T|%JY_`@e@iui`(l&VVmaxpUH+ljN`%(^tv zS@77VifH~ZqA*aEa4tGh`^0%M10&t`!-JOyp~&f5VI%o6YaI9APzk6|5E_1#(M^k6 z`o_2D;i=IZTgV~5t`v=Q)kHpkJfOltmmtGINU0~4FF;0Un1E@r`WYy|`yC%qjpSJD zU*|R7VQx-a@Oj`3l)<`To>p}?6Kd-m@WjZBe61fUi*>bru7WDoJ95q8&Tl%`vp|Vo?RQp6*qWXz+?etcv=P&e4i+^7K3r$ppdkQ*mYjI8bq;xi_xHtI6RPbM@t@p%kv@#*dfaM$#Z?j ztVqDZEeZ(cK6$%uG{D`%eNtf$vAx%W>nI7Z8s8*`7mqrNfxlG+*d#s! zdBrQ1a*XP!bM!jbt#4$nTa9h9uo);Vq^V%)IYuD?-j@fa;gmDgrVDL2@*n|rzQeB&Y7bhCa)kJUzhl~iN@h7X_kPqVDhGSGJg~8)_skaT zRCnGKXd0HLaIPyMB6=z~|A2`+zp;wnySt8=nv3hoZw@CVLGZ#k-!S+5Op5yD7Lt5sB7Oz7|^;R0r~{82UxODXh(}PL* zJ=FVVua8qKP&Y4uF;(CEWyIR6nNjDcBL0~^EYFCJmt<1n48=fhm@j&Bsz7xk*Dt-b z@$`@WTgo0f%2w&PpV{Kg#2*?vugAoM{R`FnP|0IylBua#LHeGJ#m?EkqWHoD{b5Di z7C{)*x9M61DS@ODL&fZB%V{TM0-k?!S{WGZvzvUy*`odRr-KnK-C4fl_;E_egm=Sc ziDvc9PP!fIfvCtlGfClh>(nY(Nk|< zCyu6no;QRX78v2~L_N~4Ka;IL0)_!P1LK$#BOq0u`L|mPTGDozY)Ni(5U60Vsi@uv~F%6!4;w~N|3DQa;Q3ok#u>)p7%+BJU9ZyrD*mxul z6LS0rD^nk9z|msF+t5}k|4*2uPN2^IBV7WzU|y2+rc;AHPb4bPK&x3tngRK9g{jDu z@`N_=4&bzX*f31$6z}EY0xDKZc{=#COJ#jlg_m5u<2TJ=4$Gfpmud}ncf2qQN&Ecw zs8=brvKADa7o+NbB6{`OkM>U@i7lK3qm^7T^;Tbn)&yp4(vKi9Gvntk9fIwB-hSxi%`^J)Tz7>U+t8U?QWncbUHS4P|_>&G2}m;`M^Tqw--1d;UH` zz3_ff@cU!&PFl&34?%yc9oL;-&(wYS!97AQk`R;NvND)EOWQ?@Sxf&-HEl6#F3>-T zjY}u%B*3ZBu?RF4DKl?aqdGvy_PR7Y#fCq|EgKn1k{AT`n&$*mBR0KCKv|*^&h|*R zql_Ei8QLe^02g1EsE@C&+ek!g#l&Yf*^<+LuxEkYlH`xg*iS<<8bj)~N2#eiz=PM* zUjY3t4*ILUF|0Kb)};mb4A{ptXYrvFSiC72lF42@syUf%Kifz zTFNntMS2EHvY6s6EX4pWR?r1LZmL`p#-mrp`)>*5i@40n4>3_!Bm_{Z3?k%{Fo;y>R)>L`{bV$iC^g{-@}ZG4GryI|@*3 zRq?2M#-hTw(mG`pRWOgT2lD4^ z1)+?Tez?T%-$g@LY56UWFjI!`-Y`kjsVWKwzkhCjs^X^W92Q<^<&~4xoNFYjG(D+Y z&lAB2TPVd*v{74(`*=#F%BhcjPcF~;yVTSNGG6LKq2LFz#N39 zVztwSsLdBr0P9&V*Zl;RJ={>Y6;RnOKCeIJV;ShX2S@)FqlKq@x8Y$Nl%^S`wxC*3 zAfmernu7W`^p~_Pa>D}+PS~5TAFXAK*mMF?bDB%u6|%a&sl!2S)V+C=Lnaa9=11(S z0GAE=6L6Hed317C|L zEb4upJah|3JT!Yb<6JeojyiZ*xWp8-n^PF{v-(CRart+r4zZbksK!w~2_K?3{o%z@ z64(ft8ljB?K2C#?u$4AM0Pz)O`PyO%<~lKQM#ak`8{< zFw=KzXj7RYD|!crW^oer$1eXoCkZB3W5$TQN@`(l}7?TB`m(?^=&njx59Iq#BJes5sr%IH<2`6({Be@9^Ha@j$Z!|~+4 zo5AbqXE)S$0J+H=v!-ev;Z83VDwD6}{;bH&GQ1;gL6IFkG50@DZWEWyG_dZb$JsYV zQ%P-A-v)#SXw;bA9)}Tb@$EWc?NkPOaKM!+rxjy5US7cGV*Pp65h>yWDovxJ72i5q zv+e+<6|Tw08n+#okfP=DAa}aml-W*_Zt$?^led#2N7JVSKszd;Rp57Haq+#+)uA?K zbK)pb>kB7MU4``WWJPRe0@o@BM@isc94#}w&jyrg#O(3!=;A#9OgQ^-wG^=eHnEi# zkHkqP(i2%q)Mr5jH1?rw8)Zg?Ia%#~H`L3PBsY-b+{m+;r?x-$&;3_fdqnB7WET$v z$O!;DTF%ejeBrSqz%0sH<0j3-5qN*y9T7>mVLG;S?X5OlqW31@CvTD;pW`!C=`q@i zWYCie#AgkEdDLZ4LPI2$aw`2

Sgp$`yKW2k4L`_)>R#ILm%5mR%fc7@MhDClVAM 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 literal 0 HcmV?d00001 diff --git a/images/ex1.gif b/images/ex1.gif new file mode 100644 index 0000000000000000000000000000000000000000..13522db6ddacebfaf881837bb0f7c4b85590cf66 GIT binary patch literal 67549 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 + From 62dfd579c113d80044bcaa377d715fda9192a8ff Mon Sep 17 00:00:00 2001 From: Ruben Soler Date: Tue, 26 Sep 2017 18:09:56 +0200 Subject: [PATCH 2/2] feat: imageBg optional --- app.js | 13 ++++++++----- countdown-generator/index.js | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index bb8dc56..b37c112 100644 --- a/app.js +++ b/app.js @@ -23,21 +23,24 @@ app.get('/', function (req, res) { // generate and download the gif app.get('/generate', function (req, res) { - let {time, width, height, color, bg, name, frames} = req.query; + let {time, width, height, color, bg, name, withImageBg, frames} = req.query; if(!time){ throw Error('Time parameter is required.'); } - CountdownGenerator.init(time, width, height, color, bg, name, frames, () => { + const imageBgSrc = `${imagesDir}${defaultBgImage}`; + + + CountdownGenerator.init(time, width, height, color, bg, name, (withImageBg ? imageBgSrc : null), frames, () => { let filePath = tmpDir + name + '.gif'; - res.download(filePath); + res.sendFile(filePath); }); }); // serve the gif to a browser app.get('/serve', function (req, res) { - let {time, width, height, color, bg, name, frames} = req.query; + let {time, width, height, color, bg, name, withImageBg, frames} = req.query; if(!time){ throw Error('Time parameter is required.'); @@ -46,7 +49,7 @@ app.get('/serve', function (req, res) { const imageBgSrc = `${imagesDir}${defaultBgImage}`; - CountdownGenerator.init(time, width, height, color, bg, name, imageBgSrc, frames, () => { + CountdownGenerator.init(time, width, height, color, bg, name, (withImageBg ? imageBgSrc : null), frames, () => { let filePath = tmpDir + name + '.gif'; res.sendFile(filePath); }); diff --git a/countdown-generator/index.js b/countdown-generator/index.js index 3880b42..2b9243f 100644 --- a/countdown-generator/index.js +++ b/countdown-generator/index.js @@ -24,7 +24,7 @@ module.exports = { this.height = this.clamp(height, 150, 500); this.frames = this.clamp(frames, 1, 90); - // this.bg = '#' + bg; + this.bg = '#' + bg; this.textColor = '#' + color; this.name = name; @@ -42,7 +42,7 @@ module.exports = { let timeResult = this.time(time); // start the gif encoder - if (imageBgSrc) { + if (imageBgSrc !== null) { fs.readFile(imageBgSrc, function (err, image) { if (err) throw err; var img = new Canvas.Image; @@ -149,7 +149,7 @@ module.exports = { // paint BG ctx.fillStyle = this.bg; ctx.fillRect(0, 0, this.width, this.height); - if (image) { + if (image !== null) { ctx.drawImage(image, 0, 0, this.width, this.height) } // paint text