diff --git a/LICENSE.txt b/LICENSE.md similarity index 100% rename from LICENSE.txt rename to LICENSE.md diff --git a/README.md b/README.md index a276c89..901afa5 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,24 @@ # jQuery.qrcode -* Website with download, docs and demo: -* Sources: +* Website with download, docs and demo: +* Sources: -jQuery.qrcode is provided under the terms of the [MIT License](http://github.com/lrsjng/jQuery.qrcode/blob/master/LICENSE.txt). - -Uses [QR Code Generator](http://www.d-project.com/qrcode/index.html) (MIT). Kudos to [jquery.qrcode.js](http://github.com/jeromeetienne/jquery-qrcode) (MIT). +jQuery.qrcode is provided under the terms of the [MIT License](https://github.com/lrsjng/jQuery.qrcode/blob/develop/LICENSE.md). +It makes use of [QR Code Generator](http://www.d-project.com/qrcode/index.html) (MIT). +Kudos to [jquery.qrcode.js](https://github.com/jeromeetienne/jquery-qrcode). ## Changelog +### v0.7.0 - *2013-08-17* + +* some fixes +* adds image support for fore- and background +* adds label and image positioning +* updates build process + + ### v0.6.0 - *2013-07-28* * adds version range diff --git a/makefile.js b/makefile.js index e13fbe5..aafb68f 100644 --- a/makefile.js +++ b/makefile.js @@ -2,152 +2,111 @@ 'use strict'; -var path = require('path'), - child_process = require('child_process'); - - -var pkg = require('./package.json'), - - root = path.resolve(__dirname), - src = path.resolve(root, 'src'), - build = path.resolve(root, 'build'), - - jshint = { - // Enforcing Options - bitwise: true, - curly: true, - eqeqeq: true, - forin: true, - latedef: true, - newcap: true, - noempty: true, - plusplus: true, - trailing: true, - undef: true, - - // Environments - browser: true, - - // Globals - predef: [ - "jQuery", "qrcode" - ] - }, - - mapperSrc = function (blob) { - - return blob.source.replace(src, build); - }, - - mapperRoot = function (blob) { +module.exports = function (make) { - return blob.source.replace(root, build); - }; + var path = require('path'), + pkg = require('./package.json'), -module.exports = function (make) { - - var Event = make.Event, $ = make.fQuery, - moment = make.moment, - stamp, replacements; + + root = path.resolve(__dirname), + src = path.join(root, 'src'), + build = path.join(root, 'build'); - make.version('>=0.8.1'); + make.version('>=0.10.0'); make.defaults('release'); make.before(function () { - stamp = moment(); + var moment = make.moment(); - replacements = { + make.env = { pkg: pkg, - stamp: stamp.format('YYYY-MM-DD HH:mm:ss') + stamp: moment.format('YYYY-MM-DD HH:mm:ss') }; - Event.info({ method: 'before', message: pkg.version + ' ' + replacements.stamp }); + $.info({ method: 'before', message: pkg.version + ' ' + make.env.stamp }); }); make.target('check-version', [], 'add git info to dev builds').async(function (done, fail) { - if (!/-dev$/.test(pkg.version)) { + if (!/\+$/.test(pkg.version)) { done(); return; } $.git(root, function (err, result) { - pkg.version += '-' + result.revListOriginMasterHead.length + '-' + result.revParseHead.slice(0, 7); - Event.info({ - method: 'check-version', - message: 'version set to ' + pkg.version - }); + pkg.version += result.buildSuffix; + $.info({ method: 'check-version', message: 'version set to ' + pkg.version }); done(); }); }); - make.target('clean', [], 'delete build folder') - .sync(function () { - - $.rmfr($.I_AM_SURE, build); - }); + make.target('clean', [], 'delete build folder').sync(function () { + $.DELETE(build); + }); - make.target('lint', [], 'lint all JavaScript files with JSHint') - .sync(function () { - $(src + ': jquery.qrcode.js') - .jshint(jshint); - }); + make.target('lint', [], 'lint all JavaScript files with JSHint').sync(function () { + + var options = { + // Enforcing Options + bitwise: true, + curly: true, + eqeqeq: true, + forin: true, + latedef: true, + newcap: true, + noempty: true, + plusplus: true, + trailing: true, + undef: true, + + // Environments + browser: true + }, + global = { + 'jQuery': true, + 'qrcode': true + }; + + $(src + ': jquery.qrcode.js, demo/scripts.js').log(-3) + .jshint(options, global); + }); - make.target('build', ['check-version'], 'build all updated files') - .sync(function () { + make.target('build', ['check-version'], 'build all updated files').sync(function () { - var scriptName = pkg.name; + $(src + ': jquery.qrcode.js') + .includify() + .handlebars(make.env) + .WRITE($.map.p(src, build).s('.js', '-' + pkg.version + '.js')) + .uglifyjs() + .WRITE($.map.p(src, build).s('.js', '-' + pkg.version + '.min.js')); - $(src + '/demo/*') - .handlebars(replacements) - .write($.OVERWRITE, mapperSrc); + $(src + ': **, ! *.js') + .handlebars(make.env) + .WRITE($.map.p(src, build)); - $(src + ': ' + scriptName + '.js') - .includify() - .handlebars(replacements) - .write($.OVERWRITE, path.join(build, scriptName + '-' + pkg.version + '.js')) - .write($.OVERWRITE, path.join(build, 'demo', scriptName + '.js')) - .uglifyjs() - .write($.OVERWRITE, path.join(build, scriptName + '-' + pkg.version + '.min.js')); + $(root + ': README*, LICENSE*') + .handlebars(make.env) + .WRITE($.map.p(root, build)); + }); - $(root + ': README*, LICENSE*') - .write($.OVERWRITE, mapperRoot); - }); + make.target('release', ['clean', 'build'], 'create a zipball').async(function (done, fail) { - make.target('release', ['clean', 'build'], 'create a zipball') - .async(function (done, fail) { - - var target = path.join(build, pkg.name + '-' + pkg.version + '.zip'), - cmd = 'zip', - args = ['-ro', target, '.'], - options = { cwd: build }, - proc = child_process.spawn(cmd, args, options); - - Event.info({ method: 'exec', message: cmd + ' ' + args.join(' ') }); - - proc.stderr.on('data', function (data) { - process.stderr.write(data); - }); - proc.on('exit', function (code) { - if (code) { - Event.error({ method: 'exec', message: cmd + ' exit code ' + code }); - fail(); - } else { - Event.ok({ method: 'exec', message: 'created zipball ' + target }); - done(); - } - }); + $(build + ': **').shzip({ + target: path.join(build, pkg.name + '-' + pkg.version + '.zip'), + dir: build, + callback: done }); + }); }; diff --git a/package.json b/package.json index df17a63..89d0b9c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,13 @@ { - "name": "jquery.qrcode", - "displayName": "jQuery.qrcode", - "version": "0.6.0" -} \ No newline at end of file + "name": "jquery.qrcode", + "displayName": "jQuery.qrcode", + "version": "0.7.0", + "description": "generate QR codes dynamically", + "url": "http://larsjung.de/qrcode/", + "author": "Lars Jung", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/lrsjng/jQuery.qrcode.git" + } +} diff --git a/src/demo/index.html b/src/demo/index.html index c802520..27902fa 100644 --- a/src/demo/index.html +++ b/src/demo/index.html @@ -15,7 +15,7 @@ - + @@ -35,14 +35,14 @@
- - - - + + + +
- +
+ + + + + + +
- - @@ -80,8 +85,6 @@
- - diff --git a/src/demo/scripts.js b/src/demo/scripts.js index f91cb7f..dc0ceed 100644 --- a/src/demo/scripts.js +++ b/src/demo/scripts.js @@ -1,93 +1,103 @@ -var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]', +(function ($) { + 'use strict'; - guiValuePairs = [ - ["size", "px"], - ["minversion", ""], - ["quiet", "modules"], - ["radius", "%"], - ["fontsize", "%"], - ["imagesize", "%"] - ], + var isOpera = Object.prototype.toString.call(window.opera) === '[object Opera]', - updateGui = function () { + guiValuePairs = [ + ["size", "px"], + ["minversion", ""], + ["quiet", " modules"], + ["radius", "%"], + ["msize", "%"], + ["mposx", "%"], + ["mposy", "%"] + ], - for (var idx in guiValuePairs) { + updateGui = function () { - var pair = guiValuePairs[idx], - $label = $('label[for="' + pair[0] + '"]'); + $.each(guiValuePairs, function (idx, pair) { - $label.text($label.text().replace(/:.*/, ': ' + $('#' + pair[0]).val() + pair[1])); - } - }, + var $label = $('label[for="' + pair[0] + '"]'); - updateQrCode = function () { + $label.text($label.text().replace(/:.*/, ': ' + $('#' + pair[0]).val() + pair[1])); + }); + }, - var options = { - render: $("#render").val(), - ecLevel: $("#eclevel").val(), - minVersion: parseInt($("#minversion").val(), 10), - color: $("#color").val(), - bgColor: $("#bg-color").val(), - text: $("#text").val(), - size: parseInt($("#size").val(), 10), - radius: parseInt($("#radius").val(), 10) * 0.01, - quiet: parseInt($("#quiet").val(), 10), + updateQrCode = function () { - mode: parseInt($("#mode").val(), 10), + var options = { + render: $("#render").val(), + ecLevel: $("#eclevel").val(), + minVersion: parseInt($("#minversion").val(), 10), - label: $("#label").val(), - labelsize: parseInt($("#fontsize").val(), 10) * 0.01, - fontname: $("#font").val(), - fontcolor: $("#fontcolor").val(), + fill: $("#fill").val(), + background: $("#background").val(), + // fill: $("#img-buffer")[0], - image: $("#img-buffer")[0], - imagesize: parseInt($("#imagesize").val(), 10) * 0.01 - }; + text: $("#text").val(), + size: parseInt($("#size").val(), 10), + radius: parseInt($("#radius").val(), 10) * 0.01, + quiet: parseInt($("#quiet").val(), 10), - $("#container").empty().qrcode(options); - }, + mode: parseInt($("#mode").val(), 10), - update = function () { + mSize: parseInt($("#msize").val(), 10) * 0.01, + mPosX: parseInt($("#mposx").val(), 10) * 0.01, + mPosY: parseInt($("#mposy").val(), 10) * 0.01, - updateGui(); - updateQrCode(); - }, + label: $("#label").val(), + fontname: $("#font").val(), + fontcolor: $("#fontcolor").val(), - onImageInput = function () { + image: $("#img-buffer")[0] + }; - var input = $("#image")[0]; + $("#container").empty().qrcode(options); + }, - if (input.files && input.files[0]) { + update = function () { - var reader = new FileReader(); + updateGui(); + updateQrCode(); + }, - reader.onload = function (event) { - $("#img-buffer").attr("src", event.target.result); - $("#mode").val("4"); - setTimeout(update, 250); - }; - reader.readAsDataURL(input.files[0]); - } - }, + onImageInput = function () { + + var input = $("#image")[0]; + + if (input.files && input.files[0]) { - download = function (event) { + var reader = new FileReader(); - var data = $("#container canvas")[0].toDataURL('image/png'); - $("#download").attr("href", data); - }; + reader.onload = function (event) { + $("#img-buffer").attr("src", event.target.result); + $("#mode").val("4"); + setTimeout(update, 250); + }; + reader.readAsDataURL(input.files[0]); + } + }, + download = function (event) { -$(function () { + var data = $("#container canvas")[0].toDataURL('image/png'); + $("#download").attr("href", data); + }; + + + $(function () { + + if (isOpera) { + $('html').addClass('opera'); + $('#radius').prop('disabled', true); + } - if (isOpera) { - $('html').addClass('opera'); - $('#radius').prop('disabled', true); - } + $("#download").on("click", download); + $("#image").on('change', onImageInput); + $("input, textarea, select").on("input change", update); + $(window).load(update); + update(); + }); - $("#download").on("click", download); - $("#image").on('change', onImageInput); - $("input, textarea, select").on("input change", update); - $(window).load(update); - update(); -}); +}(jQuery)); diff --git a/src/demo/styles.css b/src/demo/styles.css index b75470b..e36876c 100644 --- a/src/demo/styles.css +++ b/src/demo/styles.css @@ -101,10 +101,7 @@ input, textarea, select { input[type="range"] { -webkit-appearance: none; -/* height: 8px; - margin-top: 4px; - margin-bottom: 4px; -*/ cursor: pointer; + cursor: pointer; } input::-webkit-slider-thumb { -webkit-appearance: none; diff --git a/src/jquery.qrcode.js b/src/jquery.qrcode.js index 822f413..15277b8 100644 --- a/src/jquery.qrcode.js +++ b/src/jquery.qrcode.js @@ -79,16 +79,17 @@ drawBackgroundLabel = function (qr, context, settings) { - var font = "bold " + (settings.labelsize * settings.size) + "px " + settings.fontname, + var size = settings.size, + font = "bold " + (settings.mSize * size) + "px " + settings.fontname, ctx = $('')[0].getContext("2d"); ctx.font = font; var w = ctx.measureText(settings.label).width, - sh = settings.labelsize, - sw = w / settings.size, - sl = (1 - sw)/2, - st = (1 - sh)/2, + sh = settings.mSize, + sw = w / size, + sl = (1 - sw) * settings.mPosX, + st = (1 - sh) * settings.mPosY, sr = sl + sw, sb = st + sh, pad = 0.01; @@ -102,9 +103,8 @@ } context.fillStyle = settings.fontcolor; - context.textAlign = "center"; context.font = font; - context.fillText($("#label").val(), 0.5 * settings.size, 0.5 * settings.size + 0.3 * settings.labelsize * settings.size); + context.fillText(settings.label, sl*size, st*size + 0.75 * settings.mSize * size); }, drawBackgroundImage = function (qr, context, settings) { @@ -112,10 +112,10 @@ var size = settings.size, w = settings.image.naturalWidth || 1, h = settings.image.naturalHeight || 1, - sh = settings.imagesize, + sh = settings.mSize, sw = sh * w / h, - sl = (1 - sw)/2, - st = (1 - sh)/2, + sl = (1 - sw) * settings.mPosX, + st = (1 - sh) * settings.mPosY, sr = sl + sw, sb = st + sh, pad = 0.01; @@ -133,8 +133,10 @@ drawBackground = function (qr, context, settings) { - if (settings.bgColor) { - context.fillStyle = settings.bgColor; + if ($(settings.background).is('img')) { + context.drawImage(settings.background, 0, 0, settings.size, settings.size); + } else if (settings.background) { + context.fillStyle = settings.background; context.fillRect(settings.left, settings.top, settings.size, settings.size); } @@ -270,8 +272,22 @@ fn(qr, context, settings, l, t, w, row, col); } } - context.fillStyle = settings.color; - context.fill(); + if ($(settings.fill).is('img')) { + context.strokeStyle = 'rgba(0,0,0,0.5)'; + context.lineWidth = 2; + context.stroke(); + var prev = context.globalCompositeOperation; + context.globalCompositeOperation = "destination-out"; + context.fill(); + context.globalCompositeOperation = prev; + + context.clip(); + context.drawImage(settings.fill, 0, 0, settings.size, settings.size); + context.restore(); + } else { + context.fillStyle = settings.fill; + context.fill(); + } }, // Draws QR code to the given `canvas` and returns it. @@ -314,7 +330,7 @@ // some shortcuts to improve compression var settings_size = settings.size, - settings_bgColor = settings.bgColor, + settings_bgColor = settings.background, math_floor = Math.floor, moduleCount = qr.moduleCount, @@ -338,7 +354,7 @@ margin: 0, width: moduleSize, height: moduleSize, - 'background-color': settings.color + 'background-color': settings.fill }, $div = $('
').data('qrcode', qr).css(containerCSS); @@ -399,11 +415,11 @@ // size in pixel size: 200, - // code color - color: '#000', + // code color or image element + fill: '#000', - // background color, `null` for transparent background - bgColor: null, + // background color or image element, `null` for transparent background + background: null, // content text: 'no text', @@ -422,13 +438,15 @@ // 4: image box mode: 0, + mSize: 0.1, + mPosX: 0.5, + mPosY: 0.5, + label: 'no label', - labelsize: 0.1, fontname: 'sans', fontcolor: '#000', - image: null, - imagesize: 0.1 + image: null }; // Register the plugin