互动弯曲图像 [英] Interactive bend image
问题描述
我想用这种方式在网络浏览器中转换图片
- >
>
更精确地说,它应该是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屋!