2010-05-28 58 views
6

CAShapeLayer使用CGPathRef繪製它的東西。所以我有一條星星路徑,我想要一個半徑約15個單位的平滑陰影。在一些新的iPhone操作系統版本中可能有一些很好的功能,但我需要自己做一個老版本的3.0(大多數人仍在使用)。如何在iOS中繪製下拉陰影

我試圖做一些真正令人討厭的東西: 我創建了一個for循環,並按順序創建了15個這樣的路徑,逐步將它們變換爲更大。然後將它們分配給一個新創建的CAShapeLayer,並在每次迭代時減少它的alpha值。不僅如此,這種縮放在數學上不正確並且很糟糕(它應該發生在相對於輪廓的位置!),陰影不是圓形的,看起來非常醜陋。這就是爲什麼好的軟陰影有一個半徑。

明星的祕訣不應該出現的15個單位的陰影尺寸後完全尖銳。它們應該像奶油一樣柔軟。但在我醜陋的解決方案中,他們就像明星本身一樣豎琴,因爲我所做的只是將星星縮放15次,並將其減少15次。醜陋。

我不知道大傢伙是怎麼做的?如果你有一條任意路徑,那條路徑必須拋出一個陰影,算法如何工作?可能路徑必須被擴展30倍,相對於離開填充部分的輪廓的切線逐點增加,並且僅需0.5個單位就可以具有良好的混合。

我在重新發明輪子,也許有人有一個方便的例子或鏈接?

回答

3

影子是模糊和偏移的對象的形狀的半透明灰度掩模。

CGContextSetShadowWithColorCGContextSetShadow是這是如何在iPhone上完成的。您設置陰影然後繪製一些東西,並且還應用陰影。

CAShapeLayer沒有簡單的選項來應用陰影。在繪製形狀之前,您必須創建自定義視圖或圖層並設置陰影。

我還沒有嘗試過,但下面可能的工作:

@interface ShadowShapeLayer : CAShapeLayer 
@end 

@implementation ShadowShapeLayer 
-(void) drawInContext:(CGContextRef)context { 
    CGContextSaveGState(context); 
    CGContextSetShadow(context , CGSizeMake(5 , 5) , 15); 
    [super drawInContext:context]; 
    CGContextRestoreGState(context); 
} 
@end 

編輯:感謝吝嗇鬼。

+0

對於CGContextSetShadow,第二個參數應該是CGSize,如CGSizeMake(5,5) – 2011-05-06 20:29:15

1

我問自己同樣的問題。我根本不是這方面的專家,但我有以下想法:物理上,繪圖的一個點應該是圓形(或橢圓形),半透明陰影。因此,包含多個點的整個圖形應該會導致很多這種圓形陰影的組合。

所以我在Photoshop塗一點影子(畫筆工具,大小7,不透明度33%,顏色#3b3b3b)。這是幾乎不可見:

alt text

然後我寫了一個小的HTML使用Javascript只是嘗試,看看它是什麼樣子(絕對不是理想的技術:-):

<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
    <title>Title</title> 

    <script type="text/javascript" language="javascript"> 

     function pageload() { 
      var drawingContainerElem = document.getElementById("drawing-container"); 
      var shadowContainerElem = document.getElementById("shadow-container"); 

      this.drawDot = function(x, y) { 
       var imgElem = document.createElement("img"); 
       imgElem.style.left = x + "px"; 
       imgElem.style.top = y + "px"; 
       imgElem.src = "blue-dot.png"; 
       drawingContainerElem.appendChild(imgElem); 
      } 
      this.drawShadow = function(x, y) { 
       var imgElem = document.createElement("img"); 
       imgElem.style.left = x + "px"; 
       imgElem.style.top = y + "px"; 
       imgElem.src = "soft-shadow.png"; 
       shadowContainerElem.appendChild(imgElem); 
      } 
      this.drawDotAndShadow = function(x, y) { 
       drawShadow(x - 5, y - 1); 
       drawDot(x, y); 
      } 

      for (var x = 50; x < 70; x ++) { 
       for (var y = 50; y < 58; y ++) { 
        drawDotAndShadow(x, y); 
       } 
      } 
      for (var x = 0; x < 15; x ++) { 
       for (var y = 0; y < x; y ++) { 
        drawDotAndShadow(69 + 15 - x, 54 + y); 
        drawDotAndShadow(69 + 15 - x, 54 - y); 
       } 
      } 

     } 

    </script> 

    <style type="text/css"> 
     #drawing-container { 
      position: absolute; 
      left: 2em; 
      top: 2em; 
      width: 400px; 
      height: 400px; 
      z-index: 2; 
     } 
     #shadow-container { 
      position: absolute; 
      left: 2em; 
      top: 2em; 
      width: 400px; 
      height: 400px; 
      z-index: 1; 
     } 

     #drawing-container img { 
      position: absolute; 
     } 
     #shadow-container img { 
      position: absolute; 
     } 
    </style> 

</head> 
<body onload="javascript:pageload()"> 
    <div id="drawing-container"></div> 
    <div id="shadow-container"></div> 
</body> 
</html> 

這是結果:

alt text

也許,有很多的優化空間,當然你不會再盟友使用這種方式使用JavaScript ...也許你可以找到一種方法如何在iPhone上有效地渲染這個?如果是,請告訴我!

可能的改進:

  • 使陰影圓圈較暗(更不透明度)的中心,其餘的打火機(較小的不透明度),以實現芯的陰影。
  • 縮放陰影:使其變小一點,以達到深度效果。