2014-12-03 4 views
2

샘플 종이컵에 이미지와 텍스트를 감싸고 싶습니다. 캔버스에 이미지를 업로드 할 때 위치가 항상 고정되어있는 종이컵의 배경 이미지로 이미지를 감싸고 싶습니다. html5 캔버스 도구에 Fabric JS를 사용하고 있습니다. 여기에 내 코드가 있지만 그것은 단지 1 픽셀의 이미지를 보여줍니다. 이미지를 클릭하여 끌어다 놓을 때도 깜박입니다.종이컵에 이미지 감싸기 (배경 이미지)

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 캔버스에 새로운 오전, 도와주세요.

http://jsfiddle.net/kNEaX/217/

+0

몇 가지 초기 오류가 있습니다. CSS를 사용하여 캔버스 크기를 설정하는 경우 (너비와 높이를 직접 사용하는 경우에만 해당), 대상 너비 1 픽셀을 사용하여 이미지를 draw합니다 (이미지의 너비가 1 픽셀 인 이유 설명) 캔버스를 직접 사용하면 패브릭 내부를 업데이트하지 않습니다 (대신 패브릭 메서드를 사용해야합니다). 이렇게하면 패브릭과 상호 작용할 때 캔버스가 비어있게됩니다. – K3N

+0

drawImage의 코드를 도와 주시겠습니까? 이런 식으로하고 싶습니다 - http://stackoverflow.com/questions/26403646/fabric-js-html-5-image-curving-options – user3752437

답변

6

이 같은 사용자 이미지를 그릴 수 있습니다

enter image description here

을이 종이 컵에 :

enter image description here

이 같은 으로 결과 :

enter image description here

이 예제 코드를 사용 :

당신의 요구에 맞게이 예제를 수정합니다. 프로젝트에 행운을 빌어 요!

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

추가 참고 : 효과는 기본 캔버스에서 사용할 수있는 context.drawImage 방법을 필요로하기 때문에 위의 예는 끝났다는 HTML 캔버스 요소

에 미치는 영향을 만듭니다 요소.

네이티브 캔버스를 사용하여 효과를 만든 후에는 쉽게 FabricJS 이미지 객체를 생성 할 이미지 소스로 기본 캔버스 (fabric.Image 이미지 소스 같은 HTML 캔버스을 받아) 것을 사용할 수 있습니다

// 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); 
+0

감사 마크. 이것은 많은 도움이 될 것입니다. 그러나 직물 방법을 대신 사용하는 것이 가능합니까?끌어서 놓기, 크기 조정 및 회전은이 방법에서 허용되지 않습니다. – user3752437

+0

html 캔버스를 사용하여 효과를 만든 후에는 해당 html 캔버스를 이미지 소스로 사용하여 fabric.Image를 만들 수 있습니다. 내 대답은 그것을 할 예제 코드를 추가했습니다. 건배! – markE

+0

굉장합니다. 나는이 일을 할 것 같아요 :) – user3752437