互动弯曲图像 [英] Interactive bend image

查看:259
本文介绍了互动弯曲图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用这种方式在网络浏览器中转换图片



- >
>



更精确地说,它应该是3D效果(像包围图像可以)。我正在考虑这些选项:




  • CSS3 transform(使用matrix3d可能吗?)

  • HTML5 canvas(我目前还没有任何体验)

  • 小程序或闪光灯(这是最不重要的)



我希望有一些简单的聪明的方式如何实现这一点,但一些第三方重库也可以做这个工作。任何建议?

解决方案

您可以将图像切成1像素切片,然后抵消那些切片, / p>

左:图片卷在杯子顶部,右:图片围绕杯子中心。





下面是示例代码和演示:



  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: y1:cupBottom}; var r = {x0:249,y0:cupTop,x1:218,y1:cupBottom}; var t = {x0:1x0,y0:1.y0,x1:1x0 + 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://dl.dropboxusercontent.com/u/139992952/multple/PaperCup.png; //pic.src='https://dl.dropboxusercontent.com/u/139992952/multple /avatars1.jpg';pic.src='https://dl.dropboxusercontent.com/u/139992952/multple/google.png'function start(){if( -  imgCount> 0){return;} cw = canvas.width = faceCanvas.width = cup.width; ch = canvas.height = faceCanvas.height = cup.height;画();面对(); $ myslider.change(function(){var value = parseInt($(this).val())/ 100; topOffset =(l.y1-l.y0-pic.height)* value; draw );});} 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  

  body {background-color:ivory; } canvas {border:1px solid red;}  

  script src =https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js>< / script>垂直位置:< input id = myslider type = range min = 0 max = 100 value = 50>< br>< canvas id =canvaswidth = 300 height = 300>< / canvas>< canvas id =facewidth = 300 height = 300 hidden> ; / canvas>  


I'd like to transform image in web browser this way

->

more precisely, it should be 3D effect (like wrap the image around can). I'm considering these options:

  • CSS3 transform (is it possible with matrix3d somehow?)
  • HTML5 canvas (I don't have any experience here yet)
  • applet or flash (this would be least preffered)

I hope there is some simple smart way how to achieve this, but some 3rd party heavy library could also do the job. Any suggestions?

解决方案

You can slice your image into 1 pixel slices and then offset those slices to visually wrap around your cup:

Left: Image wrapped around top of cup, Right: Image wrapped around center of cup.

Here's example code and a Demo:

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://dl.dropboxusercontent.com/u/139992952/multple/PaperCup.png";
//pic.src='https://dl.dropboxusercontent.com/u/139992952/multple/avatars1.jpg';
pic.src='https://dl.dropboxusercontent.com/u/139992952/multple/google.png'
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);

  ctx.save();
  setClip();
  ctx.clip();

  for(var x in points){
    var y=points[x];
    ctx.drawImage(faceCanvas,  x,0,1,ch,  x,y-yy,1,ch );
    ctx.drawImage(faceCanvas,  x,0,1,ch,  x,y-yy,1,ch );
  } 
  ctx.restore();
}

function setClip(){
  ctx.beginPath();
  ctx.moveTo(t.x0,t.y0)
  ctx.bezierCurveTo(t.x1,t.y1,t.x2,t.y2,t.x3,t.y3);
  ctx.lineTo(r.x1,r.y1);
  ctx.bezierCurveTo(b.x2,b.y2,b.x1,b.y1,b.x0,b.y0);
  ctx.lineTo(t.x0,t.y0);
}

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

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.0/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>

这篇关于互动弯曲图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆