动画“变换”时抗锯齿CALayer 上的属性?

发布于 2024-09-11 09:54:15 字数 618 浏览 10 评论 0原文

我有一个 CALayer,其中以最终大小绘制了一个圆圈。我想要为圆设置动画,使其以 1% 比例开始并以 100% 结束。现在动画不是很平滑,因为缩放时边缘会闪烁。在最终尺寸下,圆圈看起来是正确的。我想知道是否有办法在动画本身期间进行抗锯齿。

CATransform3D fromTransform = CATransform3DMakeScale(0.01, 0.01, 1.0);
CATransform3D toTransform = CATransform3DMakeScale(1.0, 1.0, 1.0);

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
theAnimation.duration = 1.5;
theAnimation.fromValue = [NSValue valueWithCATransform3D:fromTransform];
theAnimation.toValue = [NSValue valueWithCATransform3D:toTransform]; 

[myLayer addAnimation:theAnimation forKey:@"animateScale"];

I have a CALayer with a circle drawn to it at its final size. I want to animate the circle in, such that it starts at 1% scale and finishes at 100%. Right now the animation is not very smooth because the edges flicker while it's scaling. At the final size the circle looks right. I'm wondering if there's a way to have anti-aliasing during the animation itself.

CATransform3D fromTransform = CATransform3DMakeScale(0.01, 0.01, 1.0);
CATransform3D toTransform = CATransform3DMakeScale(1.0, 1.0, 1.0);

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
theAnimation.duration = 1.5;
theAnimation.fromValue = [NSValue valueWithCATransform3D:fromTransform];
theAnimation.toValue = [NSValue valueWithCATransform3D:toTransform]; 

[myLayer addAnimation:theAnimation forKey:@"animateScale"];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只是在用心讲痛 2024-09-18 09:54:15

我认为没有办法改变图层缩放的方式。但是,您可以通过以下方式获得更好的结果:将多种分辨率的圆渲染到不同大小的图层中,并同时对它们进行动画处理 - 逐渐缩放和淡入/淡出更大的图层,直到到达最终的全尺寸图层。

您还可以尝试直接逐帧绘制圆圈,而不是对图层大小进行动画处理 - 如果绘制速度足够快,您将保持良好的帧速率,并且不会出现任何缩放伪影。如果选择此路径,通常最好在专用于该动画的单独线程上执行此操作,而不是使用主线程。

在类似的情况下,我通常只是柔化绘图上的边缘 - 精心选择的阴影或光晕对于减少锯齿伪影确实有奇效,而且它比任何其他解决方案都简单得多。 (另请注意,圆圈的描边宽度随图层缩放:如果您使用全尺寸 1 像素的线宽在黑色背景上绘制白色圆圈,则在 1% 时,该线将只有 0.01 像素宽!​​)

I don't think there is a way to change the way layers scale. However, you may be able to achieve better results by rendering your circle at several resolutions into different-sized layers, and by animating them simultaneously — scaling and fading in/out progressively larger layers until you get to the final, full-sized layer.

You may also try drawing the circle directly frame by frame instead of animating the layer size — if the drawing is fast enough, you'll keep good framerates, and you'll have no scaling artifacts whatsoever. If you choose this path, it's usually best to do this on a separate thread that is dedicated to this animation rather than using the main thread.

In similar situations, I usually just end up softening the edges on my drawing — a well-chosen shadow or bloom does wonders for reducing aliasing artifacts, and it's much simpler to do than any other solution. (Note also that the stroke width of the circle scales with the layer: if you draw a white circle on black backround using a line width of 1 pixel at full size, then at 1% the line will be only 0.01 pixels wide!)

伊面 2024-09-18 09:54:15

方法:使用layer.shouldRasterize

  1. 创建一个superlayer/superview,其在所有4个方向上都大1像素
  2. superlayer上进行变换/superview
  3. 在原始layer/view上启用layer.shouldRasterize

方法:绘制到< code>UIImage

  • 将内容绘制到 UIImage
  • 确保内容周围有 1 像素的透明边框
  • 显示图像

参考:http://darknoon.com/2012/05/18/the-transparent-border-trick/

Method: Using layer.shouldRasterize

  1. Create a superlayer/superview which is 1 pixel bigger in all 4 directions
  2. Do the transform on the superlayer/superview
  3. Enable layer.shouldRasterize on the original layer/view

Method: Drawing to a UIImage

  • Draw your content to a UIImage
  • Make sure that you have a transparent border of 1 pixel around the content
  • Display the image

Reference: http://darknoon.com/2012/05/18/the-transparent-border-trick/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文