var TokenStamp = {}; (function (self) { var VERSION = "2.6.4"; var bordersFilePath = "../assets/images/token_stamp_2/borders/"; self.view; self.canvas; self.bufferCanvas; self.tokenCount = 0; self.borderColorPicker; self.flags = { isEditing: false }; self.settings = { skipFrameLag: true, fpsLimit: 15, imgurClientId: "921941cbfa5c8ba", editorCanvasSettings: { backgroundColor: "#35221e", width: 500, height: 500, selectionColor: "rgba(255,255,255,0.3)", preserveObjectStacking: true, stateful: false }, preMaskCanvasSettings: { backgroundColor: null, renderOnAddRemove: false, stateful: false, width: 500, height: 500 }, bufferCanvasSettings: { backgroundColor: null, renderOnAddRemove: false, stateful: false, width: 256, height: 256 }, cloudinaryCredentials: { cloud_name: "rolladvantage", api_key: "217956772584558" }, workingImageOptions: { left: 100, top: 100, hasControls: true, hasBorders: true, hasRotatingPoint: true, visible: true, selectable: true, evented: true, transparentCorners: false, centeredScaling: true, centeredRotation: true, padding: 0, cornerSize: 14, rotatingPointOffset: 40, borderColor: "rgb(200,200,200)", cornerColor: "rgb(200,200,200)" }, staticImageOptions: { hasControls: false, hasBorders: false, hasRotatingPoint: false, visible: true, selectable: false, evented: false, transparentCorners: false, centeredScaling: false, centeredRotation: false }, defaultText: "1", textSettings: { centerToTopPosition: -100, centerToLeftPosition: 40, fontFamily: "AleoBold", fill: $("#title a").css("color"), lineHeight: 1.1, fontSize: 72, styles: { }, hasControls: true, hasBorders: true, hasRotatingPoint: true, visible: true, selectable: true, evented: true, transparentCorners: false, centeredScaling: true, centeredRotation: true, padding: 0, cornerSize: 14, rotatingPointOffset: 40, borderColor: "rgb(200,200,200)", cornerColor: "rgb(200,200,200)" }, colorPickerSettings: { size: 2, margin: "0.2rem 0 0 -0.2rem", animationSpeed: 50, // toggle animation speed doRender: ".colour-control", // render color and bgColor of input field (on certain elements if selector) opacity: true, // enable / disable alpha slider memoryColors: [ { r: 255, g: 0, b: 0 }, { r: 0, g: 255, b: 0 }, { r: 0, g: 0, b: 255 }, { r: 255, g: 255, b: 0 }, { r: 0, g: 255, b: 255 }, { r: 255, g: 0, b: 255 }, { r: 255, g: 255, b: 255 } ], buildCallback: function ($elm) { var colorInstance = this.color; var colorPicker = this; $elm.prepend( '
' + 'R
' + 'G
' + 'B
' + 'H
' + 'S
' + 'B
' + '' + '
') .on("change", "input", function (e) { var value = this.value; var className = this.className; var type = className.split("-")[1]; var color = {}; color[type] = value; var colorType = type === "HEX" ? "HEX" : /(?:r|g|b)/.test(type) ? "rgb" : "hsv"; var colorValue = type === "HEX" ? value : color; colorInstance.setColor(colorValue, colorType); colorPicker.render(); this.blur(); }); $elm.append( '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' ); $elm.find(".cp-memory .cp-memory-colour") .on("click", function (e) { var memoryColour = $(this).css("background-color"); colorInstance.setColor(memoryColour); colorPicker.render(); }); var coloursSet = 0; $elm.find(".cp-memory div") .each(function () { var nextColour = colorPicker.color.options.memoryColors[coloursSet++]; console.dir(nextColour); $(this).css({ background: "rgb({0},{1},{2})".format(nextColour.r, nextColour.g, nextColour.b) }); }); }, renderCallback: function (colourControl) { var colors = this.color.colors.RND; var modes = { r: colors.rgb.r, g: colors.rgb.g, b: colors.rgb.b, h: colors.hsv.h, s: colors.hsv.s, v: colors.hsv.v, HEX: this.color.colors.HEX }; /* $(colourControl).css({ background: "#" + this.color.colors.HEX }); */ this.$UI.find(".cp-panel input").each(function () { this.value = modes[this.className.substr(3)]; }); var triggerElement = $(colourControl).parent()[0]; var rgbaColor = colorsToRGBA(this.color.colors); if (triggerElement.className.includes("border")) self.layers.borders.colour = rgbaColor; else if (triggerElement.className.includes("overlay")) self.layers.overlays.colour = rgbaColor; else if (triggerElement.className.includes("background")) self.layers.images.backgroundColour = rgbaColor; else if (triggerElement.className.includes("text")) self.layers.text.colour = rgbaColor; } } }; function colorsToRGBA(colors) { var rgb = colors.rgb; return "rgba({0},{1},{2},{3})".format(255 * rgb.r, 255 * rgb.g, 255 * rgb.b, colors.alpha); } self.layers = { masks: { imageMask: null, borderMask: null, overlayMask: null }, images: { isLayerDirty: true, bufferCompositeImage: null, colour: "", elements: [] }, borders: { isLayerDirty: true, bufferCompositeImage: null, elements: [] }, overlays: { isLayerDirty: true, bufferCompositeImage: null, elements: [] }, text: { isLayerDirty: true, bufferCompositeImage: null, colour: "", elements: [] } }; self.borders = [ { id: "none", name: "None", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "", overlayMask: "", borderImage: "placeholder.gif" } }, { id: "none-circle", name: "None Circle", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "placeholder.gif" } }, { id: "plain_ring_1", name: "Thin Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "plain_ring_1.png" } }, { id: "plain_ring_2", name: "Thick Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "plain_ring_2.png" } }, { id: "plain_ring_3", name: "Super Thin Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "plain_ring_3.png" } }, { id: "plain_square_1", name: "Thin Square", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_square_mask.gif", overlayMask: "plain_square_mask.gif", borderImage: "plain_square_1.png" } }, { id: "plain_square_2", name: "Thick Square", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_square_mask.gif", overlayMask: "plain_square_mask.gif", borderImage: "plain_square_2.png" } }, { id: "fifthed_border_medium", name: "Classic 5e Medium", defaultBorderColor: "rgb(255, 255, 255)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "fifthed_border_medium.png" } }, { id: "fifthed_border_medium_greyscale", name: "Classic 5e Medium (Greyscale)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "fifthed_border_medium_greyscale.png" } }, { id: "plain_hexagon_1", name: "Hexagon", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_hexagon_mask.gif", overlayMask: "plain_hexagon_mask.gif", borderImage: "plain_hexagon_1.png" } }, { id: "plain_octagon_1", name: "Octagon", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_octagon_mask.gif", overlayMask: "plain_octagon_mask.gif", borderImage: "plain_octagon_1.png" } }, { id: "10_sided_ring_1", name: "10 Sided Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "10_sided_ring_mask.gif", overlayMask: "10_sided_ring_mask.gif", borderImage: "10_sided_ring_1.png" } }, { id: "12_sided_ring_1", name: "12 Sided Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "12_sided_ring_mask.gif", overlayMask: "12_sided_ring_mask.gif", borderImage: "12_sided_ring_1.png" } }, { id: "double_ring_1", name: "Double Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "double_ring_1.png" } }, { id: "spike_ring_1", name: "Spike Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "spike_ring_1.png" } }, { id: "spike_ring_2", name: "Spike Ring 2", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "spike_ring_2.png" } }, { id: "abstract_ring_1", name: "Abstract Ring 1", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_ring_1.png" } }, { id: "abstract_ring_1_flat", name: "Abstract Ring 1 (Flat)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_ring_1_flat.png" } }, { id: "abstract_ring_2", name: "Abstract Ring 2", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_ring_2.png" } }, { id: "abstract_ring_2_flat", name: "Abstract Ring 2 (Flat)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_ring_2_flat.png" } }, { id: "abstract_ring_3", name: "Abstract Ring 3", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_ring_3.png" } }, { id: "abstract_ring_3_flat", name: "Abstract Ring 3 (Flat)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_ring_3_flat.png" } }, { id: "abstract_double_ring_1", name: "Abstract Double Ring", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_double_ring_1.png" } }, { id: "abstract_double_ring_1_flat", name: "Abstract Double Ring (Flat)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "abstract_double_ring_1_flat.png" } }, { id: "abstract_octagon_1", name: "Abstract Octagon", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_octagon_mask.gif", overlayMask: "plain_octagon_mask.gif", borderImage: "abstract_octagon_1.png" } }, { id: "abstract_octagon_1_flat", name: "Abstract Octagon (Flat)", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_octagon_mask.gif", overlayMask: "plain_octagon_mask.gif", borderImage: "abstract_octagon_1_flat.png" } }, { id: "abstract_triangle_1", name: "Abstract Triangle", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "abstract_triangle_mask.gif", overlayMask: "abstract_triangle_mask.gif", borderImage: "abstract_triangle_1.png" } }, { id: "cloud_ring_1", name: "Cloud Ring 1", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "cloud_ring_1_mask.gif", overlayMask: "cloud_ring_1_mask.gif", borderImage: "cloud_ring_1.png" } }, { id: "wavey_ring_1", name: "Wavey Ring 1", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "wavey_ring_1_mask.gif", overlayMask: "wavey_ring_1_mask.gif", borderImage: "wavey_ring_1.png" } }, { id: "plain_ring_1_with_arrow_1", name: "Thin Ring With Arrow", imageMask: null, overlayMask: null, borderImage: null, fileNames: { imageMask: "plain_ring_mask.gif", overlayMask: "plain_ring_mask.gif", borderImage: "plain_ring_1_with_arrow_1.png" } } ]; self.overlays = [ { id: "none", name: "None", fileName: "placeholder.gif", overlayImage: null }, { id: "fade_strong_white", name: "Strong White Fade", fileName: "overlay_fade_strong_white.png", overlayImage: null }, { id: "fade_strong", name: "Strong Fade", fileName: "overlay_fade_strong.png", overlayImage: null }, { id: "fade_medium", name: "Medium Fade", fileName: "overlay_fade_medium.png", overlayImage: null }, { id: "fade_soft", name: "Soft Fade", fileName: "overlay_fade_soft.png", overlayImage: null } ]; function receiveFoundryMessage(event) { console.dir(event); if (event == null) return; if (event.data.action == "registerSource") { self.foundryWindowSource = event.source; event.source.postMessage({ action: "sourceRegistered" }, "*"); } if(event.data.action == "uploadPermission"){ self.view.set("canFoundryUpload", event.data.uploadPermission); } } self.init = function () { console.log("Token Stamp 2 Init Start"); self.foundryDataExport = $("#foundry-data-export"); self.isFoundryMode = self.foundryDataExport != null; if (self.isFoundryMode) { window.addEventListener("message", receiveFoundryMessage, false); } fabric.devicePixelRatio = 1; zip.workerScriptsPath = "/assets/js/zipjs/"; ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "version", eventLabel: VERSION }); $.cloudinary.config(self.settings.cloudinaryCredentials); self.view = new Ractive({ el: "#site-content", append: true, template: "#token-stamp-maker-template", decorators: { imageFileDialog: function (node) { node.onchange = function () { var file = node.files[0]; if (file) { self.tokenName = file.name; self.loadImageFromFile(file); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "image-source", eventLabel: "FILEINPUT" }); } }; return { teardown: function () { node.onchange = null; } }; }, customBorderFileDialog: function (node) { node.onchange = function () { var file = node.files[0]; if (file) { self.loadBorderFromFile(file); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "custom-border", eventLabel: "FILEINPUT" }); } }; return { teardown: function () { node.onchange = null; } }; }, customMaskFileDialog: function (node) { node.onchange = function () { var file = node.files[0]; if (file) { self.loadMaskFromFile(file); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "custom-mask", eventLabel: "FILEINPUT" }); } }; return { teardown: function () { node.onchange = null; } }; } }, data: { version: VERSION, isLoading: true, isFoundryMode: self.isFoundryMode, showStartMessage: false, errorMessage: "", optionSelections: [], outputScale: 1, borderOpacity: 1, overlayOpacity: 0.5, isBatchModeOn: false, batchImageUrls: [], unprocessedBatchedImages: [], processedBatchedImages: [], isBatchProcessing: false, isCustomBorderSet: false, isCustomMaskSet: false, }, oninit: function () { var view = this; this.on({ toggleOptionSelector: function (event, pos) { var optionSelection = view.get("optionSelections")[pos]; optionSelection.showOptions = !optionSelection.showOptions; view.update(); }, selectOption: function (event, pos, id) { if (view.get("isBatchProcessing")) return; var optionSelection = view.get("optionSelections")[pos]; if (optionSelection.selectionType == "border" || optionSelection.selectionType == "overlay") { if (optionSelection.selectionType == "border") self.setActiveBorder(id); if (optionSelection.selectionType == "overlay") self.setActiveOverlay(id); optionSelection.selectedOptionId = id; var optionData = _.find(optionSelection.options, function (e) { return e.id === id; }); optionSelection.selectedOptionImage = optionData.image; } view.update(); }, adjustOutputScale: function (event, amount) { var outputScale = view.get("outputScale"); view.set("outputScale", (outputScale + amount).clamp(0, Number.MAX_VALUE)); }, adjustOverlayOpacity: function (event, amount) { var overlayOpacity = view.get("overlayOpacity"); view.set("overlayOpacity", (overlayOpacity + amount).clamp(0, 1)); }, adjustBorderOpacity: function (event, amount) { var borderOpacity = view.get("borderOpacity"); view.set("borderOpacity", (borderOpacity + amount).clamp(0, 1)); }, buttonClick: function (event, action) { if (view.get("isBatchProcessing")) return; switch (action) { case "chooseFile": $(event.node).find("input").click(); break; case "addText": self.addTextBox(); break; case "batchModeToggle": view.set("isBatchModeOn", !view.get("isBatchModeOn")); view.set("showStartMessage", false); self.clearImageLayer(); break; case "startBatchProcess": self.processBatch(); break; case "upload": if (view.get("isBatchModeOn")) return; self.uploadStamp(self.createStamp()); break; case "download": if (view.get("isBatchModeOn")) return; self.downloadStamp(self.createStamp()); break; case "foundryImport": self.foundryWindowSource.postMessage({ action: "importToken", tokenName: self.tokenName || "Unknown Token", stampData: self.getFoundryData() }, "*"); break; case "foundryImgurImport": self.uploadStamp(self.getFoundryData(), (tokenId) =>{ ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "foundry-upload-stamp-border", eventLabel: self.view.get("optionSelections")[0].selectedOptionId }); self.foundryWindowSource.postMessage({ action: "importTokenUrl", tokenUrl: "https://i.imgur.com/{0}.png".format(tokenId) }, "*"); }); break; case "reset": if (view.get("isBatchModeOn")) return; _.each(self.layers.images.elements, function (element) { self.resetImagePosition(element); }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "clear-reset", eventLabel: "reset-position" }); break; case "clear": if (view.get("isBatchModeOn")) { view.set("batchImageUrls", []); } else { self.clearImageLayer(); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "clear-reset", eventLabel: "clear-images" }); } break; case "setCustomBorder": $(event.node).find("input").click(); break; case "clearCustomBorder": view.set("isCustomBorderSet", false); var selectedOptionId = view.get("optionSelections")[0].selectedOptionId; self.setActiveBorder(selectedOptionId); break; case "setCustomMask": $(event.node).find("input").click(); break; case "clearCustomMask": view.set("isCustomMaskSet", false); var selectedOptionId = view.get("optionSelections")[0].selectedOptionId; self.setActiveBorder(selectedOptionId); break; } } }); }, onrender: function () { var view = this; /* $(".colour-control-container").click(function () { $(this).find(".colour-control").click(); e.preventDefault && e.preventDefault(); e.stopPropagation && e.stopPropagation(); return false; }); */ self.settings.colorPickerSettings.opacity = false; var borderTint = $(this.find(".border-tint")); self.borderColorPicker = borderTint.colorPicker(self.settings.colorPickerSettings); self.layers.borders.colour = borderTint.find(".colour-control").css("background-color"); self.settings.colorPickerSettings.opacity = true; var overlayTint = $(this.find(".overlay-tint")); overlayTint.colorPicker(self.settings.colorPickerSettings); self.layers.overlays.colour = overlayTint.find(".colour-control").css("background-color"); var backgroundColour = $(this.find(".background-colour")); backgroundColour.colorPicker(self.settings.colorPickerSettings); self.layers.images.backgroundColour = backgroundColour.find(".colour-control").css("background-color"); var textColour = $(this.find(".text-colour")); textColour.colorPicker(self.settings.colorPickerSettings); self.layers.text.colour = textColour.find(".colour-control").css("background-color"); var editorCanvasNode = this.find("#editor-canvas"); self.setupEditorCanvas(editorCanvasNode); var previewCanvasNode = this.find("#preview-canvas"); self.bufferCanvas = self.createBufferCanvas(previewCanvasNode); self.updateApp(); setTimeout(function () { //self.setActiveBorder("plain_ring_1"); view.fire("selectOption", null, 0, "plain_ring_1"); view.fire("selectOption", null, 1, "none"); view.set("isLoading", false); view.set("showStartMessage", true); }, 500); } }); self.setupBorders(); self.setupOverlays(); self.setupImageDragDrop(); self.setupKeyBindings(); }; self.setupKeyBindings = function () { $(document).on({ "keyup": function (e) { if (self.view.get("isBatchProcessing")) return; var code = e.keyCode || e.which; //Delete Button if (code == 46 && !self.flags.isEditing) { var activeObject = self.canvas.getActiveObject(); self.canvas.remove(activeObject); if (_.contains(self.layers.images.elements, activeObject)) { self.layers.images.elements.remove(activeObject); self.layers.images.isLayerDirty = true; } if (_.contains(self.layers.text.elements, activeObject)) { self.layers.text.elements.remove(activeObject); self.layers.text.isLayerDirty = true; } ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "shortkey", eventLabel: code }); } } }); }; function getFileName (url) { if(typeof url != "string") return null; var nameWithExt = url.split('/') .pop() .split('#')[0] .split('?')[0]; var dotSplit = nameWithExt.split("."); if(dotSplit.length > 1) dotSplit.length = dotSplit.length - 1; var fileName = dotSplit.join("."); return fileName; }; self.setupImageDragDrop = function () { $(document).on({ "dragover": function (e) { Keaworks.cancelEvent(e); if (self.view.get("isBatchProcessing")) return; e.originalEvent.dataTransfer.dropEffect = "copy"; }, "drop": function (e) { Keaworks.cancelEvent(e); if (self.view.get("isBatchProcessing")) return; self.clearErrorMessage(); self.view.set("isLoading", true); if (self.view.get("isBatchModeOn")) { self.view.set("showStartMessage", false); var allFiles = e.originalEvent.dataTransfer.files; if (allFiles.length > 0) { for (var x = 0; x < allFiles.length; x++) { self.loadImageFromFile(allFiles[x]); } } else { var eventData = e.originalEvent.dataTransfer.getData("text/html"); var eventImages = $(eventData).find("img").addBack("img"); var imageUrls = []; eventImages.each(function () { imageUrls.push($(this).attr("src")); }); for (var x = 0; x < imageUrls.length; x++) { self.loadImageFromUrl(imageUrls[x]); } } self.view.set("isLoading", false); } else { var file = e.originalEvent.dataTransfer.files[0]; if (file) { self.tokenName = getFileName(file.name); self.loadImageFromFile(file); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "image-source", eventLabel: "DRAGDROP" }); } else { var eventData = e.originalEvent.dataTransfer.getData("text/html"); var eventImage = $(eventData).find("img").addBack("img"); var url = eventImage.attr("src"); if (url) { self.tokenName = getFileName(url); self.loadImageFromUrl(url); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "image-source", eventLabel: "DRAGDROP" }); } else { self.view.set("isLoading", false); self.showErrorMessage("Unable to load file. Try dragging from desktop. If the problem persists please contact me@chadkeating.com"); } } } } }); }; self.onFileDialogUploadImage = function () { self.loadImageFromUrl(imageUrls[x]); }; self.setupEditorCanvas = function (canvasNode) { var cNode = $(canvasNode); var canvasParent = cNode.parent(); var newCanvas = new fabric.Canvas(canvasNode, self.settings.editorCanvasSettings); newCanvas.setHeight(canvasParent.height().max(self.settings.editorCanvasSettings.height)); newCanvas.setWidth(canvasParent.width().max(self.settings.editorCanvasSettings.width)); newCanvas.on({ "event:selected": function (e) { if (e.target) e.target.sendToBack(); }, //Image Events "object:moving": function (e) { self.layers.images.isLayerDirty = true; self.layers.text.isLayerDirty = true; }, "object:rotating": function (e) { self.layers.images.isLayerDirty = true; self.layers.text.isLayerDirty = true; }, "object:scaling": function (e) { self.layers.images.isLayerDirty = true; self.layers.text.isLayerDirty = true; }, //Text Events "text:editing:entered": function (e) { self.flags.isEditing = true; }, "text:editing:exited": function (e) { self.flags.isEditing = false; self.layers.text.isLayerDirty = true; } }); self.canvas = newCanvas; }; self.createBufferCanvas = function (canvasNode) { var newBufferCanvas = new fabric.StaticCanvas(canvasNode, self.settings.bufferCanvasSettings); newBufferCanvas.on({ "after:render": function (e) { self.layers.images.isImageRendered = !self.layers.images.isLayerDirty && self.layers.images.isImageReady; }, }); return newBufferCanvas }; self.isFileReaderAvailable = function () { if (typeof window.FileReader === "undefined") { console.log("File Reader not available"); //TODO: show as error, platform not supportted self.showErrorMessage("Unable to use FileReader, change browser or OS. If the problem persists please contact me@chadkeating.com"); return false; } return true; }; self.readAsDataURL = function (file, callback) { var reader = new FileReader(); reader.onload = callback; reader.readAsDataURL(file); } self.loadImageFromFile = function (file) { if (!self.isFileReaderAvailable()) { self.view.set("isLoading", false); return; } self.readAsDataURL(file, self.onImageLoaded); }; self.loadBorderFromFile = function (file) { if (!self.isFileReaderAvailable()) { self.view.set("isLoading", false); return; } self.readAsDataURL(file, function (event) { _.each(self.layers.borders.elements, function (e) { self.canvas.remove(e); }); self.layers.borders.elements = []; var borderImage = fabric.Image.fromURL( event.target.result, function (canvasImageObject) { var maskCanvasEl = fabric.util.createCanvasElement(); maskCanvasEl.width = canvasImageObject.width; maskCanvasEl.height = canvasImageObject.height; var maskCanvasContext = maskCanvasEl.getContext('2d'); maskCanvasContext.drawImage(canvasImageObject.getElement(), 0, 0, maskCanvasEl.width, maskCanvasEl.height); self.canvas.add(canvasImageObject); self.canvas.centerObject(canvasImageObject); canvasImageObject.moveTo(3); self.layers.borders.elements = [canvasImageObject]; self.view.set("isCustomBorderSet", true); self.layers.images.isLayerDirty = true; self.layers.text.isLayerDirty = true; }, self.settings.staticImageOptions); }); }; self.loadMaskFromFile = function (file) { if (!self.isFileReaderAvailable()) { self.view.set("isLoading", false); return; } self.readAsDataURL(file, function (event) { var maskImage = fabric.Image.fromURL( event.target.result, function (canvasImageObject) { var maskCanvasEl = fabric.util.createCanvasElement(); maskCanvasEl.width = canvasImageObject.width; maskCanvasEl.height = canvasImageObject.height; var maskCanvasContext = maskCanvasEl.getContext('2d'); maskCanvasContext.drawImage(canvasImageObject.getElement(), 0, 0, maskCanvasEl.width, maskCanvasEl.height); self.layers.masks.imageMask = canvasImageObject; self.layers.masks.overlayMask = canvasImageObject; self.view.set("isCustomMaskSet", true); self.layers.images.isLayerDirty = true; self.layers.text.isLayerDirty = true; }, self.settings.staticImageOptions); }); }; self.loadImageFromUrl = function (url) { var newImage = new Image(); newImage.setAttribute('crossOrigin', 'anonymous'); newImage.onload = function (e) { var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.height = newImage.height; canvas.width = newImage.width; ctx.drawImage(newImage, 0, 0); var baseData = canvas.toDataURL("image/png"); self.onImageLoaded(baseData); canvas = null; }; newImage.onerror = function (e) { self.loadImageFromUrlCloudinary(url); }; newImage.src = url; }; self.loadImageFromUrlCloudinary = function (url) { var newImage = new Image(); newImage.setAttribute('crossOrigin', 'anonymous'); newImage.onload = function (e) { var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.height = newImage.height; canvas.width = newImage.width; ctx.drawImage(newImage, 0, 0); var baseData = canvas.toDataURL("image/png"); self.onImageLoaded(baseData); canvas = null; }; newImage.onerror = function (e) { self.view.set("isLoading", false); self.showErrorMessage("Unable to load file. Try dragging from desktop or use the 'Choose Image' button."); }; newImage.src = "http://res.cloudinary.com/rolladvantage/image/fetch/fl_lossy,f_auto,w_1920,h_1920,c_fit/" + url; }; self.onImageLoaded = function (event) { var imageToUse; if (event.target && event.target.result) { //FileReader imageToUse = event.target.result; } else { imageToUse = event; } if (!imageToUse || imageToUse == "data:image/png;base64,") { self.view.set("isLoading", false); self.showErrorMessage("Unable to load file. Try dragging from desktop. If the problem persists please contact me@chadkeating.com"); return; } if (self.view.get("isBatchModeOn")) { self.view.push("batchImageUrls", imageToUse); } else { self.addImageToWorkCanvas(imageToUse); } }; self.addImageToWorkCanvas = function (imageToUse) { var fileType = imageToUse.substr(imageToUse.lastIndexOf(".") + 1); if (fileType && fileType.toLowerCase() === "svg") { fabric.Image.fromElement(imageToUse, self.onAddImageToWorkCanvas, self.settings.workingImageOptions); } else { fabric.Image.fromURL(imageToUse, self.onAddImageToWorkCanvas, self.settings.workingImageOptions); } }; self.onAddImageToWorkCanvas = function (newImageObject) { self.clearImageLayer(); self.currentImage = newImageObject; self.resetImagePosition(newImageObject); self.layers.images.elements.push(newImageObject); self.canvas.add(newImageObject); newImageObject.moveTo(0); self.canvas.setActiveObject(newImageObject); self.layers.images.isLayerDirty = true; self.view.set("isLoading", false); self.view.set("showStartMessage", false); }; self.clearImageLayer = function () { _.each(self.layers.images.elements, function (e) { self.canvas.remove(e); }); self.layers.images.elements = []; self.layers.images.isLayerDirty = true; }; self.resetImagePosition = function (newImageObject) { var imageFitWidth = 256; var imageFitHeight = imageFitWidth; newImageObject.setScaleX(1); newImageObject.setScaleY(1); newImageObject.rotate(0); if (newImageObject.width === newImageObject.height) { newImageObject.width = imageFitWidth; newImageObject.height = imageFitHeight; } else if (newImageObject.width < newImageObject.height) { var previousWidth = newImageObject.width; newImageObject.width = imageFitWidth; newImageObject.height = newImageObject.height * (imageFitHeight / previousWidth); } else if (newImageObject.width > newImageObject.height) { var previousHeight = newImageObject.height; newImageObject.height = imageFitHeight; newImageObject.width = newImageObject.width * (imageFitWidth / previousHeight); } /* //Max size if (newImageObject.width > reducedCanvasWidth || newImageObject.height > reducedCanvasHeight) { if (newImageObject.width === newImageObject.height) { newImageObject.width = reducedCanvasWidth; newImageObject.height = reducedCanvasHeight; } else if (newImageObject.width > newImageObject.height) { var previousWidth = newImageObject.width; newImageObject.width = reducedCanvasWidth; newImageObject.height = newImageObject.height * (reducedCanvasHeight / previousWidth); } else if (newImageObject.width < newImageObject.height) { var previousHeight = newImageObject.height; newImageObject.height = reducedCanvasHeight; newImageObject.width = newImageObject.width * (reducedCanvasWidth / previousHeight); } } */ self.canvas.centerObject(newImageObject); self.layers.images.isLayerDirty = true; }; self.setupOverlays = function () { var optionsSelection = { selectionType: "overlay", label: "Overlays", showOptions: false, selectedOptionId: "", options: [] }; _.each(self.overlays, function (e) { optionsSelection.options.push({ id: e.id, name: e.name, image: bordersFilePath + e.fileName }); if (e.id === "none") return; fabric.Image.fromURL( bordersFilePath + e.fileName, function (imageObject) { e.overlayImage = imageObject; }, self.settings.staticImageOptions); }); self.view.push("optionSelections", optionsSelection); }; self.setupBorders = function () { var optionsSelection = { selectionType: "border", label: "Borders", showOptions: false, selectedOptionId: "", options: [] }; _.each(self.borders, function (e) { optionsSelection.options.push({ id: e.id, name: e.name, image: bordersFilePath + e.fileNames.borderImage }); if (e.id === "none") return; self.loadBorderFile(bordersFilePath + e.fileNames.imageMask, function (canvasImageObject) { var maskCanvasEl = fabric.util.createCanvasElement(); maskCanvasEl.width = canvasImageObject.width; maskCanvasEl.height = canvasImageObject.height; var maskCanvasContext = maskCanvasEl.getContext('2d'); maskCanvasContext.drawImage(canvasImageObject.getElement(), 0, 0, maskCanvasEl.width, maskCanvasEl.height); e.imageMask = canvasImageObject; }); self.loadBorderFile( bordersFilePath + e.fileNames.overlayMask, function (canvasImageObject) { var maskCanvasEl = fabric.util.createCanvasElement(); maskCanvasEl.width = canvasImageObject.width; maskCanvasEl.height = canvasImageObject.height; var maskCanvasContext = maskCanvasEl.getContext('2d'); maskCanvasContext.drawImage(canvasImageObject.getElement(), 0, 0, maskCanvasEl.width, maskCanvasEl.height); e.overlayMask = canvasImageObject; }); self.loadBorderFile( bordersFilePath + e.fileNames.borderImage, function (imageObject) { e.borderImage = imageObject; }); }); self.view.push("optionSelections", optionsSelection); }; self.loadBorderFile = function (fileName, callback) { fabric.Image.fromURL( fileName, callback, self.settings.staticImageOptions); }; self.setActiveOverlay = function (id) { _.each(self.layers.overlays.elements, function (e) { self.canvas.remove(e); }); self.layers.overlays.elements = []; var overlay = _.find(self.overlays, function (e) { return e.id === id; }); if (overlay.overlayImage !== null) { self.canvas.add(overlay.overlayImage); self.canvas.centerObject(overlay.overlayImage); overlay.overlayImage.moveTo(1); self.layers.overlays.elements = [overlay.overlayImage]; } else { self.layers.overlays.elements = []; } self.layers.overlays.isLayerDirty = true; }; self.setActiveBorder = function (id) { if (!self.view.get("isCustomBorderSet")) { _.each(self.layers.borders.elements, function (e) { self.canvas.remove(e); }); self.layers.borders.elements = []; } var border = _.find(self.borders, function (e) { return e.id === id; }); if (!self.view.get("isCustomBorderSet")) { if (border.defaultBorderColor != null) { self.borderColorPicker.colorPicker.color.setColor(border.defaultBorderColor); $(".border-tint .colour-control").css("background-color", border.defaultBorderColor); $(".border-tint .colour-control")[0].value = border.defaultBorderColor; self.layers.borders.colour = border.defaultBorderColor; } if (border.borderImage != null) { self.canvas.add(border.borderImage); self.canvas.centerObject(border.borderImage); border.borderImage.moveTo(3); self.layers.borders.elements = [border.borderImage]; } else { self.layers.borders.elements = []; } } if (!self.view.get("isCustomMaskSet")) { self.layers.masks.imageMask = border.imageMask; self.layers.masks.overlayMask = border.overlayMask; } self.layers.borders.isLayerDirty = true; self.layers.overlays.isLayerDirty = true; self.layers.images.isLayerDirty = true; self.layers.text.isLayerDirty = true; }; self.addTextBox = function () { var editorCenterTop = self.canvas.getHeight() / 2; var editorCenterLeft = self.canvas.getWidth() / 2; var textSettings = $.extend(self.settings.textSettings, { fill: self.layers.text.colour, top: editorCenterTop + self.settings.textSettings.centerToTopPosition, left: editorCenterLeft + self.settings.textSettings.centerToLeftPosition }); var newTextBlock = new fabric.IText(self.settings.defaultText, textSettings); _.each(self.layers.text.elements, function (element) { self.canvas.remove(element); }); self.layers.text.elements = []; self.canvas.add(newTextBlock); newTextBlock.moveTo(2); self.canvas.setActiveObject(newTextBlock); self.layers.text.elements.push(newTextBlock); self.layers.text.isLayerDirty = true; self.view.set("showStartMessage", false); }; var previousTime = 0; var deltaTime = 0; self.updateApp = function (currentTime) { currentTime = currentTime || 0; deltaTime += currentTime - previousTime; previousTime = currentTime; var msPerFrame = 1000 / self.settings.fpsLimit; if (deltaTime >= msPerFrame) { if (self.settings.skipFrameLag) deltaTime = 0; else deltaTime -= msPerFrame; self.updateBackgroundColour(); self.updateBorderColour(); self.updateOverlayColour(); self.updateTextColour(); self.updateBufferCanvas(self.canvas, self.bufferCanvas); self.updateBatchProcess(); } requestAnimationFrame(self.updateApp); }; self.updateBackgroundColour = function () { if (self.canvas.backgroundColor == self.layers.images.backgroundColour) return; self.canvas.setBackgroundColor(self.layers.images.backgroundColour); self.canvas.renderAll(); self.layers.images.isLayerDirty = true; }; self.updateBorderColour = function () { _.each(self.layers.borders.elements, function (element) { var filter = _.find(element.filters, function (x) { return x.type == "Multiply"; }); if (filter) { if (filter.colour == self.layers.borders.colour) return; filter.setOptions({ color: self.layers.borders.colour }); } else { filter = new fabric.Image.filters.Multiply({ color: self.layers.borders.colour }); element.filters.push(filter); } element.applyFilters(function () { self.layers.borders.isLayerDirty = true; }); }); }; self.updateOverlayColour = function () { _.each(self.layers.overlays.elements, function (element) { var filter = _.find(element.filters, function (x) { return x.type == "Multiply"; }); if (filter) { if (filter.colour == self.layers.overlays.colour) return; filter.setOptions({ color: self.layers.overlays.colour }); } else { filter = new fabric.Image.filters.Multiply({ color: self.layers.overlays.colour }); element.filters.push(filter); } element.applyFilters(function () { self.layers.overlays.isLayerDirty = true; }); }); }; self.updateTextColour = function () { _.each(self.layers.text.elements, function (element) { element.setColor(self.layers.text.colour); }); self.layers.text.isLayerDirty = true; } self.calculateBufferCanvasObjectPosition = function (originalObject, objectToPosition, newCanvasHeight, newCanvasWidth) { var originalTop = originalObject.getTop(); var originalLeft = originalObject.getLeft(); var editorCenterTop = self.canvas.getHeight() / 2; var editorCenterLeft = self.canvas.getWidth() / 2; var distanceFromCenterTop = originalTop - editorCenterTop; var distanceFromCenterLeft = originalLeft - editorCenterLeft; var newCanvasCenterTop = newCanvasHeight / 2; var newCanvasCenterLeft = newCanvasWidth / 2; var newTop = distanceFromCenterTop + newCanvasCenterTop; var newLeft = distanceFromCenterLeft + newCanvasCenterLeft; objectToPosition.setTop(newTop); objectToPosition.setLeft(newLeft); }; self.updateBufferCanvas = function (workingCanvas, bufferCanvas) { //workingCanvas.deactivateAll(); workingCanvas.renderAll(); if (self.layers.borders.isLayerDirty) { self.layers.borders.isLayerDirty = false; _.each(self.layers.borders.bufferCompositeImages, function (element) { bufferCanvas.remove(element); }); self.layers.borders.bufferCompositeImages = []; _.each(self.layers.borders.elements, function (element) { var elementClone = fabric.util.object.clone(element); bufferCanvas.add(elementClone); bufferCanvas.centerObject(elementClone); elementClone.moveTo(3); self.layers.borders.bufferCompositeImages.push(elementClone); }); } if (self.layers.text.isLayerDirty) { self.layers.text.isLayerDirty = false; var preMaskCanvas = new fabric.StaticCanvas(document.createElement("canvas"), self.settings.preMaskCanvasSettings); _.each(self.layers.text.elements, function (element) { var elementClone = fabric.util.object.clone(element); preMaskCanvas.add(elementClone); self.calculateBufferCanvasObjectPosition(element, elementClone, preMaskCanvas.getHeight(), preMaskCanvas.getWidth()); }); fabric.Image.fromURL(preMaskCanvas.toDataURL("image/png"), function (imageObject) { imageObject.filters.push(new fabric.Image.filters.Mask({ mask: self.layers.masks.imageMask })); imageObject.applyFilters(function () { bufferCanvas.remove(self.layers.text.bufferCompositeImage); bufferCanvas.add(imageObject); bufferCanvas.centerObject(imageObject); imageObject.moveTo(2); self.layers.text.bufferCompositeImage = imageObject; }); }, self.settings.staticImageOptions); } if (self.layers.overlays.isLayerDirty) { self.layers.overlays.isLayerDirty = false; var preMaskCanvas = new fabric.StaticCanvas(document.createElement("canvas"), self.settings.preMaskCanvasSettings); _.each(self.layers.overlays.elements, function (element, i, a) { var elementClone = fabric.util.object.clone(element); preMaskCanvas.add(elementClone); preMaskCanvas.centerObject(elementClone); }); fabric.Image.fromURL(preMaskCanvas.toDataURL("image/png"), function (imageObject) { imageObject.filters.push(new fabric.Image.filters.Mask({ mask: self.layers.masks.overlayMask })); imageObject.applyFilters(function () { bufferCanvas.remove(self.layers.overlays.bufferCompositeImage); imageObject.set("opacity", self.view.get("overlayOpacity")); bufferCanvas.add(imageObject); bufferCanvas.centerObject(imageObject); imageObject.moveTo(1); self.layers.overlays.bufferCompositeImage = imageObject; }); }, self.settings.staticImageOptions); } if (self.layers.images.isLayerDirty) { self.layers.images.isLayerDirty = false; self.layers.images.isImageReady = false; var preMaskCanvas = new fabric.StaticCanvas(document.createElement("canvas"), self.settings.preMaskCanvasSettings); preMaskCanvas.setBackgroundColor(self.layers.images.backgroundColour); _.each(self.layers.images.elements, function (element) { var elementClone = fabric.util.object.clone(element); preMaskCanvas.sendToBack(elementClone); preMaskCanvas.add(elementClone); self.calculateBufferCanvasObjectPosition(element, elementClone, preMaskCanvas.getHeight(), preMaskCanvas.getWidth()); }); fabric.Image.fromURL(preMaskCanvas.toDataURL("image/png"), function (imageObject) { imageObject.filters.push(new fabric.Image.filters.Mask({ mask: self.layers.masks.imageMask })); imageObject.applyFilters(function () { bufferCanvas.remove(self.layers.images.bufferCompositeImage); bufferCanvas.add(imageObject); bufferCanvas.centerObject(imageObject); imageObject.moveTo(0); self.layers.images.bufferCompositeImage = imageObject; self.layers.images.isImageReady = !self.layers.images.isLayerDirty; }); }, self.settings.staticImageOptions); } _.each(bufferCanvas.getObjects(), function (x) { x.scale(self.view.get("outputScale")); x.center(); }); _.each(self.layers.borders.bufferCompositeImages, function (x) { x.set("opacity", self.view.get("borderOpacity")); }); if (self.layers.overlays.bufferCompositeImage !== null) self.layers.overlays.bufferCompositeImage.set("opacity", self.view.get("overlayOpacity")); bufferCanvas.renderAll(); }; self.processBatch = function () { var imagesToProcess = self.view.get("batchImageUrls"); if (!self.view.get("isBatchProcessing") && !self.view.get("isLoading") && imagesToProcess != null && imagesToProcess.length > 0) { self.view.set("unprocessedBatchedImages", imagesToProcess.slice()); self.view.set("BATCHPROCESSSTATE", "FREE"); self.view.set("isBatchProcessing", true); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "batch-process", eventLabel: "images-to-batch-" + imagesToProcess.length }); } }; self.updateBatchProcess = function () { if (self.view.get("isBatchProcessing") && !self.view.get("isLoading")) { var batchState = self.view.get("BATCHPROCESSSTATE"); if (batchState == "FREE") { var unprocessedBatchedImages = self.view.get("unprocessedBatchedImages"); var nextImage = unprocessedBatchedImages.pop(); self.view.set("unprocessedBatchedImages", unprocessedBatchedImages); if (nextImage) { self.view.set("isLoading", true); self.addImageToWorkCanvas(nextImage); self.view.set("BATCHPROCESSSTATE", "IMAGEADDED"); } else { self.view.set("BATCHPROCESSSTATE", "OUTPUT"); } } else if (batchState == "IMAGEADDED" && !self.layers.images.isLayerDirty && self.layers.images.isImageReady) { var stamp = self.createStamp(); self.view.set("isLoading", false); stamp = stamp.replace(/^data:image\/[^;]/, 'data:application/octet-stream'); self.view.push("processedBatchedImages", stamp); self.view.set("BATCHPROCESSSTATE", "FREE"); } else if (batchState == "OUTPUT") { var nextEntryCallback = function (writer) { var processedBatchedImages = self.view.get("processedBatchedImages"); var nextImageToZip = processedBatchedImages.shift(); self.view.set("processedBatchedImages", processedBatchedImages); if (nextImageToZip) { writer.add("token_" + ++self.tokenCount + ".png", new zip.Data64URIReader(nextImageToZip), function () { // onsuccess callback nextEntryCallback(writer); // close the zip writer }, function (currentIndex, totalIndex) {/* onprogress callback */ }); } else { writer.close(function (blob) { // blob contains the zip file as a Blob object var downloadLink = document.createElement("a"); downloadLink.href = window.URL.createObjectURL(blob); downloadLink.download = "batchedTokens.zip"; self.openLink(downloadLink); self.clearImageLayer(); self.view.set("BATCHPROCESSSTATE", "FREE"); self.view.set("isBatchProcessing", false); self.view.set("isLoading", false); }); } } zip.createWriter(new zip.BlobWriter(), nextEntryCallback, function (error) { self.view.set("BATCHPROCESSSTATE", "FREE"); }); self.view.set("BATCHPROCESSSTATE", "ZIPPING"); } else if (batchState == "ZIPPING") { } } }; function onCreateStamp() { ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-border", eventLabel: self.view.get("optionSelections")[0].selectedOptionId }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-border-colour", eventLabel: self.layers.borders.colour }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-border-opacity", eventLabel: "" + self.view.get("borderOpacity") }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-background-colour", eventLabel: self.layers.images.backgroundColour }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-scale", eventLabel: "" + self.view.get("outputScale") }); var overlayId = self.view.get("optionSelections")[1].selectedOptionId; if (overlayId !== "none") { ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-overlay", eventLabel: overlayId }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-overlay-opacity", eventLabel: "" + self.view.get("overlayOpacity") }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-overlay-colour", eventLabel: self.layers.overlays.colour }); } if (self.layers.text.elements.length > 0) { var text = self.layers.text.elements[0].getText(); if (text !== null && text.length > 0) { ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-text-color", eventLabel: self.layers.text.colour }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "stamp-text", eventLabel: text }); } } } self.createStamp = function () { self.view.set("isLoading", true); onCreateStamp(); return self.bufferCanvas.toDataURL("image/png"); }; self.getFoundryData = function () { self.view.set("isLoading", true); var stampData = self.createStamp(); //stampData = stampData.replace(/^data:image\/[^;]/, 'data:application/octet-stream'); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "foundry-stamp-border", eventLabel: self.view.get("optionSelections")[0].selectedOptionId }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "foundry-stamp-overlay", eventLabel: self.view.get("optionSelections")[1].selectedOptionId }); var text = "none"; if (self.layers.text.elements.length > 0) { text = self.layers.text.elements[0].getText(); } ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "foundry-stamp-text", eventLabel: text }); self.view.set("isLoading", false); return stampData; }; self.downloadStamp = function (stampData) { stampData = stampData.replace(/^data:image\/[^;]/, 'data:application/octet-stream'); var downloadLink = document.createElement("a"); downloadLink.href = stampData; downloadLink.download = "token_" + ++self.tokenCount + ".png"; self.openLink(downloadLink); self.view.set("isLoading", false); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "download-stamp-border", eventLabel: self.view.get("optionSelections")[0].selectedOptionId }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "download-stamp-overlay", eventLabel: self.view.get("optionSelections")[1].selectedOptionId }); var text = "none"; if (self.layers.text.elements.length > 0) { text = self.layers.text.elements[0].getText(); } ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "download-stamp-text", eventLabel: text }); }; self.openLink = function (downloadLink) { document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); }; self.uploadStamp = function (stampData, callbackSuccess) { $.ajax({ url: "https://api.imgur.com/3/image", method: "POST", headers: { Authorization: "Client-ID " + self.settings.imgurClientId }, data: { image: stampData.replace("data:image/png;base64,", ""), type: "base64", title: "Roll Advantage - Token " + ++self.tokenCount, description: "Made with http://rolladvantage.com - " + VERSION, }, dataType: "json", error: function (jqXHR, textStatus, errorThrown) { self.view.set("isLoading", false); self.showErrorMessage("There was an error uploading the stamp. Please try again. If the problem persists please contact me@chadkeating.com"); }, success: function (result) { var id = result.data.id; if(callbackSuccess) { callbackSuccess(id); } else { var url = "https://imgur.com/{0}".format(id); var w = window.open("about:blank"); w.location = url; } self.view.set("isLoading", false); } }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "upload-stamp-border", eventLabel: self.view.get("optionSelections")[0].selectedOptionId }); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "upload-stamp-overlay", eventLabel: self.view.get("optionSelections")[1].selectedOptionId }); var text = "none"; if (self.layers.text.elements.length > 0) { text = self.layers.text.elements[0].getText(); } ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "upload-stamp-text", eventLabel: text }); }; self.showErrorMessage = function (message) { message = message || "There was an error please try again. If the problem persists please contact me@chadkeating.com"; self.view.set("errorMessage", message); ga("send", { hitType: "event", eventCategory: "token-stamp-2", eventAction: "error", eventLabel: message }); }; self.clearErrorMessage = function () { self.view.set("errorMessage", ""); }; })(TokenStamp); RollAdvantage.InitRegister.push(TokenStamp.init);