I want to wrap images and text on sample papercup. When a image is uploaded on canvas, I want to wrap it around the background image of papercup whose position is fixed at a
You can draw a user image like this:
On to this paper cup:
With results like this:
Using this example code:
Modify this example to fit your needs. Good luck with your project!
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;
}
body {
background-color: ivory;
}
canvas {
border: 1px solid red;
}
<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>
ADDITIONAL NOTE: The example above creates the effect on an Html Canvas element
That's done because the effect requires the context.drawImage
method which is available in the native Canvas element.
Once you create your effect using native canvas, you can easily use that native canvas as an image source to create a FabricJS Image object (fabric.Image accepts an html canvas as an image source):
// 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);