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>