在纸杯上包裹图像

在纸杯上包裹图像

本文介绍了在纸杯上包裹图像(背景图像)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在样品纸杯上包装图像和文字。
当图像上传到画布上时,我想将它包裹在纸杯的背景图像上,纸杯的位置始终是固定的。
我使用Fabric JS作为html5画布工具。
这是我的代码,但它只显示1像素的图像,当我点击图像进行拖放时,它就是VANISHES。

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 all times.I am using Fabric JS for the html5 canvas tool.Here is my code but there it only shows 1pixel of image, also when I click the image to drag and drop ,it VANISHES.

HTML:

<div id="container">
    <input type="file" id="imageLoader" name="imageLoader" />
    Remove:<input type="button" value="remove" id="imageRemove" name="imageRemove" onClick="handleRemove()"/>
    <canvas id="canvas" width="500" height="400" style="width:1000px;height:500px;margin-left:5%;" ></canvas>


</div>

JS:

var offsetY=[0,1,2,3,4,5,6,5,4,3,2,1,0];

var canvas = new fabric.Canvas('canvas', {
    backgroundColor: 'rgb(240,240,240)'
});



var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);

function handleImage(e) {
  var reader = new FileReader();
  reader.onload = function (event) {
    var image = new Image();
    image.onload = function () {
        var width = image.width,
            height = image.height;
        var context = $("canvas")[0].getContext("2d");
        for(var x=0;x<offsetY.length;x++){
            context.drawImage(image,
                x,0,1,image.height,
                x,offsetY[x],1,image.height);
        }

    };
    image.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}

function handleRemove() {
canvas.clear().renderAll();
}

我是html5画布的新手,请帮忙。

I am new at html5 canvas,please help.

推荐答案

您可以像这样绘制用户图像:

关于本文杯:

结果如下:

使用此示例代码:

修改此示例以满足您的需求。祝你的项目好运!

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>

附加说明:上面的示例在Html Canvas元素上创建效果

这样做是因为效果需要 context.drawImage 本机Canvas元素中可用的方法。

That's done because the effect requires the context.drawImage method which is available in the native Canvas element.

使用本机画布创建效果后,您可以轻松地使用该本机画布作为图像源来创建FabricJS Image对象( fabric.Image接受html canvas作为图像源):

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);

这篇关于在纸杯上包裹图像(背景图像)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 15:52