我有一个正在使用的Fabric.js应用程序,我注意到,如果我选择一个框架,添加一个图像,然后尝试调整图像的大小,它将使图像失真;添加的图像离开框架,然后无法选择。我希望它保留在框架的空间中。是什么原因造成的/我该如何解决?
当我试图使图像无意识地大于空间时,发生的情况似乎更多。
这是我现在正在使用的代码:
var mainCanvas, canvas1, canvas2, padding = 10,
view = false;
function dropText() {
var text = new fabric.IText('test');
mainCanvas.add(text);
}
function changeView(value) {
if (view) {
$viewText.textContent = "Back";
mainCanvas = canvas1;
$('#canvas1').parent().css('display', 'block');
$('#canvas2').parent().css('display', 'none');
} else {
$viewText.textContent = "Front";
mainCanvas = canvas2;
$('#canvas1').parent().css('display', 'none');
$('#canvas2').parent().css('display', 'block');
}
canvas1.setHeight(412);
canvas1.setWidth(637);
canvas2.setHeight(412);
canvas2.setWidth(637);
view = !view;
}
// Save as image
function download(url, name) {
$('#downloader').attr({
href: url,
download: name
})[0].click();
}
function save() {
mainCanvas.deactivateAll().renderAll();
var c = document.getElementById('canvas1');
var dataURL = c.toDataURL();
var name = 'image';
download(dataURL, name + ".png");
var c = document.getElementById('canvas2');
var dataURL = c.toDataURL();
var name = 'image';
download(dataURL, name + ".png");
}
function setBg(bgUrl) {
if (mainCanvas.bg) {
mainCanvas.bg.remove();
}
var imgObj = new Image();
imgObj.setAttribute('crossOrigin', 'anonymous');
imgObj.src = bgUrl;
imgObj.onload = function() {
var img = new fabric.Image(imgObj);
img.id = 'bg';
img.scaleToWidth(mainCanvas.width);
img.selectable = false;
mainCanvas.add(img);
mainCanvas.bg = img;
setZIndexes();
}
}
function setFrame(frameUrl) {
if (mainCanvas.frame) {
mainCanvas.frame.remove();
}
var imgObj = new Image();
imgObj.setAttribute('crossOrigin', 'anonymous');
imgObj.src = frameUrl;
imgObj.onload = function() {
var img = new fabric.Image(imgObj);
img.id = 'frame';
img.left = 325;
img.top = 72;
img.scaleToHeight(280);
img.selectable = false;
mainCanvas.add(img);
if (mainCanvas.pic) {
mainCanvas.pic.left = img.left + 2 * padding;
mainCanvas.pic.top = img.top + 2 * padding;
mainCanvas.pic.scaleToWidth(img.getWidth() - 4 * padding);
mainCanvas.renderAll();
}
mainCanvas.frame = img;
setZIndexes();
}
}
function setAccent(accentUrl) {
var imgObj = new Image();
imgObj.setAttribute('crossOrigin', 'anonymous');
imgObj.src = accentUrl;
imgObj.onload = function() {
var img = new fabric.Image(imgObj);
img.id = 'accent';
img.left = 60;
img.top = 205;
mainCanvas.add(img);
mainCanvas.accents.push(img);
setZIndexes();
}
}
function setZIndexes() {
var curr_zIndex = 0;
if (mainCanvas.bg) {
mainCanvas.bg.moveTo(curr_zIndex++);
}
if (mainCanvas.accents) {
mainCanvas.accents.forEach(function(accent) {
accent.moveTo(curr_zIndex++);
});
}
if (mainCanvas.pic) {
mainCanvas.pic.moveTo(curr_zIndex++);
}
if (mainCanvas.frame) {
mainCanvas.frame.moveTo(curr_zIndex++);
}
mainCanvas.getObjects().forEach(function(obj) {
if (obj.isType('i-text')) {
obj.moveTo(curr_zIndex++);
}
});
}
function loadJsonIntoCanvas(json, canvas) {
fabric.util.enlivenObjects(json, function(objects) {
objects.forEach(function(obj) {
if (obj.id) {
if (obj.id === 'bg') {
if (canvas.bg) {
canvas.bg.remove();
}
canvas.bg = obj;
} else if (obj.id === 'frame') {
if (canvas.frame) {
canvas.frame.remove();
}
canvas.frame = obj;
} else if (obj.id === 'pic') {
if (canvas.pic) {
canvas.pic.remove();
}
canvas.pic = obj;
} else if (obj.id === 'accent') {
canvas.accents.forEach(function(accent) {
accent.remove();
});
canvas.accents.push(obj);
}
}
canvas.add(obj);
canvas.renderAll.bind(canvas);
});
});
}
$(function() {
$viewText = document.querySelector("#viewText");
canvas1 = new fabric.Canvas('canvas1');
canvas1.accents = [];
canvas2 = new fabric.Canvas('canvas2');
canvas2.accents = [];
changeView(1);
// canvas2json
$("#canvas2json").click(function() {
var json = {};
json.c1 = canvas1.toJSON(['selectable', 'id']);
json.c2 = canvas2.toJSON(['selectable', 'id']);
$("#myTextArea").text(JSON.stringify(json));
var a = document.createElement("a");
var file = new Blob([JSON.stringify(json)], {
type: 'text/plain'
});
var url = URL.createObjectURL(file);
var name = 'json.txt';
download(url, name);
});
// load json2canvas
$("#loadJson2Canvas").click(function() {
var dataToLoad = JSON.parse($("#myTextArea").val());
canvas1.loadFromJSON(
dataToLoad.c1,
canvas1.renderAll.bind(canvas1),
function(o, object) {
console.log(o, object)
});
canvas2.loadFromJSON(
dataToLoad.c2,
canvas2.renderAll.bind(canvas2),
function(o, object) {
console.log(o, object)
});
});
$('#jsonload').change(function(e) {
var file = e.target.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
data = JSON.parse(data);
loadJsonIntoCanvas(data.c1.objects, canvas1);
loadJsonIntoCanvas(data.c2.objects, canvas2);
};
reader.readAsText(file);
});
$(this).val(null);
// Bleed area
mainCanvas.on('object:moving', function(e) {
var obj = e.target;
// if object is too big ignore
if (obj.currentHeight > obj.canvas.height - padding * 2 ||
obj.currentWidth > obj.canvas.width - padding * 2) {
return;
}
obj.setCoords();
// top-left corner
if (obj.getBoundingRect().top < padding ||
obj.getBoundingRect().left < padding) {
obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top + padding);
obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left + padding);
}
// bot-right corner
if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height - padding ||
obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width - padding) {
obj.top = Math.min(
obj.top,
obj.canvas.height - obj.getBoundingRect().height + obj.top - obj.getBoundingRect().top - padding);
obj.left = Math.min(
obj.left,
obj.canvas.width - obj.getBoundingRect().width + obj.left - obj.getBoundingRect().left - padding);
}
});
$("#save").click(save);
// Print
$("#print").click(function() {
mainCanvas.deactivateAll().renderAll();
var dataUrl1 = document.getElementById('canvas1').toDataURL();
var dataUrl2 = document.getElementById('canvas2').toDataURL();
var windowContent = '<!DOCTYPE html>';
windowContent += '<html>';
windowContent += '<head><title>Print</title>';
windowContent += '<style>@media print{.page-break{display:block; page-break-before:always;}}</style>';
windowContent += '</head>';
windowContent += '<body>';
windowContent += '<img src="' + dataUrl1 + '" onload=window.print();window.close();>';
windowContent += '<div class="page-break"></div>';
windowContent += '<img src="' + dataUrl2 + '" onload=window.print();window.close();>';
windowContent += '</body>';
windowContent += '</html>';
var printWin = window.open('', '', 'width=340,height=260');
printWin.document.open();
printWin.document.write(windowContent);
});
//Add Image From Computer
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var imgObj = new Image();
imgObj.setAttribute('crossOrigin', 'anonymous');
imgObj.src = event.target.result;
imgObj.onload = function() {
if (mainCanvas.pic) {
mainCanvas.pic.remove();
}
var image = new fabric.Image(imgObj);
mainCanvas.pic = image;
image.id = 'pic';
if (mainCanvas.frame) {
image.left = mainCanvas.frame.left + 2 * padding;
image.top = mainCanvas.frame.top + 2 * padding;
image.scaleToWidth(mainCanvas.frame.getWidth() - 4 * padding);
} else {
image.set({
left: 360,
top: 102,
selectable: true,
}).scaleToHeight(220);
}
image.on('moving', function(e) {
if (!mainCanvas.frame) {
return;
}
image.setCoords();
var iRect = image.getBoundingRect();
if (!(iRect.left >= mainCanvas.frame.oCoords.tl.x && mainCanvas.frame.oCoords.br.x >= iRect.left + iRect.width)) {
image.left = image.lastLeft;
} else {
image.lastLeft = image.left;
}
if (!(mainCanvas.frame.oCoords.br.y >= iRect.top + iRect.height && iRect.top >= mainCanvas.frame.oCoords.tl.y)) {
image.top = image.lastTop;
} else {
image.lastTop = image.top;
}
});
image.on('scaling', function(e) {
if (!mainCanvas.frame) {
return;
}
var maxScaleX = (mainCanvas.frame.getWidth() - 4 * padding) / this.width;
var maxScaleY = (mainCanvas.frame.getHeight() - 4 * padding) / this.height;
if (this.scaleX > maxScaleX) {
this.scaleX = maxScaleX;
this.left = this.lastGoodLeft;
this.top = this.lastGoodTop;
}
if (this.scaleY > maxScaleY) {
this.scaleY = maxScaleY;
this.left = this.lastGoodLeft;
this.top = this.lastGoodTop;
}
this.lastGoodTop = this.top;
this.lastGoodLeft = this.left;
});
mainCanvas.add(image);
setZIndexes();
mainCanvas.renderAll();
}
}
reader.readAsDataURL(e.target.files[0]);
}
$('#bg1').click(function() {
setBg('https://images.unsplash.com/photo-1515017371642-d0cc17ccdb4f?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3349f3bdeaf8d3984e5b9a0e4d5ab1ca&auto=format&fit=crop&w=1000&q=60');
});
$('#bg2').click(function() {
setBg('https://images.unsplash.com/photo-1438979087584-602939abfd2d?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=af76e0e3f8dd5e2d18cc9abfb63d9209&auto=format&fit=crop&w=1000&q=60');
});
$('#frame1').click(function() {
setFrame('https://i.imgur.com/MdX89Ix.png');
});
$('#frame2').click(function() {
setFrame('https://i.imgur.com/JMKASh4.png');
});
$('#accent1').click(function() {
setAccent('https://images.unsplash.com/photo-1529096117001-6d01d3bcaae7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=a27432a370cc564aaa82d7c3f1e38031&auto=format&fit=crop&w=250&q=60');
});
$('#accent2').click(function() {
setAccent('https://images.unsplash.com/photo-1521158611-6b569322677d?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=12bfcbf03e57cc99472bfb4f99541487&auto=format&fit=crop&w=250&q=60');
});
});
canvas {
border-radius: 3px;
border: 1px solid #343A40;
margin: auto;
margin-top: 10px;
}
#myTextArea {
width: 400px;
height: 400px;
}
input[type='file'] {
color: transparent;
max-width: 78px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<button onclick="dropText();">Drop Text</button>
<button id="bg1">BG 1</button>
<button id="bg2">BG 2</button>
<button id="frame1">Frame 1</button>
<button id="frame2">Frame 2</button>
<button id="accent1">Accent 1</button>
<button id="accent2">Accent 2</button>
<a id="addimg">Image from Device:
<input type="file" id="imgLoader" />
</a>
<br><br> Load JSON: <input type="file" id="jsonload" />
<button id='canvas2json'>Create + Save JSON</button>
<!-- <button id='loadJson2Canvas'>Load JSON Text Area to Canvas</button> -->
<br><br>
<button onclick="changeView(1);"><span id="viewText">(Front)</span></button>
<button id="save">Save as PNG</button>
<button id="print">Print Canvases as PDF</button>
<div style="text-align: center">
<canvas id="canvas1" width="400" height="400"></canvas>
<canvas id="canvas2" width="400" height="400"></canvas>
</div>
<a id="downloader"></a>
<!-- <br> JSON Generated on Save:<br>
<textarea id='myTextArea' onfocus="this.select();" onmouseup="return false;"></textarea> -->
这是一个示例图片,您可以用来测试它并了解我的意思,如果您愿意:https://imgur.com/SNFqL3i