diff --git a/README.md b/README.md index 5f9f838..57f2c3f 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # Gallery Maker for Node -A Node based static html gallery maker. +Node based static html gallery maker. ## Usage ``` Usage: gallerymaker [] - will be sanitized + ".web" suffix if not provided. + defaults to sanitized + ".web" if not provided. Commands: prepare Prepares gallery file structure based on the @@ -30,9 +30,12 @@ Commands: - ~~list the images (text based)~~ - provide <img/> tag literals for copy-pasting - create the gallery - - list the images (thumbnail based) + - ~~list the images (thumbnail based)~~ + - generate actual thumbnails + - list non-image entries of a dir first so it's clear where they belong - use some lightbox on the prepared directory - further development + - ~~style the stuff a bit~~ - integration with other projects (iframe? ajax? web component? Polymer?) - ~~config.json support (for specifying conversion settings)~~ diff --git a/src/client/index.css b/src/client/index.css index 0cbe2c3..8151c47 100644 --- a/src/client/index.css +++ b/src/client/index.css @@ -1,2 +1,25 @@ -body { font-family: Tahoma, sans-serif; margin: 0; } -h1 { font-size: 24px; padding-left: 20px; } +body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; color: #333; padding: 30px; margin: 0; } +body > * { margin: 0 auto; } + +h1 { font-size: 36px; font-weight: bold; } +h2 { font-size: 24px; font-weight: normal; } +h3 { font-size: 20px; font-weight: normal; } +h4 { font-size: 16px; font-weight: normal; } +h5 { font-size: 16px; font-weight: normal; } +h6 { font-size: 16px; font-weight: normal; } + +a { color: #0A8; text-decoration: none; } +a:hover, +a:focus { color: #086; } + +.list .dir { margin-top: 15px; margin-bottom: 15px; } +.list [data-level] { margin-left: 15px; } + +.gallery, +.gallery .dir { margin-top: 40px; margin-bottom: 15px; text-align: center; } +.gallery:first-of-type { margin-top: 0; } +.gallery .name { color: #0A8; margin: 15px auto; } +.gallery .file { margin-top: 10px; margin-bottom: 10px; } +.gallery .img { display: inline-block; } +.gallery .img img { border-radius: 4px; } diff --git a/src/index.js b/src/index.js index 795592f..3bc625b 100644 --- a/src/index.js +++ b/src/index.js @@ -18,6 +18,8 @@ try { conf = require(path.join(__dirname, '..', 'config.json')); } catch (e) { conf = {}; } if (!conf.width) conf.width = 700; if (!conf.quality) conf.quality = 80; +if (!conf.thumb_width) conf.thumb_width = 100; +if (!conf.thumb_quality) conf.thumb_quality = 70; if (!conf.fnames) conf.fnames = {}; // odir if (!conf.fnames.list) conf.fnames.list = 'list.html'; if (!conf.fnames.gallery) conf.fnames.gallery = 'gallery.html'; @@ -34,6 +36,7 @@ for (var fk in conf.fnames) conf.ignored_files.push(conf.fnames[fk]); var EOL = conf.eol ? conf.eol : "\n"; var DEPTH = conf.html_init_depth ? conf.html_init_depth : 2; var SORT_DESC = conf.sort_desc ? conf.sort_desc : true; +var IMG_TYPES = ['jpeg', 'jpg', 'png', 'gif']; var log = conf.debug ? console.log.bind(console) : function () {}; var logi = function () { @@ -60,7 +63,7 @@ if (!cmd || !idir) { var help = [ 'Usage: gallerymaker []', '', - ' will be sanitized + ".web" suffix if not provided.', + ' defaults to sanitized + ".web" if not provided.', '', 'Commands:', ' prepare Prepares gallery file structure based on the ', @@ -93,15 +96,17 @@ function prepareImages() { return mirrorDirTree(idir, (file, srcDir, destDir) => { var fname = sanitize(file); var name = file.replace(/[.][^.]*$/, ''); + var extMatch = file.match(/^.*[.]([^.]*)$/); + var ext = extMatch && extMatch[1] ? extMatch[1].toLowerCase() : null; return sharp(path.join(srcDir, file)) .resize(conf.width) .quality(conf.quality) .toFile(path.join(destDir, fname)) - .then(() => ({ file: fname, name: name })) + .then(() => ({ file: fname, ext: ext, name: name })) .catch(sharpErr => utils.copyFile(srcDir, file, destDir, fname) - .then(() => ({ file: fname, name: name, warn: '' + sharpErr })) - .catch(writeErr => ({ file: '', name: name, error: writeErr })) + .then(() => ({ file: fname, ext: ext, name: name, warn: '' + sharpErr })) + .catch(writeErr => ({ file: '', ext: ext, name: name, error: writeErr })) ); }) .then(cont => utils.writeFile(cont, 'content.json', odir)) @@ -228,25 +233,47 @@ function getPageHtml(htmlPart, pageFname) { function getListEntryHtml(cont, dir, depth) { depth = depth === undefined ? 0 : depth; - + var rootClass = depth === 0 ? ' list' : ''; var html = ''; + cont.forEach(item => { var key = item.dir ? 'dir' : 'file'; - html += ind(depth) + '
' + EOL - + (item.dir ? ind(depth +1) + '
' + (item.name || item[key]) + '
' + EOL : '') + html += ind(depth) + '
' + EOL + + (item.dir ? ind(depth +1) + '
' + item[key] + '
' + EOL : '') + (item.cont ? getListEntryHtml(item.cont, dir ? path.join(dir, item.dir) : item.dir, depth +1) : ind(depth +1) + '' - + (item.name || item[key]) + '' + EOL) + + item[key] + '' + EOL) + ind(depth) + '
' + EOL }); return html; } -function getGalleryEntryHtml(cont) { - +function getGalleryEntryHtml(cont, dir, depth) { + depth = depth === undefined ? 0 : depth; + var rootClass = depth === 0 ? ' gallery' : ''; + var htag = depth + 1 <= 6 ? 'h' + (depth + 1) : 'div' var html = ''; + cont.forEach(item => { + var key = item.dir ? 'dir' : 'file'; + var isImg = IMG_TYPES.indexOf(item.ext) !== -1; + var className = (isImg ? 'img' : key) + rootClass; + + html += ind(depth) + '
' + EOL + + (item.dir ? ind(depth +1) + '<' + htag + ' class="name">' + (item.name || item[key]) + + '' + EOL : '') + + (item.cont ? getGalleryEntryHtml(item.cont, dir ? path.join(dir, item.dir) : item.dir, depth +1) + : ind(depth +1) + '' + + (isImg + ? '' + : (item.name || item[key]) + (item.ext ? ' [' + item.ext + ']' : '')) + + '' + EOL) + + ind(depth) + '
' + EOL }); return html;