Saving JSON as File + Loading JSON from File - javascript

I have a FabricJS canvas (1.7.22) with a few buttons to add images and text. I also have a textarea which I can use to load the canvas JSON for copying and to load to the canvas for later editing.
I want to expedite the process by being able to save the canvas JSON as a file to my computer and be able to load the file onto the canvas later.
I feel like I have the essential functionality but how might I achieve the above for better usability?
$(function() {
var canvas = new fabric.Canvas('c', {
/* isDrawingMode: true */
});
$('#text').on('click', addtext);
function addtext() {
var text = new fabric.IText('Some Text!', {
left: 10,
top: 10
});
canvas.add(text);
}
// From Computer
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
console.log('fdsf');
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function() {
// start fabricJS stuff
var image = new fabric.Image(imgObj);
image.set({
left: 0,
top: 0,
angle: 20,
padding: 10,
cornersize: 10
});
//image.scale(getRandomNum(0.1, 0.25)).setCoords();
image.scale(0.2);
canvas.add(image);
// end fabricJS stuff
}
}
reader.readAsDataURL(e.target.files[0]);
}
// Add Web IMG
var myImg = 'https://i.imgur.com/q2oGjQ9.jpg';
$('#addImage').on('click', addImg);
function addImg() {
fabric.Image.fromURL(myImg, function(oImg) {
oImg.scale(0.2);
canvas.add(oImg);
});
}
// canvas2json
$("#canvas2json").click(function() {
var json = canvas.toJSON();
$("#myTextArea").text(JSON.stringify(json));
});
// load json2canvas
$("#loadJson2Canvas").click(function() {
canvas.loadFromJSON(
$("#myTextArea").val(),
canvas.renderAll.bind(canvas));
});
});
#myTextArea {
width: 90%;
height: 200px;
}
canvas {
border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<button id="text">Add Text</button>
<input type="button" id="addImage" value="Add Web IMG">
<input type="file" id="imgLoader">
<br/><br/>
<canvas id='c' width=500 height=500></canvas>
<br/>
<button id='canvas2json'>2JSON</button>
<button id='loadJson2Canvas'>2CANVAS</button>
<br/><br/>
<textarea id='myTextArea' onfocus="this.select();" onmouseup="return false;"></textarea>

Download the json using createObjectURL and then upload from browser and read the file using readAsText , FileReader api . then load JSON to canvas.
DEMO
$(function() {
var canvas = new fabric.Canvas('c', {
/* isDrawingMode: true */
});
$('#text').on('click', addtext);
function addtext() {
var text = new fabric.IText('Some Text!', {
left: 10,
top: 10
});
canvas.add(text);
}
// From Computer
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
console.log('fdsf');
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function() {
// start fabricJS stuff
var image = new fabric.Image(imgObj);
image.set({
left: 0,
top: 0,
angle: 20,
padding: 10,
cornersize: 10
});
//image.scale(getRandomNum(0.1, 0.25)).setCoords();
image.scale(0.2);
canvas.add(image);
// end fabricJS stuff
}
}
reader.readAsDataURL(e.target.files[0]);
}
// Add Web IMG
var myImg = 'https://i.imgur.com/q2oGjQ9.jpg';
$('#addImage').on('click', addImg);
function addImg() {
fabric.Image.fromURL(myImg, function(oImg) {
oImg.scale(0.2);
canvas.add(oImg);
});
}
// canvas2json
$("#canvas2json").click(function() {
var json = canvas.toJSON();
$("#myTextArea").text(JSON.stringify(json));
var a = document.createElement("a");
var file = new Blob([JSON.stringify(json)], {
type: 'text/plain'
});
a.href = URL.createObjectURL(file);
a.download = 'json.txt';
a.click();
});
// load json2canvas
$("#loadJson2Canvas").click(function() {
canvas.loadFromJSON(
$("#myTextArea").val(),
canvas.renderAll.bind(canvas));
});
$('#jsonload').change(function(e) {
var file = e.target.files[0];
if(!file) return;
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
canvas.loadFromJSON(
JSON.parse(data),
canvas.renderAll.bind(canvas));
};
reader.readAsText(file);
});
$(this).val(null);
return;
});
#myTextArea {
width: 90%;
height: 200px;
}
canvas {
border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<button id="text">Add Text</button>
<input type="button" id="addImage" value="Add Web IMG"/><input type="file" id="imgLoader"/>
<br>upload json<input type="file" id="jsonload" />
<br/><br/>
<canvas id='c' width=500 height=500></canvas>
<br/>
<button id='canvas2json'>2JSON</button>
<button id='loadJson2Canvas'>2CANVAS</button>
<br/><br/>
<textarea id='myTextArea' onfocus="this.select();" onmouseup="return false;"></textarea>

Use localStorage to save data to your hard drive. For example
$("#canvas2json").click(function() {
localStorage.myFabricJSCanvas = JSON.stringify(canvas.toJSON());
$("#myTextArea").text('Saved');
});
$("#loadJson2Canvas").click(function() {
canvas.loadFromJSON(
JSON.parse(localStorage.myFabricJSCanvas),
canvas.renderAll.bind(canvas)
);
});
If you want to make it more flexible, such as with more load/save slots, then load/save from a container object such as myCanvases, assign to / get data from its values, and save the myCanvases object to localStorage instead.

Related

Fabric js - reset all actions/filters on active object

In my project I'm trying to figure out how to reset all the changes I make on the image.
Example:
If I remove two colors from my image I would like that when I click on button#remove the image returns to the previous one without changes and without filters.
My code is this:
$(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
canvas.setHeight('300');
canvas.setWidth('800');
canvas.renderAll();
document.getElementById('file-input').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 10, top: 10, angle: 00}).scale(0.8);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({ format: 'png', quality: 0.8 });
console.log("Canvas Image " + dataURL);
});
};
reader.readAsDataURL(file);
});
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.padding = 5;
$("#remove-color-color").change(function(){
var oImg = canvas.getActiveObject();
var filter = new fabric.Image.filters.RemoveColor({
color: $(this).val(),
threshold: 0.2,
distance: 0.5,
});
oImg.filters.push(filter);
oImg.applyFilters();
canvas.renderAll();
});
$(".removeItem").click(function(){
canvas.remove(canvas.getActiveObject());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<div id="contCanvasLogo" style="float:left;width:100%;">
<canvas id="canvas" class="resize canvasLogo" style="width:500px;height:500px;border:1px solid #ccc;"></canvas>
<input type="file" id="file-input">
<input type="color" id="remove-color-color" />
</div>
<br/>
<button class="removeItem" >Remove</button>
<button class="reset" >Reset</button>
How can i do for reset all filters on my activeObject?
To clear all filters on the object just set your filters to an empty array and then run applyFilters(), then renderAll()
obj.filters = [];
obj.applyFilters();
canvas.renderAll();
$(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
canvas.setHeight('300');
canvas.setWidth('800');
canvas.renderAll();
document.getElementById('file-input').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 10,
top: 10,
angle: 00
}).scale(0.8);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
console.log("Canvas Image " + dataURL);
});
};
reader.readAsDataURL(file);
});
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.padding = 5;
$("#remove-color-color").change(function() {
var oImg = canvas.getActiveObject();
if(!oImg) return;
var filter = new fabric.Image.filters.RemoveColor({
color: $(this).val(),
threshold: 0.2,
distance: 0.5,
});
oImg.filters.push(filter);
oImg.applyFilters();
canvas.renderAll();
});
$(".removeItem").click(function() {
var obj = canvas.getActiveObject();
if(obj) canvas.remove(obj);
});
$(".reset").click(function() {
var obj = canvas.getActiveObject();
if(!obj) return;
obj.filters = [];
obj.applyFilters();
canvas.renderAll();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<div id="contCanvasLogo" style="float:left;width:100%;">
<canvas id="canvas" class="resize canvasLogo" style="width:500px;height:500px;border:1px solid #ccc;"></canvas>
<input type="file" id="file-input">
<input type="color" id="remove-color-color" />
</div>
<br/>
<button class="removeItem">Remove</button>
<button class="reset">Reset</button>

How to add an image to a canvas, scaled to size?

I can add a local image to my canvas. My problem though is that I can only scale the image by something like 0.5 but this isn't very helpful because images are always different. How might I have the image scale to say 400px wide, but the rest resize proportionally so that no matter the size of the chosen image, things fit and it isn't a guessing game (currently I have a link to an image resizer, I'm trying to remove the need)?
I'm using fabricjs 1.7.21.
var canvas = new fabric.Canvas("c");
canvas.setHeight(616);
canvas.setWidth(446);
// New Photo to Canvas
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function() {
var image = new fabric.Image(imgObj);
image.set({
left: 10,
top: 10,
}).scale(0.5);
canvas.add(image);
}
}
reader.readAsDataURL(e.target.files[0]);
}
canvas {
border: 1px solid #dddddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.21/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label class="btn btn-default" id="imgLoader">
<span class="oi oi-image"></span> Add Image<input type="file" hidden>
</label>
<canvas id="c"></canvas>
Try this:
var canvas = new fabric.Canvas("c");
canvas.setHeight(616);
canvas.setWidth(446);
// New Photo to Canvas
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function() {
var image = new fabric.Image(imgObj);
image.width = 400;
image.height = 400;
image.set({
left: 10,
top: 10,
});
canvas.add(image);
}
}
reader.readAsDataURL(e.target.files[0]);
}
scaleToWidth/scaleToHeight was what I was looking for. You can find the documentation here.
Props to #Ben who commented this. I wanted to close the question.

Exclude element from canvas to be saved to json (fabric.js)

I am using
var jsonToPHP= JSON.stringify(canvas.toObject(['id','name']));
to save all from canvas to JSON.
I am also adding background image to canvas.
document.getElementById('imgLoader').addEventListener("change", function (e) { var file = e.target.files[0]; var reader = new FileReader(); reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 0, top: 0, angle: 00,width:canvas.width, height:canvas.height,}).scale(1);
oImg.set('selectable', false);
canvas.add(oImg).renderAll();
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
}); }; reader.readAsDataURL(file);
});
But i would like to exclude background image to be saved to JASON.
I vas googling for:
Exclude element from canvas to be saved to json fabric.js
and i have got next:
in the fabricjs docs there is a property for the Object class calles
'excludeFromExport'.
Once set to true it should do exactly what you want.
www.fabricjs.com/docs
I went to:
Source: fabric.js, line 12350 excludeFromExport
And what now?
My knowlage is to less to get to result from this. Does any one can give more informations: maybe one example?
Thank you
DEMO
document.getElementById('imgLoader').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 0,
top: 0,
angle: 00,
width: canvas.width,
height: canvas.height
});
canvas.setBackgroundImage(oImg).renderAll();
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
var canvas = new fabric.Canvas('c', {
serializeBgOverlay: false //to serialize background data toJson
});
canvas.backgroundColor = 'green';
canvas.add(new fabric.Circle({
left: 50,
top: 50,
radius: 50,
stroke: 'red',
fill: ''
}))
canvas.renderAll();
// override _toObjectMethod and if you want to serialize background , set serializeBgOverlay true, while canvas initialize
fabric.StaticCanvas.prototype._toObjectMethod = function(methodName, propertiesToInclude) {
var data = {
objects: this._toObjects(methodName, propertiesToInclude)
};
if (this.serializeBgOverlay) {
fabric.util.object.extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));
}
fabric.util.populateWithProperties(this, data, propertiesToInclude);
return data;
}
function exportToJson() {
console.log(canvas.toJSON());
}
canvas{
border:2px dotted blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.16/fabric.min.js"></script>
<input type="file" id="imgLoader" accept="image/*"> <br>
<canvas id='c' width='400' height='400'></canvas>
<button onclick='exportToJson();'>ToJson</button>
Here I added a prototype of _toObjectMethod() , it will exclude background image of canvas toJson export.

Convert canvas into image with fix size in HTML5

I am using HTML5. Right now I am convert canvas into image by toDataURL. But I want to this canvas convert into different size. For example, My canvas size is 450px*450px then it should convert into 1000px*1000px.
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 50, top: 100,width:100, height:100, angle: 00}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8, width:1000, height:10000});
console.log("aaaaaaaaaaa" + dataURL);
// console.log("Canvas Image " + dataURL);
// document.getElementById('txt').href = dataURL;
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function (e) {
e.preventDefault();
canvas.deactivateAll().renderAll();
document.querySelector('#preview').src = canvas.toDataURL();
}
canvas {
border: 1px solid black;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<canvas id="canvas" width="400" height="400"></canvas>
Click Me!!
<br />
<img id="preview" />
I tried canvas.toDataUrl({format: 'png', quality: 0.8, width:1000,
height:1000}) But it is not works.
DEMO JSFIDDLE.
https://jsfiddle.net/varunPes/8gt6d7op/13/
expected Result:
Just add width:1000, height:1000 to var oImg = img.set({left: 50, top: 100, angle: 00}).scale(0.9);
Full Code:
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 0, top: 0, angle: 00}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function (e) {
e.preventDefault();
canvas.deactivateAll().renderAll();
increaseImg(canvas.toDataURL(), function(dataURL) {
document.querySelector('#preview').src = dataURL;
});
}
function increaseImg(src, callback) {
var n_canvas = $('<canvas width="1800" height="2000" />')[0],
n_ctx = n_canvas.getContext('2d'),
n_img = new Image();
n_img.onload = function() {
n_ctx.drawImage(n_img, 0, 0, n_canvas.width, n_canvas.height);
callback(n_canvas.toDataURL());
}
n_img.src = src;
}
canvas{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="450" height="450"></canvas>
Click Me!!
<br />
<img id="preview" />
Your code is fine and do not need any big change.
If you want to export image in various dimensions try this.
I created two export links, one for width 500 and one for 1000.
As you see you can export image directly instead of canvas.
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 50, top: 100, angle: 00}).scale(0.9);
canvas.add(oImg);
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function (e) {
_export(e, 500);
}
document.querySelector('#txt2').onclick = function (e) {
_export(e, 1000);
}
function _export(e, width) {
e.preventDefault();
var a = canvas.getActiveObject();
canvas.deactivateAll().renderAll();
var mult = width / a.width;
document.querySelector('#preview').src = a.toDataURL({multiplier: mult});
}
canvas {
border: 1px solid black;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<canvas id="canvas" width="400" height="400"></canvas>
Click Me!! 500<br />
Click Me!! 1000
<br />
<img id="preview" />
See if https://jsfiddle.net/8gt6d7op/14/ works. toDataURL only works with whatever is in the canvas, so you can't specify size. Size is already in the canvas.
You can use a 2nd canvas with a size you want and use that to populate the image from.
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<canvas id="canvas" width="400" height="400"></canvas>
Click Me!!
<br />
<img id="preview" />
<canvas id="canvas2" width="1000" height="1000" style="display:none;"></canvas>
var canvas = new fabric.Canvas('canvas');
var canvas2 = new fabric.Canvas('canvas2');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 50, top: 100, angle: 00}).scale(0.9);
canvas.add(oImg).renderAll();
canvas2.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas2.toDataURL({format: 'png', quality: 0.8});
console.log("aaaaaaaaaaa" + dataURL);
// console.log("Canvas Image " + dataURL);
// document.getElementById('txt').href = dataURL;
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function (e) {
e.preventDefault();
canvas2.deactivateAll().renderAll();
document.querySelector('#preview').src = canvas2.toDataURL();
}

Export resized image in canvas to new JSZip package

I can load an image into a canvas element and resize it, but I'm having trouble grabbing the resized image:
var logo = $(".logo"),
loader = $(".load"),
canvas = $(".holder"),
ctx = canvas[0].getContext("2d");
function displayPreview(file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = new Image();
img.src = e.target.result;
img.onload = function() {
// x, y, width, height
ctx.drawImage(img, 0, 0, 128, 128);
var dataURL = canvas[0].toDataURL("image/png");
var logo = $(".logo");
var imgUrl = dataURL;
var imgz = $("<img>");
imgz.attr("src", imgUrl);
logo.html("");
logo.append(imgz);
};
};
reader.readAsDataURL(file);
}
into the download package function for jszip.
// Download Zip
$(".download").on("click", function(imgUrl) {
var zip = new JSZip();
zip.file("logo.png", imgUrl);
var content = zip.generate({type:"blob"});
// see FileSaver.js
saveAs(content, "test.zip");
});
Snippet:
var logo = $(".logo"),
loader = $(".load"),
canvas = $(".holder"),
ctx = canvas[0].getContext("2d");
function displayPreview(file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = new Image();
img.src = e.target.result;
img.onload = function() {
// x, y, width, height
ctx.drawImage(img, 0, 0, 128, 128);
var dataURL = canvas[0].toDataURL("image/png");
var logo = $(".logo");
var imgUrl = dataURL;
var imgz = $("<img>");
imgz.attr("src", imgUrl);
logo.html("");
logo.append(imgz);
};
};
reader.readAsDataURL(file);
}
$(document).ready(function() {
loader.on("change", function(evt) {
var file = evt.target.files[0];
displayPreview(file);
var reader = new FileReader();
reader.onload = function(e) {
// Download Zip
$(".download").on("click", function(imgUrl) {
var zip = new JSZip();
zip.file("logo.png", imgUrl);
var content = zip.generate({type:"blob"});
// see FileSaver.js
saveAs(content, "test.zip");
});
return false;
};
reader.readAsArrayBuffer(file);
});
// Trigger Load Image
$(".trigload").click(function() {
$("input").trigger("click");
});
});
#import url("http://necolas.github.io/normalize.css/3.0.1/normalize.css");
.hide {
display: none;
}
.logo {
text-align: center;
}
.fill {
width: 100%;
}
.fr {
float: right;
}
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip-utils/dist/jszip-utils.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/vendor/FileSaver.js"></script>
<input type="file" class="hide load">
<a class="trigload" href="javascript:void(0)">Load Image</a>
<a class="download fr" href="javascript:void(0)">Download</a>
<div class="logo"></div>
<div class="fill" align="center">
<canvas class="holder" width="128" height="128"></canvas>
</div>
In order to get JSZip to correctly save your dataURL to valid png file, it seems you need to add an object containing {base64: true}as third argument of the zip.file() method, and to remove the data:image/png;base64, from the dataURL.
Also, you were assigning the click event to the imgUrl variable. You may want to store it in a global variable, or check the $('.logo>img')[0].src or call once again canvas[0].toDataURL().
var logo = $(".logo"),
loader = $(".load"),
canvas = $(".holder"),
ctx = canvas[0].getContext("2d");
function displayPreview(file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = new Image();
img.src = e.target.result;
img.onload = function() {
// x, y, width, height
ctx.drawImage(img, 0, 0, 128, 128);
var dataURL = canvas[0].toDataURL("image/png");
var logo = $(".logo");
var imgUrl = dataURL;
var imgz = $("<img>");
imgz.attr("src", imgUrl);
logo.html("");
logo.append(imgz);
};
};
reader.readAsDataURL(file);
}
$(document).ready(function() {
loader.on("change", function(evt) {
var file = evt.target.files[0];
displayPreview(file);
var reader = new FileReader();
reader.onload = function(e) {
// Download Zip
$(".download").on("click", function() {
var imgUrl = canvas[0].toDataURL();
var zip = new JSZip();
zip.file("logo.png", imgUrl.split('base64,')[1],{base64: true});
var content = zip.generate({type:"blob"});
// see FileSaver.js
saveAs(content, "test.zip");
});
return false;
};
reader.readAsArrayBuffer(file);
});
// Trigger Load Image
$(".trigload").click(function() {
$("input").trigger("click");
});
});
#import url("http://necolas.github.io/normalize.css/3.0.1/normalize.css");
.hide {
display: none;
}
.logo {
text-align: center;
}
.fill {
width: 100%;
}
.fr {
float: right;
}
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip-utils/dist/jszip-utils.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/vendor/FileSaver.js"></script>
<input type="file" class="hide load">
<a class="trigload" href="javascript:void(0)">Load Image</a>
<a class="download fr" href="javascript:void(0)">Download</a>
<div class="logo"></div>
<div class="fill" align="center">
<canvas class="holder" width="128" height="128"></canvas>
</div>
2022 Edit
JSZip now accepts Blobs as input directly, so it's better to convert your canvas to a Blob and pass this directly to JSZip. (As a fiddle because StackSnippets don't allow-downloads).

Categories