saveFileDialog(blob) // dark theme
Dark background. Преобразование canvas в blob для отсылки на сервер в бинарном виде (а не dataURL) или для сохранения в файл на клиенте Диалог сохранения blob на клиенте
by denvdmj
HTML
<body>
<h1>Диалог сохранения blob`а</h1>
<ul>
<li>Преобразование canvas в blob для отсылки на сервер в бинарном виде (а не dataURL) или для сохранения в файл на клиенте</li>
<li>Диалог сохранения blob на клиенте</li>
<li><a href='http://jsfiddle.net/DenVdmj/go2vpknb/'>saveFileDialog(blob)</a></li>
</ul>
<div>
<input id='file-name' type='text' value='generated-image.png'>
<button id='save-dialog'>Сохранить изображение на диск</button>
</div>
<div>
<div id='canvasContainer'>
<div>Canvas:</div>
</div>
<div id='imageContainer'>
<div>Image:</div>
</div>
</div>
CSS
body {
background: #282828;
color: #ddc;
font: 14px/130% Verdana;
min-width: 20em;
margin: auto;
padding: 1em 4em;
}
h1, h2, h3, h4, h5, h6 {
font: 140%/110% Verdana;
}
body > ul + div {
margin: 2em 0 1em 0;
}
body > ul + div + div {
margin: 1em 0 1em 0;
}
a {
color: #aae;
}
body > ul + div + div > div {
display: inline-block;
color: #7A7;
}
body > ul + div + div > div + div {
display: inline-block;
color: #88C;
}
canvas, img {
border: 4px ridge #7A7;
margin: 10px 10px 10px 0;
padding: 5px;
}
img {
border: 4px ridge #88C;
}
input[type="text"] {
box-sizing: border-box;
display: block;
background: linear-gradient(#aaa, #fff);
border: none;
font-size: 1.1em;
padding: .3em .5em;
margin: 5px 0 5px 5px;
border-radius: .2em;
width: 320px;
}
button {
box-sizing: border-box;
cursor: pointer;
display: inline-block;
vertical-align: top;
height: 52px;
width: 320px;
line-height: 1.6;
margin: 5px 0 5px 5px;
padding: 12px 22px;
position: relative;
background: linear-gradient(#4d4d4d, #2f2f2f);
border-radius: 8px;
border: 1px solid #333;
font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif;
color: white;
font-size: 1.1em;
white-space: nowrap;
text-shadow: 0 1px 2px #000;
text-overflow: ellipsis;
text-decoration: none;
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
button:hover {
background: linear-gradient(#505050, #333);
}
button:active {
background: linear-gradient(#444444, #282828);
margin: 6px 0 4px 5px;
}
button:focus {
outline: 0;
}
/* ******* */
/* ************** */
::selection {
background: #C9DBEF
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
background: #333;
}
::-webkit-scrollbar-thumb {
border-radius: 4px !important;
}
::-webkit-scrollbar-thumb:vertical {
background: linear-gradient(90deg, rgba(0,0,0,0), rgba(110,110,110,.3));
}
::-webkit-scrollbar-thumb:horizontal {
...
JavaScript
document.querySelector('button#save-dialog').onclick = function buttonSaveOnClick () {
var filename = document.querySelector('input#file-name').value;
document.querySelector('canvas').toBlob(function(blob) {
saveFileDialog(blob, filename);
});
};
function saveFileDialog (blob, filename, mimetype) {
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, filename);
return;
}
var a = document.createElement('a'),
URL = window.URL,
objectURL;
if (mimetype) {
a.type = mimetype;
}
a.download = filename;
a.href = objectURL = window.URL.createObjectURL(blob);
a.dispatchEvent(new MouseEvent('click'));
setTimeout(URL.revokeObjectURL.bind(URL, objectURL), 500);
};
function createCanvasImage () {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = 200;
canvas.height = 150;
context.fillStyle = '#009';
canvas.getContext('2d').fillRect(5, 5, 190, 140);
context.font = '16pt Arial';
context.fillStyle = '#fff';
context.fillText('hello, world.', 12, 40);
document.querySelector('#canvasContainer').appendChild(canvas);
return canvas;
}
function testImageBlob (canvas) {
canvas.toBlob(function(blob) {
// проверка, что блоб правильный
var fr = new FileReader();
fr.onload = function() {
var img = new Image();
img.src = fr.result;
document.querySelector('#imageContainer').appendChild(img);
};
fr.readAsDataURL(blob);
});
}
if (window.HTMLCanvasElement && !HTMLCanvasElement.prototype.toBlob) {
HTMLCanvasElement.prototype.toBlob = function (cback) {
var str = this.toDataURL();
str = atob(str.substr(str.indexOf('base64') + 7));
var buffer = new ArrayBuffer(str.length);
var bytes = new Uint8Array(buffer);
for (var i = 0; i < str.length; ++i) {
bytes[i] = str.charCodeAt(i);
}
cback(new Blob([bytes]));
};
}
testImageBlob( createCanvasImage() );