canvas realizes the picture around the cup to prevent the deformation command in psd

We usually use ps to modify the image through the deformation command to fit it on the cup. How can we make it with canvas?

Examples in ps

The demand I met is to complete the real-time rendering preview of a cup, so I need to realize this bending effect. First I write the code, and then explain the principle

	var canvas = document.getElementById("canvas");
		var ctx = canvas.getContext("2d");

		var img = new Image();
		img.onload = start;

		var productImg = new Image();
		productImg.onload = function() {
			var iw = productImg.width;
			var ih = productImg.height;
			canvas.width = iw * 2 / 3;
			canvas.height = ih * 2 / 3;
			ctx.drawImage(productImg, 0, 0, productImg.width * 2 / 3, productImg.height * 2 / 3);
			//			img.src='/img/test/i.jpg';
		};
		productImg.src = "img/cola.jpeg";

		$(function() {
			$('#change').on('change', function(ev) {
//				console.log(ev);
				var reader = new FileReader();
				var file = this.files[0];
//				console.log(file)
				reader.onload = function(ev) {
					//self.imagePress(ev.target.result, self.option.sizeMax, function(dataURL, blob) {
					//					console.log(ev.target.result);
					img.src = ev.target.result
				}
				reader.readAsDataURL(file);
			})
		})

		function start() {
			var iw = img.width;
			var ih = img.height;

			var xOffset = 190,
				yOffset = 212;

			var a = 80.0;
			var b = 15.0;

			var scaleFactor = iw / (2 * a);


			for(var X = 0; X < 2 * a; X++) {
				var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
				for(var Y = 0; Y < 194 + y * 2; Y++) {
					var _scaleFactor = ih / (194 + y * 2);
					var scaleFactor = iw / (2 * a - Y / 5);
					if(Y < X * 10 && Y < -10 * X + 2 * a * 10) { //Y<x*10
						ctx.drawImage(img, (X - Y / 10) * scaleFactor , Y * _scaleFactor, 1, 1, X + xOffset, y + yOffset + Y, 1, 1);
					}
				}

			}
			//Edge banding, drawing line segments to cover roughness
			ctx.beginPath();
			ctx.moveTo(xOffset, yOffset);
			ctx.lineTo(xOffset + 226 / 10, yOffset + 226);
			ctx.strokeStyle = '#fff';
			ctx.lineWidth = 3;
			ctx.stroke();

			ctx.beginPath();
			ctx.moveTo(xOffset + 2 * a + 1, yOffset);
			ctx.lineTo(xOffset + 2 * a + 1 - 226 / 10, yOffset + 226);
			ctx.strokeStyle = '#fff';
			ctx.lineWidth = 3;
			ctx.stroke();

			ctx.beginPath();
			ctx.moveTo(xOffset, yOffset + 1);
			ctx.bezierCurveTo(xOffset + a / 2 - 10, yOffset + 20, xOffset + a * 3 / 2 + 15, yOffset + 20, xOffset + 2 * a, yOffset + 1);
			ctx.strokeStyle = 'rgb(230,230,230)';
			ctx.lineWidth = 3;
			ctx.stroke();

			ctx.beginPath();
			ctx.moveTo(xOffset + 226 / 10, yOffset+226-1);
			ctx.bezierCurveTo(xOffset + 226 / 10 + a / 2 -5, yOffset+226 + 18, xOffset + 226 / 10 + a * 3 / 2 - 35, yOffset+226 + 18, xOffset + 226 / 10 +  a*3/2-3, yOffset+226 -1);
			ctx.strokeStyle = '#fff';
			ctx.lineWidth = 3;
			ctx.stroke();

If it works normally, you will get such a picture

There is an obvious feeling of lower arc

To achieve this radian, we must first operate in two steps

The main idea is to draw the outline of the cup, and then paste the picture corresponding to the position and proportion. First, draw the shape with the upper and lower ellipses:

Looking at the above figure, we can see that we only need to cut the original drawing according to the vertical shape, and then draw the shape with upper and lower semicircles. Just paste the picture at the corresponding position. Now let's see how to draw the shape with upper and lower semicircles:

After looking at the calculation method of the ellipse above, there is another ellipse below. The next ellipse is a little simpler to see how it relates to the ellipse above:

Just now we have a general understanding of how ellipses are cut. Now let's look at how ellipses + beveled edges are cut. Compared with ellipse cutting, it is a little more complex. It will cut vertically at the same time:

 

Now let's look at the equations of the left and right lines, one is y=10*x, the other is y=20*a-10*x;

So far, we have completed all the picture drawing. The application scenario of this code is cylinder, but it is not flexible enough in case of special perspective relationship. If we can directly analyze the deformation command in psd, it will be more flexible by replacing intelligent layers

I recently found a website that can realize this idea and share it with you. Interested students can have a try

Program replace PSD smart layer https://foxpsd.com/https://foxpsd.com/

Keywords: Javascript Front-end html5

Added by xgrewellx on Mon, 03 Jan 2022 22:52:46 +0200