简体   繁体   中英

Change animation speed on slider

If you scroll to the bottom you'll see a slider for changing the animation speed. What I'd like to do is create an animation speed on the slider based around the replicatorLayer animation2() part. Is this possible?

var player:AVAudioPlayer = AVAudioPlayer()
var meditationState: MeditationState?
var replicatorLayer = CAReplicatorLayer()
var dot = CALayer()

func updateTimer(){

    seconds += 1
    timerclock.text = "\(seconds)"
}

// Animation starts running

func animation2() {

    // A layer that creates a specified number of copies of its sublayers (the source layer), each copy potentially having geometric, temporal, and color transformations applied to it.
    replicatorLayer = CAReplicatorLayer()

    // The layer’s bounds rectangle. Animatable.
    replicatorLayer.bounds = CGRect(x: 0.0, y: 0.0, width: 300.0, height: 300.0)

    // The radius to use when drawing rounded corners for the layer’s background. Animatable.
    replicatorLayer.cornerRadius = 10.0

    // The background color of the receiver. Animatable.
    replicatorLayer.backgroundColor = UIColor(white: 0.0, alpha: 0.0).cgColor

    // The layer’s position in its superlayer’s coordinate space. Animatable.
    replicatorLayer.position = view.center

    // calling this method creates an array for that property and adds the specified layer to it.
    view.layer.addSublayer(replicatorLayer)


    // connectng the animation to the content

    // An object that manages image-based content and allows you to perform animations on that content
     dot = CALayer()

    // The layer’s bounds rectangle. Animatable.
    dot.bounds = CGRect(x: 0.0, y: 0.0, width: 12.0, height: 12.0)

    //The layer’s position in its superlayer’s coordinate space. Animatable.
    dot.position = CGPoint(x: 150.0, y: 40.0)

    //The background color of the receiver. Animatable.
    dot.backgroundColor = UIColor(white: 0.2, alpha: 1.0).cgColor

    // The color of the layer’s border. Animatable.
    dot.borderColor = UIColor(white: 1.0, alpha: 1.0).cgColor

    // The width of the layer’s border. Animatable.
    dot.borderWidth = 1.0

    //The radius to use when drawing rounded corners for the layer’s background. Animatable.
    dot.cornerRadius = 5.0


    //Appends the layer to the layer’s list of sublayers.
    replicatorLayer.addSublayer(dot)

    // number of copies of layer is instanceCount

    let nrDots: Int = 1000

    //The number of copies to create, including the source layers.
    replicatorLayer.instanceCount = nrDots

    // The basic type for floating-point scalar values in Core Graphics and related frameworks.
    let angle = CGFloat(2*M_PI) / CGFloat(nrDots)

    // The transform matrix applied to the previous instance to produce the current instance. Animatable.
    replicatorLayer.instanceTransform = CATransform3DMakeRotation(angle, 0.0, 0.0, 1.0)

    // Type used to represent elapsed time in seconds.
    let duration: CFTimeInterval = 10.0

    // animation capabilities for a layer property.

    // An object that provides basic, single-keyframe animation capabilities for a layer property.
    let shrink = CABasicAnimation(keyPath: "transform.scale")

    // Defines the value the receiver uses to start interpolation.
    shrink.fromValue = 1.0

    // Defines the value the receiver uses to end interpolation.
    shrink.toValue = 0.1

    // Specifies the basic duration of the animation, in seconds.
    shrink.duration = duration

    // Determines the number of times the animation will repeat.
    shrink.repeatCount = Float.infinity

    // Add the specified animation object to the layer’s render tree.
    dot.add(shrink, forKey: "shrink")

    // Specifies the delay, in seconds, between replicated copies. Animatable.
    replicatorLayer.instanceDelay = duration/Double(nrDots)

    // The transform applied to the layer’s contents. Animatable.
    dot.transform = CATransform3DMakeScale(0.01, 0.01, 0.01)
}

// connecting the breathe in label

@IBOutlet weak var label: UILabel!

// instant delay

@IBOutlet weak var instantDelay: UIButton!
@IBAction func delayBtn(_ sender: Any) {

    dot.removeAnimation(forKey: "shrink")
    timer1.invalidate()
    seconds = 0
    timer2.invalidate()
    timerclock.text = "\(seconds)"
    time = 0
    timerLabel.text = "Breathe in"
    timerisOn = false
    pauseBtn.isHidden = true
    playBtn.isHidden = false

    label.isHidden = true
    replicatorLayer.isHidden = true
    instantDelay.isHidden = true
    instantDelay1.isHidden = false
    slider.isHidden = false
}

// Delay 1

@IBOutlet weak var instantDelay1: UIButton!
@IBAction func delayBtn1(_ sender: Any) {


    instantDelay1.isHidden = true
    instantDelay.isHidden = false
    label.isHidden = false
    slider.isHidden = true
}


//Slider for changing animation speed

@IBOutlet weak var slider: UISlider!
@IBAction func slider(_ sender: Any) {

}

CALayer conforms to the CAMediaTiming protocol, which means it has a speed property. When you change the speed property of a layer it alters the "frame of reference" of all child layers. (Speed == 1.0 is normal speed, speed 2.0 is double-speed, and speed 0.5 is half-speed.)

You can change the speed property of the parent layer that contains your replicator layer and it should alter the speed of your animation. Try making a valueChanged IBAction attached to your slider that changes the speed property of your animation's super layer to values ranging from 0.5 to 2.0.

CAAnimation objects also conform to the CAMediaTiming protocol, so you can change the speed on individual animations as well.

EDIT:

It's not complicated. You could make your slider IBAction method something like this:

@IBAction func slider(_ sender: UISlider) {
  view.layer.speed = sender.value
}  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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