CAShapeLayer使用CGPathRef来绘制它的东西。所以我有一条星路,我想要一个半径约为15个单位的平滑投影。可能在一些新的iPhone OS版本中有一些不错的功能,但我需要自己做一个旧版本的3.0(大多数人仍然使用)。
我试图做一些非常令人讨厌的事情: 我创建了一个for循环并按顺序创建了15个这样的路径,逐步变换它们以变大。然后将它们分配给新创建的CAShapeLayer,并在每次迭代时稍微降低它的alpha值。不仅这个缩放在数学上是不正确的并且很糟糕(它应该相对于轮廓发生!),阴影不是圆形的并且看起来非常难看。这就是为什么漂亮的柔和阴影具有半径。
在15个单位的阴影后,星星的尖端不应该显得非常尖锐。它们应该像奶油一样柔软。但是在我丑陋的解决方案中,它们就像恒星本身一样竖琴,因为我所做的只是将恒星缩放15次并将其降低15次。难看。
我想知道大家伙是怎么做到的?如果你有一个任意路径,并且该路径必须抛出阴影,那么算法如何工作呢?可能必须将路径扩展30次,相对于远离填充部分的轮廓的切线逐点扩展,并且只需0.5个单位即可进行良好的混合。
在重新发明轮子之前,也许有人有一个方便的例子或链接?
答案 0 :(得分:3)
阴影是一个半透明的灰度蒙版,对象的形状被模糊和偏移。
CGContextSetShadowWithColor
和CGContextSetShadow
是如何在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
编辑:谢谢Miser。
答案 1 :(得分:1)
所以我在Photoshop中画了一个小阴影(画笔工具,尺寸7,不透明度33%,颜色#3b3b3b)。它几乎不可见:
然后我用Javascript编写了一个小HTML,试着看看它的样子(绝对不是理想的技术: - ):
<!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>
结果如下:
可能有很多优化空间,当然你不会以这种方式使用javascript真正渲染它...也许你可以找到一种方法如何在iPhone上有效地渲染它?如果是,请告诉我!
可能的改进: