2013-08-22 26 views
31

Tôi đã cố hết sức để tìm một ví dụ đơn giản, có liên quan và cập nhật hoạt động cho phiên bản Firefox mới nhất và tôi thực sự đang gặp khó khăn.Tôi làm cách nào để người dùng dán dữ liệu hình ảnh từ khay nhớ tạm vào phần tử canvas trong Firefox bằng Javascript thuần túy?

Nhan đề nói rằng tất cả đều thực sự. Tôi muốn người dùng có thể sao chép một phần của hình ảnh từ trình chỉnh sửa như Windows Paint hoặc sử dụng nút Print Screen và sau đó dán hình ảnh đó vào phần tử canvas. Điểm thưởng nếu canvas thay đổi kích thước để vừa với chính xác hình ảnh được dán (theo nghĩa đen).

Muốn tránh các giải pháp dựa trên Flash hoặc Java nếu hợp lý.

Tôi khá nửa vời ở Javascript nhưng tương đối thiếu kinh nghiệm với các tính năng HTML5 mới nhất và hoàn toàn mới đối với phần tử Canvas. Hãy giúp tôi!

+0

[Làm thế nào để quản lý hình ảnh dán từ clipboard trong html5?] (Http://stackoverflow.com/questions/6219197/how-to-manage-image-pasting-from-clipboard-in-html5) – Andreas

Trả lời

58

Phiên bản 2.0: Mã nhỏ hơn, sạch hơn hoạt động trên Chrome, Firefox, Edge, Opera. Không còn hack nữa. Nhưng nếu bạn cần hỗ trợ IE và Safari, hãy kiểm tra phiên bản v1.

http://jsfiddle.net/KJW4E/905/


Phiên bản 1.0 thực hiện Chrome là đơn giản. Firefox (và IE) có những hạn chế mà người dùng phải đưa ra lệnh để dán như sự kiện bàn phím và đầu vào có thể chỉnh sửa phải được tập trung, vì vậy chúng tôi làm thủ thuật ở đây - trên ctrl xuống lĩnh vực đầu vào focusthat, phát hành unfocus.

Hỗ trợ trình duyệt (dữ liệu hình ảnh):

  • Firefox
  • Chrome
  • Cạnh
  • IE-11
  • Opera

var CLIPBOARD = new CLIPBOARD_CLASS("my_canvas", true); 
 

 
/** 
 
* image pasting into canvas 
 
* 
 
* @param {string} canvas_id - canvas id 
 
* @param {boolean} autoresize - if canvas will be resized 
 
*/ 
 
function CLIPBOARD_CLASS(canvas_id, autoresize) { 
 
\t var _self = this; 
 
\t var canvas = document.getElementById(canvas_id); 
 
\t var ctx = document.getElementById(canvas_id).getContext("2d"); 
 
\t var ctrl_pressed = false; 
 
\t var command_pressed = false; 
 
\t var paste_event_support; 
 
\t var pasteCatcher; 
 

 
\t //handlers 
 
\t document.addEventListener('keydown', function (e) { 
 
\t \t _self.on_keyboard_action(e); 
 
\t }, false); //firefox fix 
 
\t document.addEventListener('keyup', function (e) { 
 
\t \t _self.on_keyboardup_action(e); 
 
\t }, false); //firefox fix 
 
\t document.addEventListener('paste', function (e) { 
 
\t \t _self.paste_auto(e); 
 
\t }, false); //official paste handler 
 

 
\t //constructor - we ignore security checks here 
 
\t this.init = function() { 
 
\t \t pasteCatcher = document.createElement("div"); 
 
\t \t pasteCatcher.setAttribute("id", "paste_ff"); 
 
\t \t pasteCatcher.setAttribute("contenteditable", ""); 
 
\t \t pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;width:10px;margin-left:-20px;'; 
 
\t \t document.body.appendChild(pasteCatcher); 
 

 
\t \t // create an observer instance 
 
\t \t var observer = new MutationObserver(function(mutations) { 
 
\t \t \t mutations.forEach(function(mutation) { 
 
\t \t \t \t if (paste_event_support === true || ctrl_pressed == false || mutation.type != 'childList'){ 
 
\t \t \t \t \t //we already got data in paste_auto() 
 
\t \t \t \t \t return true; 
 
\t \t \t \t } 
 

 
\t \t \t \t //if paste handle failed - capture pasted object manually 
 
\t \t \t \t if(mutation.addedNodes.length == 1) { 
 
\t \t \t \t \t if (mutation.addedNodes[0].src != undefined) { 
 
\t \t \t \t \t \t //image 
 
\t \t \t \t \t \t _self.paste_createImage(mutation.addedNodes[0].src); 
 
\t \t \t \t \t } 
 
\t \t \t \t \t //register cleanup after some time. 
 
\t \t \t \t \t setTimeout(function() { 
 
\t \t \t \t \t \t pasteCatcher.innerHTML = ''; 
 
\t \t \t \t \t }, 20); 
 
\t \t \t \t } 
 
\t \t \t }); 
 
\t \t }); 
 
\t \t var target = document.getElementById('paste_ff'); 
 
\t \t var config = { attributes: true, childList: true, characterData: true }; 
 
\t \t observer.observe(target, config); 
 
\t }(); 
 
\t //default paste action 
 
\t this.paste_auto = function (e) { 
 
\t \t paste_event_support = false; 
 
\t \t if(pasteCatcher != undefined){ 
 
\t \t \t pasteCatcher.innerHTML = ''; 
 
\t \t } 
 
\t \t if (e.clipboardData) { 
 
\t \t \t var items = e.clipboardData.items; 
 
\t \t \t if (items) { 
 
\t \t \t \t paste_event_support = true; 
 
\t \t \t \t //access data directly 
 
\t \t \t \t for (var i = 0; i < items.length; i++) { 
 
\t \t \t \t \t if (items[i].type.indexOf("image") !== -1) { 
 
\t \t \t \t \t \t //image 
 
\t \t \t \t \t \t var blob = items[i].getAsFile(); 
 
\t \t \t \t \t \t var URLObj = window.URL || window.webkitURL; 
 
\t \t \t \t \t \t var source = URLObj.createObjectURL(blob); 
 
\t \t \t \t \t \t this.paste_createImage(source); 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 
\t \t \t \t e.preventDefault(); 
 
\t \t \t } 
 
\t \t \t else { 
 
\t \t \t \t //wait for DOMSubtreeModified event 
 
\t \t \t \t //https://bugzilla.mozilla.org/show_bug.cgi?id=891247 
 
\t \t \t } 
 
\t \t } 
 
\t }; 
 
\t //on keyboard press 
 
\t this.on_keyboard_action = function (event) { 
 
\t \t k = event.keyCode; 
 
\t \t //ctrl 
 
\t \t if (k == 17 || event.metaKey || event.ctrlKey) { 
 
\t \t \t if (ctrl_pressed == false) 
 
\t \t \t \t ctrl_pressed = true; 
 
\t \t } 
 
\t \t //v 
 
\t \t if (k == 86) { 
 
\t \t \t if (document.activeElement != undefined && document.activeElement.type == 'text') { 
 
\t \t \t \t //let user paste into some input 
 
\t \t \t \t return false; 
 
\t \t \t } 
 

 
\t \t \t if (ctrl_pressed == true && pasteCatcher != undefined){ 
 
\t \t \t \t pasteCatcher.focus(); 
 
\t \t \t } 
 
\t \t } 
 
\t }; 
 
\t //on kaybord release 
 
\t this.on_keyboardup_action = function (event) { 
 
\t \t //ctrl 
 
\t \t if (event.ctrlKey == false && ctrl_pressed == true) { 
 
\t \t \t ctrl_pressed = false; 
 
\t \t } 
 
\t \t //command 
 
\t \t else if(event.metaKey == false && command_pressed == true){ 
 
\t \t \t command_pressed = false; 
 
\t \t \t ctrl_pressed = false; 
 
\t \t } 
 
\t }; 
 
\t //draw pasted image to canvas 
 
\t this.paste_createImage = function (source) { 
 
\t \t var pastedImage = new Image(); 
 
\t \t pastedImage.onload = function() { 
 
\t \t \t if(autoresize == true){ 
 
\t \t \t \t //resize 
 
\t \t \t \t canvas.width = pastedImage.width; 
 
\t \t \t \t canvas.height = pastedImage.height; 
 
\t \t \t } 
 
\t \t \t else{ 
 
\t \t \t \t //clear canvas 
 
\t \t \t \t ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
\t \t \t } 
 
\t \t \t ctx.drawImage(pastedImage, 0, 0); 
 
\t \t }; 
 
\t \t pastedImage.src = source; 
 
\t }; 
 
}
1. Copy image data into clipboard or press Print Screen <br> 
 
2. Press Ctrl+V (page/iframe must be focused): 
 
<br /><br /> 
 
<canvas style="border:1px solid grey;" id="my_canvas" width="300" height="300"></canvas>

+0

Cảm ơn! Thật là nhẹ nhõm! –

+4

Có giải pháp đơn giản nào trong tháng 4 năm 2014 không? mà không phân biệt các trình duyệt? –

+2

Nó phải đơn giản: http://jsfiddle.net/KJW4E/222/ - hiện chỉ có chrome. Trong tương lai, có khả năng ví dụ này sẽ hoạt động trên tất cả các trình duyệt. Đáng buồn là các trình duyệt khác có một số hạn chế, cần phải bỏ qua. – ViliusL