我想在样品纸杯上包装图像和文字。 当图像上传到画布上时,我想将它包裹在纸杯的背景图像上,纸杯的位置始终是固定的。 我正在使用Fabric JS作为html5画布工具。 这是我的代码,但它只显示1像素的图像,当我点击图像拖放时,它就是VANISHES。
HTML:
<div id="container">
<input type="file" id="imageLoader" name="imageLoader" />
Remove:<input type="button" value="remove" id="imageRemove" name="imageRemove" onClick="handleRemove()"/>
<canvas id="canvas" width="500" height="400" style="width:1000px;height:500px;margin-left:5%;" ></canvas>
</div>
JS:
var offsetY=[0,1,2,3,4,5,6,5,4,3,2,1,0];
var canvas = new fabric.Canvas('canvas', {
backgroundColor: 'rgb(240,240,240)'
});
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var image = new Image();
image.onload = function () {
var width = image.width,
height = image.height;
var context = $("canvas")[0].getContext("2d");
for(var x=0;x<offsetY.length;x++){
context.drawImage(image,
x,0,1,image.height,
x,offsetY[x],1,image.height);
}
};
image.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
function handleRemove() {
canvas.clear().renderAll();
}
我是html5画布的新手,请帮忙。
答案 0 :(得分:8)
您可以像这样绘制用户图片:
关于本文杯:
结果如下:
使用此示例代码:
修改此示例以满足您的需求。祝你的项目好运!
var faceCanvas = document.getElementById('face');
var faceCtx = faceCanvas.getContext('2d');
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw, ch;
$myslider = $('#myslider');
$myslider.val(50);
var PI = Math.PI;
var cupTop = 78;
var cupBottom = 295;
var dxx = 19;
var dyy = 34;
var l = {
x0: 41,
y0: cupTop,
x1: 74,
y1: cupBottom
};
var r = {
x0: 249,
y0: cupTop,
x1: 218,
y1: cupBottom
};
var t = {
x0: l.x0,
y0: l.y0,
x1: l.x0 + dxx,
y1: r.y0 + dyy,
x2: r.x0 - dxx,
y2: r.y0 + dyy,
x3: r.x0,
y3: r.y0
};
var b = {
x0: l.x1,
y0: l.y1,
x1: l.x1 + dxx,
y1: r.y1 + dyy,
x2: r.x1 - dxx,
y2: r.y1 + dyy,
x3: r.x1,
y3: r.y1
};
var topOffset = 40;
var imgCount = 2;
var cup = new Image();
cup.crossOrigin = 'anonymous';
cup.onload = start;
var pic = new Image();
pic.crossOrigin = 'anonymous';
pic.onload = start;
cup.src = 'https://image.ibb.co/iKJvyc/VENFv.png';
pic.src = 'https://image.ibb.co/dJHG4H/Pu7aY.jpg';
function start() {
if (--imgCount > 0) {
return;
}
cw = canvas.width = faceCanvas.width = cup.width;
ch = canvas.height = faceCanvas.height = cup.height;
draw();
face();
$myslider.change(function() {
var value = parseInt($(this).val()) / 100;
topOffset = (l.y1 - l.y0 - pic.height) * value;
draw();
face();
});
}
function face() {
//
var lm = (l.y1 - l.y0) / (l.x1 - l.x0);
var lb = l.y1 - (lm * l.x1);
//
var rm = (r.y1 - r.y0) / (r.x1 - r.x0);
var rb = r.y1 - (rm * r.x1);
faceCtx.clearRect(0, 0, faceCanvas.width, faceCanvas.height);
for (var y = 0; y < pic.height; y++) {
var yy = cupTop + topOffset + y;
var leftX = (yy - lb) / lm;
var rightX = (yy - rb) / rm;
var width = rightX - leftX;
faceCtx.drawImage(
pic,
0, y, pic.width, 1,
leftX, yy, width, 1
);
}
var yy = cupTop + topOffset;
var p0 = {
x: (yy - lb) / lm,
y: cupTop + topOffset
};
var p3 = {
x: (yy - rb) / rm,
y: cupTop + topOffset
};
var p1 = {
x: p0.x + dxx,
y: p0.y + dyy
};
var p2 = {
x: p3.x - dxx,
y: p3.y + dyy
};
var points = calcPointsOnBezier(p0, p1, p2, p3);
for (var x in points) {
var y = points[x];
ctx.drawImage(faceCanvas, x, 0, 1, ch, x, y - yy, 1, ch);
}
}
function calcPointsOnBezier(p0, p1, p2, p3) {
var points = {};
for (var x = parseInt(p0.x); x < parseInt(p3.x + 1); x++) {
points[x] = p0.y;
}
for (var i = 0; i < 1000; i++) {
var t = i / 1000;
var pt = getCubicBezierXYatT(p0, p1, p2, p3, t);
points[parseInt(pt.x)] = parseInt(pt.y);
}
return (points);
}
function draw() {
ctx.strokeStyle = 'gold';
ctx.clearRect(0, 0, cw, ch);
ctx.drawImage(cup, 0, 0);
// diagnostic();
}
function diagnostic() {
ctx.beginPath();
ctx.moveTo(l.x0, l.y0);
ctx.lineTo(l.x1, l.y1);
ctx.moveTo(r.x0, r.y0);
ctx.lineTo(r.x1, r.y1);
ctx.lineWidth = 3;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(t.x0, t.y0);
ctx.bezierCurveTo(t.x1, t.y1, t.x2, t.y2, t.x3, t.y3);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(b.x0, b.y0);
ctx.bezierCurveTo(b.x1, b.y1, b.x2, b.y2, b.x3, b.y3);
ctx.stroke();
}
function getCubicBezierXYatT(startPt, controlPt1, controlPt2, endPt, T) {
var x = CubicN(T, startPt.x, controlPt1.x, controlPt2.x, endPt.x);
var y = CubicN(T, startPt.y, controlPt1.y, controlPt2.y, endPt.y);
return ({
x: x,
y: y
});
}
// cubic helper formula at T distance
function CubicN(T, a, b, c, d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T +
(3 * b + T * (-6 * b + b * 3 * T)) * T +
(c * 3 - c * 3 * T) * t2 +
d * t3;
}
&#13;
body {
background-color: ivory;
}
canvas {
border: 1px solid red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Vertical Position:<input id=myslider type=range min=0 max=100 value=50><br>
<canvas id="canvas" width=300 height=300></canvas>
<canvas id="face" width=300 height=300 hidden></canvas>
&#13;
附加说明:上面的示例在Html Canvas元素上创建效果
这样做是因为效果需要本地Canvas元素中可用的context.drawImage
方法。
使用原生画布创建效果后,您可以轻松地使用该原生画布作为图像源来创建FabricJS Image对象( fabric.Image接受html画布作为图像源):
// get a reference to the html canvas with the
// "image around mug" effect
var canvas=document.getElementById("canvas");
// create a fabric.Image using that html canvas
// as an image source
var c=new fabric.Canvas('c');
var myFabricImage=new fabric.Image(canvas, {
left: 50,
top: 50,
});
c.add(myFabricImage);