JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product-images-container">
<label for="curve">Curve</label><input size="80" type="text" id="curve" name="curve" value="40,228,100,260,270,260,330,240">
<label for="text">Text</label><input size="80" type="text" id="text" name="text" value="testing 1234567890">
<label for="offset">Y offset</label><input size="80" type="number" id="offset" name="offset" value="5">
<label for="fontsize">Font size</label><input size="80" type="number" id="fontsize" name="fontsize" value="20">
<div class="engravingArea">
<div id="canvasDiv"></div>
</div>
<img class="productImage" src="https://i.imgur.com/BaoChJT.jpeg">
</div>
CSS
.product-images-container {
width:100%;
position:relative;
}
canvas {
position: absolute;
top: 0;
}
.productImage {
width: 100%
}
.engravingArea {
position: relative;
}
#canvasDiv > canvas {
width:100%;
height: auto;
}
JavaScript
var first = true;
var productImage = document.getElementsByClassName('productImage')[0];
var curveOffset = document.getElementById('offset');
var fontSize = document.getElementById('fontsize');
$(productImage).on('load', function() {
startIt();
});
function startIt()
{
canvasDiv = document.getElementById('canvasDiv');
canvasDiv.innerHTML = '<canvas id="layer0" width="' + productImage.naturalWidth + '" height="' + productImage.naturalHeight + '"></canvas>'; //for IE
canvas = document.getElementById('layer0');
ctx = canvas.getContext('2d');
ctx.fillStyle = "green";
curve = document.getElementById('curve');
curveText = document.getElementById('text');
scale = productImage.naturalWidth/400;
$(curve).keyup(function(e) {changeCurve();});
$(curveText).keyup(function(e) {changeCurve();});
$(curveOffset).on('change', changeCurve);
$(fontSize).on('change', changeCurve);
if (first)
{
changeCurve();
first = false;
}
}
function changeCurve()
{
points = curve.value.split(',');
offset = (parseInt(curveOffset.value) || 0);
ctx.font = (parseInt(fontSize.value) || 20)*scale + "px Courier New";
if (points.length == 8)
drawStack();
}
function drawStack()
{
Ribbon = {maxChar: 50, startX: points[0]*scale, startY: (points[1] - offset)*scale,
control1X: points[2]*scale, control1Y: (points[3] - offset)*scale,
control2X: points[4]*scale, control2Y: (points[5] - offset)*scale,
endX: points[6]*scale, endY: (points[7] - offset)*scale};
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.beginPath();
ctx.moveTo(Ribbon.startX,Ribbon.startY);
ctx.bezierCurveTo(Ribbon.control1X,Ribbon.control1Y,
Ribbon.control2X,Ribbon.control2Y,
Ribbon.endX,Ribbon.endY);
ctx.stroke();
ctx.restore();
...