基於HTML5的Drag and Drop生成圖片Base64信息

HTML5的Drag and Drop是很不錯的功能,網上使用例子較多如 http://html5demos.com/drag ,但這些例子大部分沒實際用途,本文將搞個有點使用價值的例子,經過Drag and Drop生成圖片的Base64的字符串信息。html

使用Base64方式的圖片有諸多好處,可將多個圖片信息整合到單個js文件避免屢次http請求,能夠避免WebGL例子跨域訪問的安全限制沒法本地文件運行等好處,固然弊端也很多例如不能有效利用瀏覽器圖片緩存機制等。使用HT for Web的朋友會發現HT的例子不少註冊圖片都採用Base64的方式,這主要是爲了方便用戶直接本地文件打開HT的手冊便可操做瀏覽,無需構建web服務器發佈進行訪問,用戶常問而後將圖片轉出Base64信息,咱們使用的就是本文介紹的小工具。html5

Screen Shot 2014-12-18 at 11.49.18 PM

該工具由一個列表、一個拓撲圖和一個文本框三部分組成,用戶任意拖拽本地多圖片文件到任意頁面部分,HT自動將圖片信息生成對應的DataModel數據模型,列表顯示圖片效果、名稱和寬高信息,拓撲顯示圖片、修改時間和文件大小等信息,文本框生成對應註冊到htDefault.setImage函數的代碼片斷,用戶直接能夠將文本框內的代碼拷貝到本身的工程的js文件進行使用。node

function init(){                                                                 
	dataModel = new ht.DataModel();                                                                             
	listView = new ht.widget.ListView(dataModel); 
	graphView = new ht.graph.GraphView(dataModel);
	splitView = new ht.widget.SplitView(listView, graphView);
	textArea = new ht.widget.TextArea(); 
	textArea.getElement().style.wordWrap = 'normal';
	textArea.getElement().style.color = '#777';
	textArea.setEditable(false);
	new ht.widget.SplitView(splitView, textArea, 'v').addToDOM();    
	new ht.layout.ForceLayout(graphView).start();                            
	listView.setRowHeight(50);   
	listView.drawRowBackground = function(g, data, selected, x, y, width, height){
		if(this.isSelected(data)){
			g.fillStyle = '#87A6CB';
		}
		else if(this.getRowIndex(data) % 2 === 0){
			g.fillStyle = '#F1F4F7';
		}
		else{
			g.fillStyle = '#FAFAFA';
		}
		g.beginPath();
		g.rect(x, y, width, height);
		g.fill();
	};

	ht.Default.setImage('icon', {
		width: 50,
		height: 50,
		clip: function(g, width, height) {   
			g.beginPath();
			g.arc(width/2, height/2, Math.min(width, height)/2-3, 0, Math.PI * 2, true);
			g.clip();                        
		},
		comps: [
			{
				type: 'image',
				stretch: 'uniform',
				rect: [0, 0, 50, 50],
				name: {func: 'getImage'}
			}
		]
	});
	listView.setIndent(60);  
	listView.setVisibleFunc(function(data){
		return data instanceof ht.Node;
	});
	listView.getIcon = function(data){
		return 'icon';
	};                                  
	listView.getLabel = function(data){
		var name = data.getName(name);
		var image = ht.Default.getImage(name);
		if(image){
			name += ' ( ' + image.width + ' X ' + image.height + ' )';
		}
		return name;
	};
	window.addEventListener("dragenter", dragEnter, false);
	window.addEventListener("dragexit", dragExit, false);
	window.addEventListener("dragover", dragOver, false);
	window.addEventListener("drop", drop, false);                                             
}

function dragEnter(evt) {
	evt.stopPropagation();
	evt.preventDefault();
}

function dragExit(evt) {
	evt.stopPropagation();
	evt.preventDefault();
}

function dragOver(evt) {
	evt.stopPropagation();
	evt.preventDefault();
}

function drop(evt) {
	evt.stopPropagation();
	evt.preventDefault();

	dataModel.clear();
	textArea.setText("");
	lastNode = null;                

	var files = evt.dataTransfer.files;
	var count = files.length;                
	for (var i = 0; i < count; i++) {
		var file = files[i];
		var reader = new FileReader();
		reader.onloadend = handleReaderLoadEnd;
		reader.file = file;
		reader.readAsDataURL(file);
	}
}

function handleReaderLoadEnd(evt) {
	var reader = evt.target;  
	var file = reader.file;
	var name = file.name;
	name = name.substr(0, name.length - 4);
	var text = "ht.Default.setImage('" + name + "', '" + reader.result + "');\n";
	textArea.setText(textArea.getText() + text);                 
	ht.Default.setImage(name, reader.result); 

	var note = 'Date: ' + file.lastModifiedDate.toLocaleString() + '\n'
			+ 'Name: ' + file.name + '\n'
			+ 'Size: ' + file.size + '\n'
			+ 'Type: ' + file.type;

	var node = new ht.Node();
	node.setName(name);
	node.setImage(name);
	node.s({
		'note': note,
		'note.position': 3
	});
	dataModel.add(node);

	if(lastNode){
		var edge = new ht.Edge(lastNode, node);
		dataModel.add(edge);                    
	}
	lastNode = node;                
}

該代碼主要對window添加了dragenter、dragexit、dragover和drop的拖拽處理,大部分都是經過e.stopPropagation();和evt.preventDefault();阻止默認行爲,咱們僅需在最後的drop事件中經過e.dataTransfer.files獲得全部當前拖拽文件信息,構建FileReader進行加載,而後對加載的信息構建對應DataModel中的ht.Node對象和屬性就完事了。web

最後代碼中還有幾處使用HT for Web的技術細節值得提到,左側list列表經過自定義矢量圖標,而且在定義矢量時採用了clip的功能,這樣列表的圖標就會顯示成clip裁剪後的圓形效果。重載了listView.drawRowBackground函數,實現隔行變色的列表效果。重載了listView.getLabel顯示了更多的動態文本信息。經過listView.setVisibleFunc過濾不顯示連線信息在列表中。跨域

如下爲該Base64轉換工具的操做效果視頻和抓圖供參考:http://v.youku.com/v_show/id_XODUxNzY3OTA4.html

Screen Shot 2014-12-18 at 11.43.41 PMScreen Shot 2014-12-18 at 11.51.27 PM瀏覽器

相關文章
相關標籤/搜索