简体   繁体   English

在CALayer上设置“转换”属性动画时进行抗锯齿处理?

[英]Anti-aliasing while animating “transform” property on CALayer?

I have a CALayer with a circle drawn to it at its final size. 我有一个CALayer,在其最终尺寸上画了一个圆。 I want to animate the circle in, such that it starts at 1% scale and finishes at 100%. 我想在圆上设置动画,使其以1%的比例开始,以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"];

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!) (还请注意,圆的笔触宽度与图层成比例:如果在黑色背景上使用全尺寸的1像素的线宽在白色背景上绘制白色圆圈,则在1%时,线的宽度仅为0.01像素!)

Method: Using layer.shouldRasterize 方法:使用layer.shouldRasterize

  1. Create a superlayer / superview which is 1 pixel bigger in all 4 directions 创建一个在所有4个方向上大1像素的superlayer / superlayer superview
  2. Do the transform on the superlayer / superview superlayer / superlayer superview上进行变换
  3. Enable layer.shouldRasterize on the original layer / view 在原始layer / view上启用layer.shouldRasterize

Method: Drawing to a UIImage 方法:绘制到UIImage

  • Draw your content to a UIImage 将内容绘制到UIImage
  • Make sure that you have a transparent border of 1 pixel around the content 确保内容周围有1像素的透明边框
  • Display the image 显示图像

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM