import dti from 'dom-to-image'; import './Label.html'; import PDF from 'jspdf'; import { saveAs } from 'file-saver'; import swal from 'sweetalert2'; import dragula from 'dragula'; //import JsBarcode from 'JsBarcode'; import QRCode from '/imports/util/qrcode/qrcode'; //let QRCode = require('/imports/util/qrcode/qrcode.js'); console.log(QRCode); //let {qrcode, svg2url} = require('pure-svg-code'); //let QRCode = require('qrcode-svg'); //****************************************************************** //** Creates printable labels for a roll style printer. //****************************************************************** let PREFIX = "LabelMaker_"; let PX_PER_MM = 300 / 25.4; let SCREEN_PX_PER_MM = 96 / 25.4; let imagePath = "/images/3x2 Label Logo BW.svg";//"/images/Logo_0.8x0.73_300ppi.png"; function generateLabels(title1, title2, ingredients, date, count, topSpacing, bottomSpacing) { //TODO: Allow logo to be removed or altered with an alternative logo for sizing fixes let label = "
" + "
" + //"
" + //"" + "" + //"
We grow it. We can it.
" + "
" + title1 + "
" + "
" + (title2 === undefined ? "" : title2) + "
" + "
Ingredients:" + ingredients + "
" + "
*grown by us 8oz FD1951 (" + date + ")
" + "
Refrigerate after opening; return jar when done
" + "
18601 Hwy 128, Yorkville, CA 95494
" + "
www.PetitTeton.com
" + //"
" + "
"; let labels = ""; //TODO: Include bar code and identifying numbers. for(let i = 0; i < count; i++) { labels += label; } return labels; } function printImageOld(template, dataUrl) { let img = new Image(); img.onload = function() { let imageCanvas = $('.labelCanvas')[0]; let ctx = imageCanvas.getContext('2d'); //let threshold = 255 + 200 + 0; let desiredContrast = 100; let contrastCorrectionFactor = (259 * (desiredContrast + 255)) / (255 * (259 - desiredContrast)); imageCanvas.width = img.width; imageCanvas.height = img.height; //console.log("Generated image: " + img.width + ", " + img.height); //ctx.scale(0.25, 0.25); ctx.drawImage(img, 0, 0); let imageData = ctx.getImageData(0, 0, imageCanvas.width, imageCanvas.height); let data = imageData.data; //Run three times for(let c = 0; c < 3; c++) { //Set each pixel to either black or white with the given threshold. for(let i = 0; i < data.length; i += 4) { data[i] = contrastCorrectionFactor * (data[i] - 128) + 128; data[i + 1] = contrastCorrectionFactor * (data[i + 1] - 128) + 128; data[i + 2] = contrastCorrectionFactor * (data[i + 2] - 128) + 128; //if(data[i] + data[i + 1] + data[i + 2] < threshold) { // data[i] = 0; // data[i + 1] = 0; // data[i + 2] = 0; //} //else { // data[i] = 255; // data[i + 1] = 255; // data[i + 2] = 255; //} data[i + 3] = 255; } } ctx.putImageData(imageData, 0, 0); //Convert the canvas content to an image for printing. (cannot print a canvas?) //sendToPrinter(template, imageCanvas.toDataURL("image/png")); //Save to disk. //imageCanvas.toBlob(function(blob) { // saveAs(blob, "label.png"); //}, "image/png", 1); //imageCanvas.toBlob(function(blob) { // let url = URL.createObjectURL(blob); // window.open(url, "_blank"); //}, "image/png", 1); //let imgData = imageCanvas.toDataURL('image/jpeg', 1.0); imageCanvas.toBlob(function(blob) { let pdf = new PDF(); let url = URL.createObjectURL(blob); pdf.addImage(url, "image/png", 0, 0); pdf.save("label.pdf"); }, "image/png", 1); }; img.src = dataUrl; } function printImage(template, raw, width, height) { let data = raw; //Run three times for(let c = 0; c < 3; c++) { //Set each pixel to either black or white with the given threshold. for(let i = 0; i < data.length; i += 4) { data[i] = contrastCorrectionFactor * (data[i] - 128) + 128; data[i + 1] = contrastCorrectionFactor * (data[i + 1] - 128) + 128; data[i + 2] = contrastCorrectionFactor * (data[i + 2] - 128) + 128; //if(data[i] + data[i + 1] + data[i + 2] < threshold) { // data[i] = 0; // data[i + 1] = 0; // data[i + 2] = 0; //} //else { // data[i] = 255; // data[i + 1] = 255; // data[i + 2] = 255; //} data[i + 3] = 255; } } let url = URL.createObjectURL(new Blob(raw, {type: "image/png"})); let test = new Image(); test.src = url; $('.testImage').html(test); } // Note: Not working correctly. Output seems to be at 96dpi instead of 300+dpi. Using a large image scaled down in in an Image tag seems to not print well. function sendToPrinter(template, dataUrl) { let canvasImg = new Image(); canvasImg.onload = function() { //window.print(); }; canvasImg.src = dataUrl; canvasImg.style.height = template.labelHeight.get() + "mm"; canvasImg.style.width = template.labelWidth.get() + "mm"; $(".printableLabel").html(canvasImg); //$('.printableLabel').html(img); window.print(); } function loadImage(url) { return new Promise(r => { let i = new Image(); i.onload = (() => r(i)); i.src = url; }); } async function refreshLabelCanvas(template) { let mmWidth = template.labelWidth.get(); let mmHeight = template.labelHeight.get(); let title1 = template.title1.get(); let title1Font = template.title1Font.get(); let title1YOffset = template.title1YOffset.get(); let title2 = template.title2.get(); let title2Font = template.title2Font.get(); let title2YOffset = template.title2YOffset.get(); let ingredients = template.ingredients.get(); let ingredientsFont = template.ingredientsFont.get(); let ingredientsYOffset = template.ingredientsYOffset.get(); let date = template.date.get(); let $labelCanvas = $('.labelCanvas'); let ctx = $labelCanvas[0].getContext('2d'); let width = Math.floor(mmWidth * PX_PER_MM); let height = Math.floor(mmHeight * PX_PER_MM); let center = width / 2; let img = await loadImage(imagePath); let imageWidth = 241; let imageHeight = 219; let ingredientsY = 180; let ingredientsEndingY = 240; let instructionsY = 280; let addressY = 320; let websiteY = 380; ctx.fillStyle = 'white'; ctx.fillRect(0,0, width, height); ctx.fillStyle = 'black'; ctx.drawImage(img, center - (imageWidth / 2), 0); ctx.font = title1Font; ctx.textAlign = 'center'; ctx.fillText(title1, center, title1YOffset); ////TODO: Allow logo to be removed or altered with an alternative logo for sizing fixes //let label = "
" + // "
" + // //"" + // "" + // "
We grow it. We can it.
" + // "
" + title1 + "
" + // "
" + (title2 === undefined ? "" : title2) + "
" + // "
Ingredients:" + ingredients + "
" + // "
*grown by us 8oz FD1951 (" + date + ")
" + // "
Refrigerate after opening; return jar when done
" + // "
18601 Hwy 128, Yorkville, CA 95494
" + // "
www.PetitTeton.com
" + // "
" + // "
"; //let labels = ""; // ////TODO: Include bar code and identifying numbers. //for(let i = 0; i < count; i++) { // labels += label; //} // //return labels; } function bufferToBase64(buf) { var binstr = Array.prototype.map.call(buf, function (ch) { return String.fromCharCode(ch); }).join(''); return btoa(binstr); } Template.LabelMaker.onCreated(function() { this.labelWidth = new ReactiveVar(76); this.labelHeight = new ReactiveVar(50); this.title1 = new ReactiveVar("Strawberry"); this.title2 = new ReactiveVar("w/ Espelette"); this.ingredients = new ReactiveVar("*strawberry, sugar, *espelette"); this.date = new ReactiveVar(19001); //Session.set(PREFIX + "title1", "Strawberry"); //Session.set(PREFIX + "title1Font", "50px Times New Roman"); //Session.set(PREFIX + "title1YOffset", 260); //Session.set(PREFIX + "title2", "w/ Espelette"); //Session.set(PREFIX + "title2Font", "40px Times New Roman"); //Session.set(PREFIX + "title2YOffset", 340); //Session.set(PREFIX + "ingredients", "*strawberry, sugar, *espelette"); //Session.set(PREFIX + "date", 19001); //Session.set(PREFIX + "count", 3); }); Template.LabelMaker.onRendered(function() { let template = this; //Re-run this routine when ever the session variables change. //Tracker.autorun(function() { // //refreshLabelCanvas(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), 1, Session.get(PREFIX + "labelSpacing"), 0); // refreshLabelCanvas(template); //}); // //template.$('.labelContainer').on('DOMSubtreeModified', function() { // console.log("Initialized barcode"); // // //}); //JsBarcode(".barcode").init(); //const svgString = qrcode({content: "1234567890", padding: 0, width: 60, height: 60, color: "#000000", background: "#FFFFFF", ecl: "L"}); //this.$('.qrcode').attr('src', svg2url(svgString)); //this.$('.qrcode').attr('src', svg2url(new QRCode({content: '1234567890', width: 80, height: 80, color: "#000000", background: "#FFFFFF"}).svg())); new QRCode(document.getElementById("qrcode"), {text: "1234567890", width: 60, height: 60}); }); Template.LabelMaker.onDestroyed(function() { }); Template.LabelMaker.events({ 'change .labelWidth': function(e, t) { let x = $(e.target).val(); t.labelWidth.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 76); }, 'change .labelHeight': function(event, template) { let x = $(event.target).val(); t.labelHeight.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 50); }, 'change .title1': function(e, t) {t.title1.set($(e.target).val());}, 'change .title1Font': function(e, t) {t.title1Font.set($(e.target).val());}, 'change .title1YOffset': function(e, t) {t.title1YOffset.set(parseInt($(e.target).val()));}, 'change .title2': function(e, t) {t.title2.set($(e.target).val());}, 'change .title2Font': function(e, t) {t.title2Font.set($(e.target).val());}, 'change .title2YOffset': function(e, t) {t.title2YOffset.set(parseInt($(e.target).val()));}, 'change .ingredients': function(e, t) {t.ingredients.set($(e.target).val());}, 'change .ingredientsFont': function(e, t) {t.ingredientsFont.set($(e.target).val());}, 'change .ingredientsYOffset': function(e, t) {t.ingredientsYOffset.set(parseInt($(e.target).val()));}, 'change .date': function(e, t) {t.date.set(parseInt($(e.target).val()));}, 'click .preview': function(event, template) { let params = {}; params['title1'] = "Strawberry"; params['title2'] = ""; params['ingredients'] = "Fairies"; params['date'] = "1234"; window.open('/PrintLabel?' + $.param(params)); }, 'click .print': function(event, template) { let _this = template; let node = $('.label')[0]; let width = _this.labelWidth.get(); let height =_this.labelHeight.get(); let title1 =_this.title1.get(); let title2 =_this.title2.get(); let ingredients =_this.ingredients.get(); let date =_this.date.get(); Meteor.call('printLabels', width, height, "3x2Standard", title1, title2, ingredients, date, (error, result) => { if(error) { console.log(error); } else { const blob = new Blob([result], {type: 'application/pdf'}); const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = "labels.pdf"; link.click(); } }); //dti.toBlob(node, {bgcolor: 'white'}).then(function(blob) { // printImage(template, blob); //}).catch(function(err) { // console.log(err); //}); //dti.toPng(node, {bgcolor: 'white'}).then(function(dataUrl) { // printImageOld(template, dataUrl); //}).catch(function(err) { // console.log(err); //}); //let count = template.$('input[name="count"]').val(); //let spacing = Session.get(PREFIX + "labelSpacing"); // ////count = (count === undefined || Number.isNaN(count)) ? 1 : parseInt(count); //// ////if(count < 1) { //// count = 1; ////} //// ////Session.set(PREFIX + "generatedLabels", generateLabels(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), count, 0, spacing)); // //let $label = $('.printableLabel'); // //console.log($label); //console.log($label.length); //domtoimage.toPng($label).then(function(dataUrl) { // console.log("A"); // let img = new Image(); // img.src = dataUrl; // $('.printableLabel').html(img); // //caman('.printableLabel img', function() { // // this.contrast(100); // // this.render(); // // window.print(); // //}); //}).catch(function(error) { // console.error("failed to convert dom to image"); // console.error(error); //}); } }); Template.LabelMaker.helpers({ title1: function() {return Template.instance().title1.get();}, title2: function() {return Template.instance().title2.get();}, ingredients: function() {return Template.instance().ingredients.get();}, date: function() {return Template.instance().date.get();}, labelWidth: function() {return Template.instance().labelWidth.get();}, labelHeight: function() {return Template.instance().labelHeight.get();}, sampleLabel: function() { let t = Template.instance(); setTimeout(function() {JsBarcode(".barcode").init();}, 500); return generateLabels(t.title1.get(), t.title2.get(), t.ingredients.get(), t.date.get(), 1, 0); }, //canvasLabel: function() { // return generateLabelCanvas(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), 1, Session.get(PREFIX + "labelSpacing"), 0); //}, labels: function() { return Session.get(PREFIX + "generatedLabels"); }, labelPxWidth: function() { //console.log("label width: " + Template.instance().labelWidth.get()); //console.log("px_per_mm: " + PX_PER_MM); //console.log("labelPxWidth: " + (Template.instance().labelWidth.get() * PX_PER_MM)); return Math.floor(Template.instance().labelWidth.get() * PX_PER_MM); }, labelPxHeight: function() { return Math.floor(Template.instance().labelHeight.get() * PX_PER_MM); }, labelPxWidthActual: function() { //console.log("label width: " + Template.instance().labelWidth.get()); //console.log("px_per_mm: " + PX_PER_MM); //console.log("labelPxWidth: " + (Template.instance().labelWidth.get() * PX_PER_MM)); return Math.floor(Template.instance().labelWidth.get() * SCREEN_PX_PER_MM); }, labelPxHeightActual: function() { return Math.floor(Template.instance().labelHeight.get() * SCREEN_PX_PER_MM); } });