As usual, we'll look at the effect chart.
What do you think? The effect is very good, let's look at the implementation of the process and code examples.
Implementation principle
As can be seen from the diagram, the explosion point is taken by the color value of a coordinate, and then based on some animation effects to complete.
Take color value
How to take the view
color value of a certain point? Google, you can find a lot of answers. Don't say it specifically. Create a 1*1 bitmap, then render to the screen, then get RGBA. That's what I'm writing here UIView
extension
.
Extension UIView {public
func colorofpoint (point:cgpoint)-> uicolor
{
var pixel:[cunsignedchar] = [ 0,0,0,0] Let
colorspace = Cgcolorspacecreatedevicergb () let
bitmapinfo = Cgbitmapinfo (rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue) Let context
= Cgbitmapcontextcreate (&pixel, 1, 1, 8, 4, ColorSpace, Bitmapinfo.rawvalue)
CGCONTEXTTRANSLATECTM (context,-point.x,-point.y)
Self.layer.renderInContext (context!)
Let red:cgfloat = CGFloat (pixel[0])/255.0 let
green:cgfloat = CGFloat (pixel[1))/255.0 let
blue:cgfloat = CGFloat (pixel[2])/255.0 let
alpha:cgfloat = CGFloat (pixel[3))/255.0 return
uicolor (red:red, Green:green, b Lue:blue, Alpha:alpha)
}
}
The generation of particles
Here I write relatively simple, is to fix the size of each particle, according to the view of the width of the horizontal, longitudinal particles, take the color value of the point, set the background color of the particles, and then generate.
The main code is as follows:
frameDict
It's a list of coordinates I've calculated beforehand, and colorDict
it's a color table. With "I-j" as key
Class Func createexplosionpoints (Containerlayer:explosionlayer, Targetview:uiview, Animationtype: Explosionanimationtype) {let
hcount = Self.caculatepointhcount (containerLayer.targetSize.width) let
vcount = Self.caculatepointvcount (containerLayer.targetSize.height) for
I-0..
Animation effects
Each particle has an CAAnimation
animation, the data provided by the caller, flexible point.
This defines an protocol:ExplosionAnimationProtocol
animated object that can be customized to implement the Protocol, providing an animation effect.
Protocol Explosionanimationprotocol {
//particle initial position
var oldposition:cgpoint {set Get}
//particle final position
var newpos Ition:cgpoint {Set Get}
//scale
var scale:cgfloat {set Get}
//animation time long
var duration:cftimeinterval { Set get}
//animation repeat number
var repeatcount:float {set Get}
//Generate animation
func animation ()-> caanimation
//set properties after animation
func resetlayerproperty (layer:calayer)
}
view
the animation effect of the explosion to occur
This is relatively simple, is shaking down and down. The specific code will not be posted.
Let shakeanimation = Cakeyframeanimation (keypath: "position")
...
Code structure
This is the general idea. The code structure is as follows:
ExplosionLayer
is the parent container of the particles,
ExplosionPointLayer
is the particle itself.
ExplosionHelper
is an auxiliary class for calculating particle position, color value.
FallAnimation
, UpAnimation
is the realization ExplosionAnimationProtocol
of the animation, respectively, to provide to the whereabouts of the upward effect.
Problems encountered
At first I was on the edge to calculate the color value, edge to draw particles, found that will be a card will have an explosion effect out, analysis may be in the calculation of color value in the main thread, time is longer, so stuck.
Later thought put in the background thread to do, but in the main thread in the color value, the background must be done, so use the semaphore to synchronize.
Vibration effect
private Func shake () {
self.createsemaphore ()
//calculation position, color value
self.caculate ()
Let Shakeanimation = Cakeyframeanimation (keypath: "position")
shakeanimation.values = [Nsvalue.init (cgpoint: self.position), Nsvalue.init (Cgpoint:cgpointmake (self.position.x, SELF.POSITION.Y + 1)), Nsvalue.init (CGPoint: Cgpointmake (self.position.x + 1, self.position.y-1)), Nsvalue.init (Cgpoint:cgpointmake (Self.position.x-1, SELF.POSITION.Y + 1)]
shakeanimation.duration = 0.2
Shakeanimation.repeatcount =
Shakeanimation.delegate = self
shakeanimation.removedoncompletion = True
self.targetview?. Layer.addanimation (Shakeanimation, Forkey: "Shake")
}
When the view that is going to explode starts to vibrate, it starts to calculate in the background. After the motion animation is finished, wait for the calculation to complete.
Override Func Animationdidstop (anim:caanimation, finished Flag:bool) {
//wait for caculate
Dispatch_semaphore _wait (self.semaphore!, Dispatch_time_forever)
print ("Shake animation Stop")
//Begin explode
if let TargetView = self.targetview {
self.parentlayer? Addsublayer (self)
explosionhelper.createexplosionpoints (self, targetview:targetview, Animationtype: Self.animationtype)
Self.targetview? Hidden = True
}
}
In the subsequent creation of the particle, it is taken directly from the cache.
Summarize
OK, this is the entire content of iOS to achieve the explosion effect, the effect is not very cool? Interested friends quickly practice it, only their own operation can really understand, I hope this article for everyone's study or work can bring certain help.