我正试图建立一个CAEmitterLayer制作五彩纸屑的效果,我遇到了两个问题:
birthRate我的单元格设置为非零值以启动动画时,我会在屏幕上随机放置一系列单元格,这些单元格会正常生成动画,然后发射器继续正常发射.emitterCells我在屏幕上绘制内容时,无论何时触摸屏幕,发射器都会emitterCells(看似)随机抽取(看似)随机时间量的随机位置.发射器中没有任何内容与任何触摸事件相关联(即我不是故意在触摸事件上绘制任何东西),但该图层位于具有多个嵌入视图的视图中.我触摸得越多,出现的细胞就越多.这是我设置发射器的代码,然后启动和停止它(一旦我调用了stop函数,然后点击屏幕就会停止创建新的随机元素):
- (void)setupConfetti
{
self.confettiLayer = [CAEmitterLayer layer];
[self.view.layer addSublayer:self.confettiLayer];
[self.view.layer setNeedsDisplay];
self.confettiLayer.emitterPosition = CGPointMake(1024.0/2,-50.0);
self.confettiLayer.emitterSize = CGSizeMake(1000.0, 10.0);
self.confettiLayer.emitterShape = kCAEmitterLayerLine;
self.confettiLayer.renderMode =kCAEmitterLayerUnordered;
CAEmitterCell *confetti = [CAEmitterCell emitterCell];
confetti1.contents = (id)[[UIImage imageNamed:@"confetti.png"] CGImage];
confetti.emissionLongitude = M_PI;
confetti.emissionLatitude = 0;
confetti.lifetime = 5;
confetti.birthRate = 0.0;
confetti.velocity = 125;
confetti.velocityRange = 50;
confetti.yAcceleration = 50;
confetti.spin = 0.0;
confetti.spinRange = 10;
confetti.name = @"confetti1";
self.confettiLayer.emitterCells = [NSArray arrayWithObjects:confetti, nil]; …Run Code Online (Sandbox Code Playgroud) 奇怪的问题我似乎无法解决iOS 7只在哪里,CAEmitterLayer当出生率最初设置为非零值时,将错误地在屏幕上产生粒子.就像它计算未来该层的状态一样.
// Create black image particle
CGRect rect = CGRectMake(0, 0, 20, 20);
UIGraphicsBeginImageContext(rect.size);
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Create cell
CAEmitterCell *cell = [CAEmitterCell emitterCell];
cell.contents = (__bridge id)img.CGImage;
cell.birthRate = 100.0;
cell.lifetime = 10.0;
cell.velocity = 100.0;
// Create emitter with particles emitting from a line on the
// bottom of the screen
CAEmitterLayer *emitter = [CAEmitterLayer layer];
emitter.emitterShape = kCAEmitterLayerLine;
emitter.emitterSize = CGSizeMake(self.view.bounds.size.width,0);
emitter.emitterPosition = CGPointMake(self.view.bounds.size.width/2,
self.view.bounds.size.height);
emitter.emitterCells = …Run Code Online (Sandbox Code Playgroud) 我想分享我self.layer.shouldRasterize = YES;在UIViews上使用旗帜的经验.
我有一个UIView类层次结构已经self.layer.shouldRasterize变成ON,以提高性能滚动(所有的人都静子视图是比设备的屏幕大).
今天在其中一个子类中我用来CAEmitterLayer产生漂亮的粒子效果.
该业绩是真穷,虽然粒子的数目确实很低(50个).
这个问题的原因是什么?
我正在玩CAEmitterLayer,我现在面临一些问题:(
我需要一个短的粒子效果 - 比如击中或爆炸 - 例如在一个地方(所以我在这个地方有小UIView).我该怎么办?
1,我有一个想法 - 使用它的粒子创建emitterLayer并将lifeTime设置为0.当我需要它时,我将lifeTime设置为1,一段时间后我可以将其设置为0. - 但是它没有做任何事情:(
2,第二个想法是每次需要时创建[CAEmitterLayer图层]并将其添加为图层子图层.但是我在想,当我重复十次时会发生什么......我有10个子层,一个有效,9个"死"?如何停止一般发射?我有一段时间后执行performSelector将生命周期设置为0,其他选择器的间隔时间更长,以删除.FromSuperlayer ...但它不是那么漂亮我想拥有它:(还有另一种"正确"方式吗?
我认为太多的子层与我的另一个问题有关...我想只发射一个粒子.当我这样做时,它有效.但有时候它发出三颗粒子,有时两粒......这让我很生气.当我不停止发射器时,它每次给出正确数量的粒子......
所以问题......
如何在短时间内发射粒子.如何使用它们 - 比如停止,从父层移除,...如何发出准确数量的粒子
编辑:
emitter = [CAEmitterLayer layer];
emitter.emitterPosition = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);
emitter.emitterMode = kCAEmitterLayerPoints;
emitter.emitterShape = kCAEmitterLayerPoint;
emitter.renderMode = kCAEmitterLayerOldestFirst;
emitter.lifetime = 0;
particle = [CAEmitterCell emitterCell];
[particle setName:@"hit"];
particle.birthRate = 1;
particle.emissionLongitude = 3*M_PI_2;//270deg
particle.lifetime = 0.75;
particle.lifetimeRange = 0;
particle.velocity = 110;
particle.velocityRange = 20;
particle.emissionRange = M_PI_2;//PI/2 = 90degrees
particle.yAcceleration = 200;
particle.contents = (id) [[UIImage imageNamed:@"50"] CGImage];
particle.scale = 1.0; …Run Code Online (Sandbox Code Playgroud) 我的目标是制作类似爆炸的动画,其中许多粒子在短时间内发射.我的问题是CAEmitterLayer在开始发射时会添加"未来"粒子,使其看起来像动画已经运行了一段时间.
如何禁用或解决此问题?当我增加birthRate时,我只希望粒子从emitterPosition开始出现,而不是沿CAEmitterCell的预计生命周期中的所有点开始.任何帮助表示赞赏.
#import "EmitterView.h"
@interface EmitterView ()
@property CAEmitterLayer* emitter;
@end
@implementation EmitterView
- (void) awakeFromNib {
[super awakeFromNib];
self.emitter = (CAEmitterLayer*)self.layer;
CAEmitterCell* snowflake = [CAEmitterCell emitterCell];
snowflake.contents = (id)[[UIImage imageNamed: @"snowflake"] CGImage];
snowflake.lifetime = 3;
snowflake.birthRate = 1;
snowflake.velocity = 50;
snowflake.emissionRange = 3.1415;
self.emitter.birthRate = 0;
self.emitter.emitterCells = [NSArray arrayWithObject: snowflake];
self.emitter.emitterPosition = CGPointMake(100, 100);
self.emitter.emitterSize = CGSizeMake(0, 0);
self.emitter.emitterShape = kCAEmitterLayerPoint;
}
+ (Class) layerClass {
return [CAEmitterLayer class];
}
- (void) burst {
self.emitter.birthRate = 10; …Run Code Online (Sandbox Code Playgroud) 到目前为止,我的问题很难解决.
我应该和我的同事一起开发一个Android应用程序,它在iOS上做同样的事情.
在开发结束时,我们应该提供两个做同样事情并且看起来很相似的应用程序(可以放心,没有像iOS指南那样强制在Android上使用,反之亦然),这样体验就是一样的,身临其境.
提供的顶级功能之一是一个漂亮的白色空圆圈动画,在圆圈内发出雪状粒子.圆圈可以通过滚动或简单的弹跳/滑动动画来移动.
因此,想象一个带有白色边框的圆圈和白色颗粒离开那个白色的膜.所有这些粒子都被吸引到中心,它们的速度基础是变化的(但没有加速!).假设最快的粒子在到达中心之前"死亡".可以通过设置终身和速度轻松设置的东西.
我的伙伴,像我这样的大三学生,正在使用iOS'CAEmitterLayer,她在一两天内获得的结果非常华丽,非常接近我们应该达到的目标.
在我身边,我真的很挣扎.像她一样,我对任何动画和UI/UX都没有任何经验.在Android上寻找粒子生成器/发射器时,我偶然发现了这个漂亮的库:https://github.com/plattysoft/Leonids,它似乎可以提供我想要的东西.
但是我使用这个库有一些未解决的问题:
正如我所说,我的iOS同事解决了这些问题.即使是动人的部分:我们正在和我们的经理谈话,他们告诉我们"如果圆圈移动怎么办?" 她立刻在我们面前试了一下.我被吹走了......
她告诉我,我应该寻找一种方法将我的粒子包含在一个容器内(有意义^^),并且我的圆形视图应该用图层剪裁,这样粒子就不会离开圆圈,特别是如果整个东西都在移动.
这是我通过前面提到的Android库实现的目标:
height和width)和奇怪的原因,我的圈画上面说基于平方的观点.我希望我能找到另一个图书馆,但如果当前的图书馆正在运作,为什么不呢?试试我的运气^^
谢谢您的帮助 !
目前,我的粒子突然以完整的形状和形式出现在屏幕上.我想要的是细胞要么以0.0不透明度开始,要么动画达到完全不透明度,要么以0.0比例开始,动画最高为1.0比例.我在网上找不到如何做到这一点.
我想创建一个只在用户触摸屏幕时发出的粒子效果,但是一旦设置为非零值,我就无法更改CAEmitterCell birthRate属性.
我有一个UIView的子类,它按照我想要的方式设置我的CAEmitterLayer和我的CAEmitterCell.我在该类上定义了两个属性:
@property (strong, nonatomic) CAEmitterLayer *emitterLayer;
@property (strong, nonatomic) CAEmitterCell *emitterCell;
Run Code Online (Sandbox Code Playgroud)
然后,在我的视图控制器中,我正在跟踪触摸,设置emitterLayer的位置和emitterCell的出生率:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint tappedPt = [touch locationInView:touch.view];
NSLog(@"began x:%f y:%f",tappedPt.x, tappedPt.y);
emitterView.emitterCell.birthRate = 42;
emitterView.emitterLayer.emitterPosition = tappedPt;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint tappedPt = [touch locationInView:touch.view];
NSLog(@"moved x:%f y:%f",tappedPt.x, tappedPt.y);
emitterView.emitterLayer.emitterPosition = tappedPt;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"ending %f", emitterView.emitterCell.birthRate);
emitterView.emitterCell.birthRate = 0.00;
NSLog(@"ended %f", emitterView.emitterCell.birthRate);
}
Run Code Online (Sandbox Code Playgroud)
日志报告emitterView.emitterCell.birthRate更改:
began x:402.000000 …Run Code Online (Sandbox Code Playgroud) 我正在使用CAEmitterLayer和CAEmitterCell实例创建粒子动画.动画没有问题,但我想让它们慢慢淡出.我正在使用下面的代码但是粒子突然消失,没有淡出动画.
NSString *animationPath = [NSString stringWithFormat:@"emitterCells.%@.birthRate", cell.name];
CABasicAnimation *birthRateAnimation = [CABasicAnimation animationWithKeyPath:animationPath];
birthRateAnimation.fromValue = [NSNumber numberWithFloat:30.0];
birthRateAnimation.toValue = [NSNumber numberWithFloat:0.0];
birthRateAnimation.removedOnCompletion = NO;
birthRateAnimation.duration = 10.0;
[emitterLayer addAnimation:birthRateAnimation forKey:@"birthRate"];
Run Code Online (Sandbox Code Playgroud)
该代码在for循环中运行,用于五个不同的发射器单元.
你在这段代码中发现了错误吗?
谢谢
我有一个CAEmitterLayerbezier路径的动画(封闭形式,就像'8',四个控制点中的一个)CAKeyframeAnimation.现在我想通过沿着(但不一定在路径上)触摸手指的滑动来控制动画.这怎么可能,这甚至可能吗?
caemitterlayer ×10
ios ×8
objective-c ×3
cocoa-touch ×2
android ×1
animation ×1
calayer ×1
ios5 ×1
ios7 ×1
path ×1
performance ×1
uiview ×1