【发布时间】:2019-12-13 07:02:07
【问题描述】:
我有一个带有 fields_for 的表单,我需要为每个 ff.object.print_location.id 提供一个画布
这是带有帆布的整个表格:
<%= f.fields_for :shop_product_print_files do |ff| %>
<%= ff.object.print_location.title %>
...
...
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-beta.7/fabric.min.js"></script>
<label title="Add a background" class="myFile2%>"><span class="mdi mdi-image"> Add Background</span>
<input type="file" id="file2-<%= "#{ff.object.print_location.id}" %>" />
</label>
<label title="Add an image" class="myFile"><span class="mdi mdi-image"> Add Photo</span>
<input type="file" id="file-<%= "#{ff.object.print_location.id}" %>" />
</label>
<a id="lnkDownload-<%= "#{ff.object.print_location.id}" %>" title="Save"><span class="mdi mdi-download"> Save</span></a>
<canvas id="fCanvas-<%= "#{ff.object.print_location.id}" %>" width="400" height="400"></canvas>
<script>
var canvas = new fabric.Canvas('fCanvas-<%= "#{ff.object.print_location.id}" %>');
var myImage = document.createElement('canvas');
document.getElementById('file-<%= "#{ff.object.print_location.id}" %>').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 0,
top: 0,
angle: 0,
border: '#000',
}).scale(0.2);
canvas.add(oImg).renderAll();
//var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
});
};
reader.readAsDataURL(file);
});
document.getElementById('file2-<%= "#{ff.object.print_location.id}" %>').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
// add background image
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
});
};
reader.readAsDataURL(file);
});
// Download
var imageSaver = document.getElementById('lnkDownload-<%= "#{ff.object.print_location.id}" %>');
imageSaver.addEventListener('click', saveImage, false);
function saveImage(e) {
this.href = canvas.toDataURL({
format: 'png',
quality: 0.8
});
this.download = 'custom-<%= "#{ff.object.print_location.id}" %>.png'
}
</script>
当我这样做 ^ 时,每个 print_location 都会出现画布,但我无法将图像上传到所有人(仅适用于循环中的最后一个画布,并且所有文件上传输入都被放入循环中的最后一个画布中。
例如:如果我为第一个(第二个或第四个等)画布上传文件,它将出现在最后一个画布中)并让它出现。
当我使用时:
const canvas = new fabric.Canvas('fCanvas-<%= "#{ff.object.print_location.id}" %>');
const myImage = document.createElement('canvas');
...画布可以正常工作,但仅适用于第一个 print_location,其他任何一个都没有。
总共有 6 个 print_locations 需要遍历。
在 fields_for 循环中使用 var 时,是什么阻止了文件/图像出现在画布中?
我该怎么做才能让他工作?
这是此工作的代码笔:https://codepen.io/anon/pen/YmEGyW
尝试(删除 file-2 并下载到它只是为了看看我是否可以让画布单独工作然后应用它):
var canvas = new fabric.Canvas('fCanvas');
document.querySelectorAll('[id$=file-']).forEach((fileInput) => {
fileInput.addEventListener('change', function(e){
let id = this.id.replace('file-','');
let canvas = new fabric.Canvas('fCanvas-'+id);
// the rest of your "change" code
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 0,
top: 0,
angle: 0,
border: '#000',
}).scale(0.2);
// canvas.add(oImg).renderAll();
canvas.add(oImg);
//var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
});
};
}
reader.readAsDataURL(file);
});
【问题讨论】:
标签: javascript ruby-on-rails canvas html5-canvas fabricjs