2

My goal is to wrap a image over a coffee mug virtually using HTML5 and javascript.

I have created a prototype: http://jsfiddle.net/sandeepkum88/uamov2m7/

Currently I am cutting the image in strips of width 1px and then placing those strips on the bezier curve.

var img = new Image();
img.onload = start;
img.src = "http://in-sandeep.printvenue.org/test-images/mug-strap.png";
var pointer = 0;

function start() {

    var iw = 198.97826;
    var ih = img.height;

    var x1 = 50;
    var y1 = 40;
    var x2 = 97;
    var y2 = 60;
    var x3 = 152;
    var y3 = 40;

    // calc unit value for t to calculate bezier curve
    var unitT = 1 / iw;

    // put image slices on the curve
    for (var X = 0, t = 0; X < iw; X++, t+=unitT) {
        var xTop = (1-t) * (1-t) * x1 + 2 * (1 - t) * t * x2 + t * t * x3;
        var yTop = (1-t) * (1-t) * y1 + 2 * (1 - t) * t * y2 + t * t * y3;
        ctx.drawImage(img, X + pointer, 0, 1, ih, xTop, yTop, 0.85, ih-188);
    }
}

But I am not satisfied with the result.

Am I doing it wrong somewhere? Is there any better alternative. What if top curve and bottom curve are different.

Is there a way to achieve this using transformation matrix?

  • My first thought: start from a rotating cube, like with this plugin http://www.kevs3d.co.uk/dev/canvask3d/k3d_test.html ; Instead of 4 surfaces you make 8, then 16, ... until you get strips of the right size. I have no idea if I'm pointing you to a good direction, it's just my first thought – Emmanuel Delay Jul 15 '15 at 09:50
  • can you please explain. I didn't get your notion. sorry – Sandeep Kumar Roy Jul 15 '15 at 11:22
  • **The 2d way**: To give the illusion that the cup is rotating (and showing new parts of the applied image), *show only a part of the total image wrapped around the cup at any one time*. The cup image will not rotate at all. For example, assume that you have an image (to wrap) that is 400px wide of which you want to show 250px wrapped on the cup at any one time. Start by cropping the leftmost 250px (x=0-249) of the image and wrap it. As the user pans right, crop increasingly rightward pixels (1-250) and wrap it, etc. – markE Jul 15 '15 at 17:54
  • **The 3d way**: If your client browsers support webGL you can simply use texture mapping to wrap your image around a curved portion of your cup. – markE Jul 15 '15 at 17:56
  • **The 2d faking 3d way**: You can "fake" 3d texture mapping using 2d canvas plus some math. The math divides an image into triangles and then uses a transformation matrix to interpolate each triangle pixel into a perspective position. Here's a previous SO answer that uses the math technique to "unwarp" an image. Just reverse the technique used in this answer to "warp" your image around the cup: http://stackoverflow.com/questions/30565987/cropping-images-with-html5-canvas-in-a-non-rectangular-shape-and-transforming/30566272#30566272 – markE Jul 15 '15 at 18:07
  • I have already tried the 2d way. And its working till some extent. ( See JsFiddle link ). I only have problem with its finishing. – Sandeep Kumar Roy Jul 16 '15 at 06:13
  • Is there a way to achieve this trough transformation matrix ( vector method ). If not then I have to consider some server side alternative. but there i can't show the rotating effect of the cup. – Sandeep Kumar Roy Jul 16 '15 at 06:17
  • You say: *"I only have problem with its finishing..."*? Your rotating fiddle looks adequate for a simple product demo (Maybe create a clipping region to clean up the top & bottom artifacts of your offset slices). If you want the cup to rotate infinitely, just add another copy of the applied image to the right and left of the original applied image. You can modify this SO answer to create an applied image that infinitely rotates on your cup: http://stackoverflow.com/questions/20263954/make-a-bitmap-wrap-around-the-canvas-for-infinite-scrolling/20273738#20273738 – markE Jul 16 '15 at 15:20
  • you could also use three.js >> http://threejsplaygnd.brangerbriz.net/s/?id=2485 – Nick Briz Sep 15 '15 at 19:22

0 Answers0