2009-11-07 3 views
4

다음과 같은 코드는 수직 미러 이미지와 투명한 배경 그라데이션 그라데이션을 결합하려고합니다. 이 두 가지 효과를 결합하면 실패합니다. 두 작업을 수행하기 위해 캔버스를 가져 오는 대신 캔바스 위에 PNG 그래디언트를 오버레이해야합니까? 매우 설득력 그라디언트 오버레이를 제공하지 않는 두 번째 캔버스를 사용HTML Canvas로 반사 된 이미지를 만드시겠습니까?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 
    <style type="text/css"> 
     body { 
      background-color: #eee; 
      text-align: center; 
      padding-top: 150px; 
     } 
    </style> 
    <script type="text/javascript"> 
     var img = new Image(); 
     img.onload = function() {    
      var ctx = document.getElementById("output").getContext("2d"); 
      // reflect image 
      ctx.translate(0, 75); 
      ctx.scale(1, -1); 
      ctx.drawImage(img, 0, 0, 75, 75); 

      // add gradient 
      var grad = ctx.createLinearGradient(0, 0, 0, 20); 
      grad.addColorStop(0, 'transparent'); 
      grad.addColorStop(1, '#eeeeee'); 

      ctx.fillStyle = grad; 
      ctx.fillRect(0, 0, 75, 20); 
     }; 

     img.src = "test.jpg"; 
    </script> 
</head> 
<body> 
    <div><img src="test.jpg" height="75" width="75" /></div> 
    <canvas id="output" width="75" height="20"></canvas> 
</body> 
</html> 
+0

에 대한 링크입니다 투명 시도하기 전에 중지합니다. 그래디언트 만 적용하거나 반사 이미지 만 적용 할 수 있지만 둘 다 적용 할 수는 없습니다. –

+0

브라우저에서 캔버스가 지원되는 경우 일부 CSS3도 지원 될 가능성이 있습니다 ... CSS3 만 사용하여 반사 (iTunes 스타일)를 만들 수 있습니다 (자바 스크립트 필요 없음). http://s3.amazonaws.com/nettuts/704_cssReflections/index.html – Greg

답변

3

2 개의 캔버스 요소가 필요하지 않습니다. 아래 코드는 Linux의 FireFox 3.0에서 작동합니다.

캔버스 크기를 변경하여 테스트하는 동안 캔버스 크기를 200x100 픽셀로 변경했습니다. 필요에 따라 다시 크기를 조정해야합니다 (75x20). 테스트 목적으로 그라디언트로 이미지의 절반을 볼 수 있도록 오버레이를 100x100 픽셀로 만들었습니다.

<canvas id="output" width="200" height="100" style="border:1px solid black;"></canvas> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 
<style type="text/css"> 
    body { 
      background-color: #eee; 
      text-align: center; 
      padding-top: 150px; 
    } 
</style> 
<script type="text/javascript"> 
    var img = new Image(); 
    img.onload = function() { 
      var ctx = document.getElementById("output").getContext("2d"); 
      // reflect image 
      ctx.translate(0, 100); 
      ctx.scale(1, -1); 
      ctx.drawImage(img, 0, 0, 200, 100); 

      // add gradient 
      var grad = ctx.createLinearGradient(0, 0, 0, 100); 
      grad.addColorStop(0.3, 'rgb(255,255,255)'); 
      grad.addColorStop(0.7, 'rgba(255,255,255,0)'); 

      ctx.fillStyle = grad; 
      ctx.translate(0,0); 
      ctx.rect(0, 0, 100, 100); 
      ctx.fill(); 
    }; 

    img.src = "img/avatarW3.png"; 
</script> 

편집

이 중 일부를 설명하기 :

을 당신이 기본적으로 그라데이션에 알파 속성이 누락되었다 생각합니다.

grad.addColorStop(0.7, 'rgba(255,255,255,0)'); 

네 번째 매개 변수는 alpha입니다. 또한 캔버스를 거꾸로 뒤집 으면서 그라디언트가 현재 거꾸로 그려집니다 (따라서 두 번째 색상 정지 점은 투명도를 가지지 만 블록은 윗면에 투명 함). 당신이 그것을 필요로 당신이 당신의 투명 그라데이션 블록을 그릴 수

ctx.save(); 
ctx.translate(0, 100); 
ctx.scale(1, -1); 
ctx.drawImage(img, 0, 0, 200, 100); 
ctx.restore(); 

그리고 지금 : 당신이 제대로 일을하고 싶었다면에

, 당신은해야합니다.

또한 나를 위해 ctx.fillRect() 명령이 작동하지 않았습니다. ctx.rect() 및 ctx.fill()을 사용해야했습니다.

희망이 도움이됩니다.

+0

대단히 감사합니다. Mac의 Safari에서도 이것을 테스트 했으므로 Chrome에서도 작동 할 것입니다. 그라디언트 매개 변수를 변경하여 리플렉션을 좀 더 매끄럽게 보이게 만들었습니다. grad.addColorStop (0, 'rgba (238,238,238,0.8)'); grad.addColorStop (1, 'rgb (238,238,238)'); –

0

. 적절한 결과를 얻으려면 그라디언트 PNG를 사용해야 할 수도 있습니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 
    <style type="text/css"> 
     body { 
      background-color: #eee; 
      padding-top: 150px; 
     } 

     canvas { 
      float: left; 
     } 

     canvas#grad { 
      margin-left: -75px; 
     } 
    </style> 
    <script type="text/javascript"> 
     var img = new Image(); 
     img.src = "test.jpg"; 

     img.onload = function() { 
      var reflect = document.getElementById("reflect").getContext("2d"); 
      // reflect image 
      reflect.translate(0, 75); 
      reflect.scale(1, -1); 
      reflect.drawImage(img, 0, 0, 75, 75); 

      // add gradient 
      var overlay = document.getElementById("grad").getContext("2d"); 
      var grad = overlay.createLinearGradient(0, 0, 0, 15); 
      grad.addColorStop(0, 'transparent'); 
      grad.addColorStop(1, '#eeeeee'); 

      overlay.fillStyle = grad; 
      overlay.fillRect(0, 0, 75, 15); 
     }; 
    </script> 
</head> 
<body> 
    <div> 
     <div><img src="test.jpg" height="75" width="75" /></div> 
     <canvas id="reflect" width="75" height="15"></canvas> 
     <canvas id="grad" width="75" height="15"></canvas> 
    </div> 
</body> 
</html> 
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 
<style type="text/css"> 
    body { 
      background-color: #FFF; 
      text-align: center; 
      padding-top: 100px; 
    } 
</style> 
<script type="text/javascript"> 
    var img = new Image(); 
    img.onload = function() { 
     var c = document.getElementById("output"); 
     var ctx = c.getContext("2d"); 

     /* Maximum Canvas/Image Size 
      i.e supposing image size 640x480 or greater than 399px 
     */ 
     var max = 400; 

     /* Resizing Image/Drawing */ 
     var r = img.width/img.height; 
     if(r>1) 
      ctx.drawImage(img , 0 , 0 , r*max , max); 
     else 
      ctx.drawImage(img , 0 , 0 , max , max/r); 
     ctx.save(); 

     /* Clearing extra spaces */ 
     ctx.clearRect(0, max, c.width , c.height); 

     /* Creating reflection */ 
     ctx.translate(0, max); 
     ctx.scale(1, -1); 
     if(r>1) 
      ctx.drawImage(img , 0 , -max , r*max , max); 
     else 
      ctx.drawImage(img , 0 , max/2 , max , max/2 , 0 , -max/2 , max , max/2); 
     ctx.restore(); 

     /* Adding gradiant */ 
     ctx.globalCompositeOperation = 'destination-out'; 
     var grad = ctx.createLinearGradient(0, Math.floor(c.height-(max/2)) , 0, c.height); 
     grad.addColorStop(1, 'rgba(255,255,255,1.0)'); 
     grad.addColorStop(0, 'rgba(255,255,255,0.8)'); 
     ctx.fillStyle = grad; 
     ctx.fillRect(0, Math.floor(c.height-(max/2)) , max, (max/2)); 
    }; 

    img.src = "a.jpg"; 
</script> 

</head> 
<body> 
<canvas id="output" width="400" height="600" ></canvas> 
</body> 
</html> 
+0

이 접근법은 당신에게 투명한 반영을 제공합니다 (이것은 좋은 것입니다). – Philippe

+0

Fiddle : https://jsfiddle.net/gwov2784/1/ – Josiah

0

당신은 반사를 만들 때 전체 이미지를 다시 그릴 필요가 없습니다. 원본 반사는 단순히 이미지의 아래쪽 부분을 보여줍니다. 이렇게하면 더 나은 성능을 제공하는 이미지의 더 작은 부분을 다시 그릴 수 있으며 이미지의 하단 부분을 숨기려면 선형 그라디언트를 만들 필요가 없습니다 (그리지 않기 때문에).

REFLECTION_HEIGHT 및 불투명도로 재생하여 원하는 결과를 얻을 수 있습니다. 여기

var thumbWidth = 250; 
var REFLECTION_HEIGHT = 50; 
var c = document.getElementById("output"); 
var ctx = c.getContext("2d"); 
var x = 1; 
var y = 1; 

//draw the original image 
ctx.drawImage(img, x, y, thumbWidth, thumbWidth); 
ctx.save(); 
//translate to a point from where we want to redraw the new image 
ctx.translate(0, y + thumbWidth + REFLECTION_HEIGHT + 10); 
ctx.scale(1, -1); 
ctx.globalAlpha = 0.25; 

//redraw only bottom part of the image 
//g.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); 
ctx.drawImage(img, 0, img.height - REFLECTION_HEIGHT, img.width, REFLECTION_HEIGHT, x, y, thumbWidth, REFLECTION_HEIGHT); 

내가 '블랙'과 '화이트'색상이 테스트 fiddle

관련 문제