Element.NativeEvents['drop'] = 2;
Element.NativeEvents['dragover'] = 2;
Element.NativeEvents['dragleave'] = 2;
var dataURL = new Class({
Implements: [Options, Events],
options: {
reduce: true,
sizeattr: true,
filemetas:true,
filesizes:true,
imagetag:true,
container: 'file-list'
},
initialize: function(options) {
this.setOptions(options);
this.files = [];
this.container = $(this.options.container);
},
setOption: function(name, value) {
this.options[name] = value;
},
//@param files {array} dataTransfer.files
convert: function(files) {
var self = this;
this.files = [];
if (typeOf(files) === 'collection') {
this.container.empty();
Object.each(files, function(file, key) {
self.readFile(file, key);
self.files.push(file);
});
} else {
return false;
}
},
//@param file {object}
readFile: function(file, key) {
var reader = new FileReader();
reader.key = key;
reader.onload = this._fileLoadHandler.bind(this);
reader.readAsDataURL(file);
},
_fileLoadHandler: function(e) {
var reader = e.target;
var file = this.files[reader.key];
var key = reader.key;
var dataurl = reader.result;
var preview = new Element('img', {
'src': dataurl,
'data-key': key,
'events': {
'load': this._imgLoadHandler.bind(this)
}
});
var wrapper = new Element('fieldset', {
'class': 'wrapper form-inline',
'id': 'result-' + key
});
this.wrapper = wrapper;
var close = new Element('button', {
'text': '×',
'type': 'button',
'class': 'close'
});
close.addEvent('click', function() {
this.getParent('fieldset').destroy();
});
close.inject(wrapper);
//FileName
new Element('legend', {
'text': file.fileName
}).inject(wrapper);
//Preview Image
new Element('div', {
'class': 'preview control-group'
}).grab(preview).inject(wrapper);
if(this.options.filemetas){
this._createFileMeta(key, file);
}
if (!this.options.dirname) {
this._createDataUrlArea(key, dataurl);
}
this.container.grab(new Element('form').grab(wrapper));
},
_imgLoadHandler: function(e) {
var img = e.target;
var key = img.get('data-key');
var file = this.files[key];
var w = img.width;
var h = img.height;
var reduce = this.options.reduce;
var w2 = (w / 2).floor();
var h2 = (h / 2).floor();
var className = this.options.classname ? ' class="' + this.options.classname + '"' : '';
var sizeAttr = this.options.sizeattr ? ' width="' + (reduce ? w2 : w) + '" height="' + (reduce ? h2 : h) + '"' : '';
var source = '<img alt=""' + className + sizeAttr + ' src="' + img.src + '">';
if(this.options.filesizes){
this._createSizeHtml(w, h, w2, h2, key);
}
if (this.options.dirname) { //create img tag of filepath
var path = this.options.dirname + file.fileName;
source = '<img alt=""' + className + sizeAttr + ' src="' + path + '">';
}
if(this.options.imagetag){
this._createImageTag(key, source);
}
},
_createImageTag:function(key, source){
new Element('p', {
'class': 'dir control-group',
'html': '<label class="control-label" for="dir-' + key + '">Img tag</label><div class="controls"><input type="text" class="input-xxlarge" id="dir-' + key + '" value="' + source + '"></div>'
}).inject(this.wrapper);
},
_createDataUrlArea:function(key, dataurl){
//DataURL
new Element('div', {
'class': 'dataurl control-group',
'html': '<label class="control-label" for="dataurl-' + key + '">DataURL</label><div class="controls"><textarea rows="5" class="input-xxlarge" id="dataurl-' + key + '">' + dataurl + '</textarea></div>'
}).inject(this.wrapper);
},
_createFileMeta:function(key, file){
//Filename
var fnameHTML = '<label class="span5 inline">fileName <input type="text" value="' + file.fileName + '" id="filename-' + key + '"></label>';
//Filesize
var fsizeHTML = '<div class="span4 inline">fileSize <input type="text" value="' + (file.fileSize / 1000) + '" class="mini" id="filesize-' + key + '">kb</div>';
//Filename + Filesize
new Element('div', {
'class': 'control-group',
'html': '<strong class="control-label">File Meta</strong><div class="controls row">' + fnameHTML + fsizeHTML + '</div>'
}).inject(this.wrapper);
},
_createSizeHtml:function(w, h, w2, h2, key){
var sizeHTML = '<label class="control-label">Size</label><div class="input row controls">';
sizeHTML += '<div class="span4 inline"><b>Original</b> W:<input type="text" id="width-' + key + '" class="span1" size="3" value="' + w + '">';
sizeHTML += ' H:<input type="text" id="height-' + key + '" class="span1" size="3" value="' + h + '"></div>';
if (reduce) {
sizeHTML += '<div class="span4 inline"><b>50%縮小</b> W:<input type="text" id="width-' + key + '-reduce" class="span1" size="3" value="' + w2 + '">';
sizeHTML += ' H:<input type="text" id="height-' + key + '-reduce" class="span1" size="3" value="' + h2 + '"></div>';
}
sizeHTML += '</div>';
new Element('p', {
'class': 'size control-group',
'html': sizeHTML
}).inject(this.wrapper);
}
});
window.addEvent('domready', function() {
var Converter = new dataURL();
$('options').getElements('input').each(function(el) {
var type_ = el.get('type');
if (type_ === 'checkbox') {
el.addEvent('click', function() {
Converter.setOption(this.id, this.checked);
});
} else if (type_ === 'text') {
el.addEvent('keyup', function() {
Converter.setOption(this.id, this.value);
});
}
});
document.body.addEvents({
'dragover': function(e) {
e.preventDefault();
document.body.addClass('hover');
},
'dragleave': function(e) {
document.body.removeClass('hover');
},
'drop': function(e) {
e.preventDefault();
document.body.removeClass('hover');
Converter.convert(e.event.dataTransfer.files);
}
});
});
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#">dataURL Converter</a>
</div>
</div>
</div>
<div class="container">
<section id="options">
<h2>Option</h2>
<form class="well form-inline">
<fieldset>
<div class="control-group">
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" id="reduce" name="reduce" value="" checked="checked">
50%縮小
</label>
<label class="checkbox inline">
<input type="checkbox" id="sizeattr" name="sizeattr" value="" checked="checked">
width, height属性
</label>
</div>
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" id="filemetas" name="filemetas" value="" checked="checked">Result File Meta
</label>
<label class="checkbox inline">
<input type="checkbox" id="filesizes" name="filesizes" value="" checked="checked">Result File Size
</label>
<label class="checkbox inline">
<input type="checkbox" id="imagetag" name="imagetag" value="" checked="checked">Result Image Tag
</label>
</div>
</div>
<div class="row">
<div class="control-group span4">
<label for="dirname" class="control-label">DirName</label>
<div class="controls">
<input type="text" id="dirname">
<p class="help-block">
ファイルパスのimgタグだけを生成する
</p>
</div>
</div>
<div class="control-group span4">
<label for="classname" class="control-label">ClassName</label>
<div class="controls">
<input type="text" id="classname">
<p class="help-block">
imgタグに付与するクラス
</p>
</div>
</div>
</div>
</fieldset>
</form>
</section>
<section id="convert-result">
<div class="page-header">
<h2>Convert Result</h2>
</div>
<div id="file-list">画像ファイルをドロップしてください</div>
</section>
</div>
<footer>©<a href="https://twitter.com/#!/Tenderfeel">Tenderfeel</a> | <a href="http://twitter.github.com/bootstrap/">Bootstrap</a></footer>
html,body {
width:100%;
height:100%;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
.hover{
border:solid 2px blue;
}
.wrapper {
border-bottom:dashed 1px #ccc;
position:relative;
}
.wrapper .preview {
background:#efefef;
margin-top:20px;
border:solid 1px #ccc;
-webkit-margin-top-collapse: separate;
-moz-margin-top-collapse: separate;
-ms-margin-top-collapse: separate;
margin-top-collapse: separate;
}
.preview > img {
margin:10px;
}
.wrapper .close {
position:absolute;
right:10px;
top:10px;
}
#options {
padding-top:60px;
}
footer{
text-align:center;
}
External resources loaded into this fiddle: