在以下代码中,在 Fabric.js 中单击鼠标时 Canvas 层消失,并且 Firefox 在创建画布到图像时停止响应?
Posted
技术标签:
【中文标题】在以下代码中,在 Fabric.js 中单击鼠标时 Canvas 层消失,并且 Firefox 在创建画布到图像时停止响应?【英文标题】:In the following code, Canvas layer disappears on mouse click in Fabric.js and Firefox stops responding when creating canvas to image? 【发布时间】:2013-07-02 08:20:12 【问题描述】:http://jsfiddle.net/rodrigopandini/gj7HT/
我正在使用此示例使用 Fabric.js 将图像从我的计算机拖放到画布。
//Drag and Drop Image
var canvas = new fabric.Canvas('c');
function handleDragStart(e)
[].forEach.call(images, function (img)
img.classList.remove('img_dragging');
);
this.classList.add('img_dragging');
function handleDragOver(e)
if (e.preventDefault)
e.preventDefault(); // Necessary. Allows us to drop.
e.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
// NOTE: comment above refers to the article (see top) -natchiketa
return false;
function handleDragEnter(e)
// this / e.target is the current hover target.
this.classList.add('over');
function handleDragLeave(e)
this.classList.remove('over'); // this / e.target is previous target element.
function handleDrop(e)
// this / e.target is current target element.
/*
if (e.stopPropagation)
e.stopPropagation(); // stops the browser from redirecting.
*/
e.stopPropagation(); // Stops some browsers from redirecting.
e.preventDefault(); // Stops some browsers from redirecting.
// handle desktop images
if (e.dataTransfer.files.length > 0)
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++)
// Only process image files.
if (f.type.match('image.*'))
// Read the File objects in this FileList.
var reader = new FileReader();
// listener for the onload event
reader.onload = function (evt)
// create img element
var img = document.createElement('img');
img.src = evt.target.result;
// put image on canvas
var newImage = new fabric.Image(img,
width: img.width,
height: img.height,
// Set the center of the new object based on the event coordinates relative to the canvas container.
left: e.layerX,
top: e.layerY
);
canvas.add(newImage);
;
// Read in the image file as a data URL.
reader.readAsDataURL(f);
// handle browser images
else
var img = document.querySelector('#images img.img_dragging');
var newImage = new fabric.Image(img,
width: img.width,
height: img.height,
// Set the center of the new object based on the event coordinates relative to the canvas container.
left: e.layerX,
top: e.layerY
);
canvas.add(newImage);
return false;
function handleDragEnd(e)
// this/e.target is the source node.
[].forEach.call(images, function (img)
img.classList.remove('img_dragging');
);
if (Modernizr.draganddrop)
// Browser supports html5 DnD.
// Bind the event listeners for the image elements
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img)
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
);
// Bind the event listeners for the canvas
var canvasContainer = document.getElementById('canvas-container');
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
else
// Replace with a fallback to a library solution.
alert("This browser doesn't support the HTML5 Drag and Drop API.");
//End Drag and Drop
为了通过拖放添加多个图像,我使用了上面的代码(jsfiddle 示例)。 这是我的代码,当我在 Canvas 上一张一张地添加图像时,它运行良好。
var $ = function (id) return document.getElementById(id) ;
//Upload Click
var fileSelect = document.getElementById("fileSelect"),
upload = document.getElementById("upload");
fileSelect.addEventListener("click", function (e)
if (upload)
upload.click();
e.preventDefault(); // prevent navigation to "#"
, false);
//End
function applyFilter(index, filter)
var obj = canvas.getActiveObject();
obj.filters[index] = filter;
obj.applyFilters(canvas.renderAll.bind(canvas));
function applyFilterValue(index, prop, value)
var obj = canvas.getActiveObject();
if (obj.filters[index])
obj.filters[index][prop] = value;
obj.applyFilters(canvas.renderAll.bind(canvas));
var canvas = new fabric.Canvas('c'),
f = fabric.Image.filters;
//Canvas Events
canvas.on(
'object:selected': function ()
fabric.util.toArray(document.getElementsByTagName('input'))
.forEach(function (el)
el.disabled = false;
)
//Check for already applied filter on Image after selecting an image
var filters = ['grayscale', 'invert', 'remove-white', 'sepia', 'sepia2',
'brightness', 'noise', 'gradient-transparency', 'pixelate',
'blur', 'sharpen'];
for (var i = 0; i < filters.length; i++)
$(filters[i]).checked = !!canvas.getActiveObject().filters[i];
canvas._activeObject.bringToFront();
,
//'selection:cleared': function()
// fabric.util.toArray(document.getElementsByTagName('input'))
// .forEach(function(el) el.disabled = true; )
//
);
var imageLoader = document.getElementById('upload');
imageLoader.addEventListener('change', handleImage, false);
var c = document.getElementById('c');
var context = canvas.getContext('2d');
//Canvas Handler
function handleImage(e)
var reader = new FileReader();
reader.onload = function (event)
var img = new Image();
img.onload = function ()
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img);
img.src = event.target.result;
reader.readAsDataURL(e.target.files[0]);
//Fabric.JS single image handler
document.getElementById('upload').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: 250,
top: 250,
angle: 20,
padding: 10,
cornersize: 10,
).scale(0.4);
canvas.add(image);
reader.readAsDataURL(e.target.files[0]);
//End
//Static Image in background
function setBackgrnd()
fabric.Image.fromURL('/2-road.jpg', function (img)
var oImg = img.set( left: 400, top: 300, opactiy:0.5, selectable:false, lockHorizontally: false, lockVertically: false, lockScaling: false, lockRotation: false ).scale(1);
//oImg.filters.push(new fabric.Image.filters.blur());
//oImg.applyFilters(canvas.renderAll.bind(canvas));
//canvas.setBackgroundImage('/2-road.jpg', canvas.renderAll.bind(canvas));
canvas.add(oImg).renderAll();
canvas.setActiveObject(oImg);
canvas.sendToBack(oImg);
$('#delBackgrnd').click(function()
canvas.getObjects();
remove(oImg);
canvas.renderAll();
);
//function setBackgrnd()
// canvas.add(oImg).renderAll();
// canvas.setActiveObject(oImg);
//
//function delBackgrnd()
// fxRemove(oImg, canvas.renderAll());
//
);
//Clears Everything on Canvas
function clearCanvas()
canvas.clear();
//Delete Background Image
function delBackgrnd()
//SelectedObject.onclick = function ()
// if (canvas.getActiveGroup())
// canvas.getActiveGroup().forEachObject(function (o) canvas.remove(o) );
// canvas.discardActiveGroup().renderAll();
// else
// canvas.remove(canvas.getActiveObject());
//
//;
//Generate Collage
function convertCanvasToImage()
//var canvas = document.getElementById('c');
canvas.deactivateAll().renderAll();
var image_src = canvas.toDataURL("image/jpeg");
//document.write('<img src="' + image_src + '"/>');
window.open(image_src);
//Drag and Drop Image
var canvas = new fabric.Canvas('c');
function handleDragStart(e)
[].forEach.call(images, function (img)
img.classList.remove('img_dragging');
);
this.classList.add('img_dragging');
function handleDragOver(e)
if (e.preventDefault)
e.preventDefault(); // Necessary. Allows us to drop.
e.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
// NOTE: comment above refers to the article (see top) -natchiketa
return false;
function handleDragEnter(e)
// this / e.target is the current hover target.
this.classList.add('over');
function handleDragLeave(e)
this.classList.remove('over'); // this / e.target is previous target element.
function handleDrop(e)
// this / e.target is current target element.
/*
if (e.stopPropagation)
e.stopPropagation(); // stops the browser from redirecting.
*/
e.stopPropagation(); // Stops some browsers from redirecting.
e.preventDefault(); // Stops some browsers from redirecting.
// handle desktop images
if (e.dataTransfer.files.length > 0)
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++)
// Only process image files.
if (f.type.match('image.*'))
// Read the File objects in this FileList.
var reader = new FileReader();
// listener for the onload event
reader.onload = function (evt)
// create img element
var img = document.createElement('img');
img.src = evt.target.result;
// put image on canvas
var newImage = new fabric.Image(img,
width: img.width,
height: img.height,
// Set the center of the new object based on the event coordinates relative to the canvas container.
left: e.layerX,
top: e.layerY
);
canvas.add(newImage);
;
// Read in the image file as a data URL.
reader.readAsDataURL(f);
// handle browser images
else
var img = document.querySelector('#images img.img_dragging');
var newImage = new fabric.Image(img,
width: img.width,
height: img.height,
// Set the center of the new object based on the event coordinates relative to the canvas container.
left: e.layerX,
top: e.layerY
);
canvas.add(newImage);
return false;
function handleDragEnd(e)
// this/e.target is the source node.
[].forEach.call(images, function (img)
img.classList.remove('img_dragging');
);
if (Modernizr.draganddrop)
// Browser supports HTML5 DnD.
// Bind the event listeners for the image elements
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img)
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
);
// Bind the event listeners for the canvas
var canvasContainer = document.getElementById('canvas-container');
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
else
// Replace with a fallback to a library solution.
alert("This browser doesn't support the HTML5 Drag and Drop API.");
//End Drag and Drop
//End of Code
我原来的 HTML 画布标签是
<div id="canvas-container" class="canvas-container" >
<canvas id="c" style="left: -300px; border: 1px dotted;"></canvas>
</div>
但是,当我集成此代码时,图像会添加到画布中,但当我单击画布时,它们会消失。我检查了 Chrome 中的元素,发现有 2 个 Canvas 标记。
<div id="canvas-container" class="canvas-container">
<div class="canvas-container" style="width: 800px; height: 600px; position: relative; -webkit-user-select: none;">
<div class="canvas-container" style="width: 800px; height: 600px; position: relative; -webkit-user-select: none;">
<canvas id="c" style="left: 0px; border: 1px dotted; position: absolute; width: 800px; height: 600px; top: 0px; -webkit-user-select: none;" class="lower-canvas"></canvas>
<canvas class="upper-canvas" style="position: absolute; width: 800px; height: 600px; left: 0px; top: 0px; -webkit-user-select: none;"></canvas>
</div>
<canvas class="upper-canvas" style="position: absolute; width: 800px; height: 600px; left: 0px; top: 0px; -webkit-user-select: none;"></canvas>
</div>
</div>
当我将上述代码中所有元素的位置更改为position: relative;
时,它可以工作。
3 个额外的 Canvas 标签是自动生成的。我怎样才能改变位置?此外,当我使用 DataURL 生成画布的 png 或 jpg 图像时,Firefox 停止响应。
【问题讨论】:
【参考方案1】:您需要使用以下代码覆盖该库的 css。
/deep/ .canvas-container
.upper-canvas
position: relative !important;
【讨论】:
以上是关于在以下代码中,在 Fabric.js 中单击鼠标时 Canvas 层消失,并且 Firefox 在创建画布到图像时停止响应?的主要内容,如果未能解决你的问题,请参考以下文章