/ / Draw line animowany - szybki, animacja, remis

Rysuj linię animowaną - szybka, animacja, rysuj

Chcę mieć linię pośrodku ekranu i animować ją jak wąż

To jest animacja krok po kroku, którą chcę wykonać

wprowadź opis obrazu tutaj

Jak mogę to zrobić?

Odpowiedzi:

30 dla odpowiedzi nr 1

Możesz animować koniec suwu path na CAShapeLayernp.

weak var shapeLayer: CAShapeLayer?

@IBAction func didTapButton(_ sender: Any) {
// remove old shape layer if any

self.shapeLayer?.removeFromSuperlayer()

// create whatever path you want

let path = UIBezierPath()
path.move(to: CGPoint(x: 10, y: 50))
path.addLine(to: CGPoint(x: 200, y: 50))
path.addLine(to: CGPoint(x: 200, y: 240))

// create shape layer for that path

let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
shapeLayer.strokeColor = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1).cgColor
shapeLayer.lineWidth = 4
shapeLayer.path = path.cgPath

// animate it

view.layer.addSublayer(shapeLayer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.duration = 2
shapeLayer.add(animation, forKey: "MyAnimation")

// save shape layer

self.shapeLayer = shapeLayer
}

To daje:

obrysowana ścieżka

Oczywiście, możesz zmienić UIBezierPath do tego, co pasuje do twoich zainteresowań. Na przykład możesz mieć spacje na ścieżce. Lub nawet nie musisz mieć ścieżek prostoliniowych:

let path = UIBezierPath()
path.move(to: CGPoint(x: 10, y: 130))
path.addCurve(to: CGPoint(x: 210, y: 200), controlPoint1: CGPoint(x: 50, y: -100), controlPoint2: CGPoint(x: 100, y: 350))

Możesz także połączyć animację zarówno początku, jak i końca obrysu w a CAAnimationGroup:

// create shape layer for that path (this defines what the path looks like when the animation is done)

let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
shapeLayer.strokeColor = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1).cgColor
shapeLayer.lineWidth = 5
shapeLayer.path = path.cgPath
shapeLayer.strokeStart = 0.8

let startAnimation = CABasicAnimation(keyPath: "strokeStart")
startAnimation.fromValue = 0
startAnimation.toValue = 0.8

let endAnimation = CABasicAnimation(keyPath: "strokeEnd")
endAnimation.fromValue = 0.2
endAnimation.toValue = 1.0

let animation = CAAnimationGroup()
animation.animations = [startAnimation, endAnimation]
animation.duration = 2
shapeLayer.add(animation, forKey: "MyAnimation")

Wydajność:

wprowadź opis obrazu tutaj

CoreAnimation daje ci dużą kontrolę nad sposobem renderowania obcinanej ścieżki.


2 dla odpowiedzi nr 2

Moja potrzeba była podobna - chciałem, aby ruch kształtu śledził linię w scenie, ale miał wielką trudność w synchronizowaniu animacji w CAShapeLayer z animacją w SKScene.

Tak zakończyło się przy użyciu innego podejścia:

import SpriteKit
import PlaygroundSupport
import AVFoundation

let start = CGPoint(x: 100, y: 50)
let end = CGPoint(x: 200, y: 50)
let control = CGPoint(x: 150, y: 100);
var motion: SKAction = SKAction();

let radius: CGFloat = 20;
let bounds = CGRect(x: 0, y: 0, width: 400, height: 200)
let skview = SKView(frame: bounds)
PlaygroundPage.current.liveView = skview
PlaygroundPage.current.needsIndefiniteExecution = true

class MyScene: SKScene,AVSpeechSynthesizerDelegate {
var motionComplete = false
var redline: SKShapeNode = SKShapeNode();
var greenball: SKShapeNode = SKShapeNode();
override func sceneDidLoad() {

greenball = SKShapeNode(circleOfRadius: radius);
greenball.position = start;
greenball.fillColor = .green;

let motionpath = CGMutablePath();

motionpath.move(to: start)
motionpath.addQuadCurve(to: end, control: control)

motion = SKAction.follow(motionpath, asOffset: false, orientToPath: true,duration: 2);

let linepath = CGMutablePath();
linepath.move(to: start);
redline = SKShapeNode(path: linepath);
redline.strokeColor = .red;
redline.lineWidth = 5;

greenball.run(motion) {
self.motionComplete = true;
};

self.addChild(greenball);
self.addChild(redline);
}

override func update(_ currentTime: TimeInterval) {

if (motionComplete == false) {
let cgpath = self.redline.path as! CGMutablePath;
cgpath.addLine(to: greenball.position);
self.redline.path = cgpath;

}
}


}



let scene = MyScene(size: CGSize(width: 400, height: 200));
scene.scaleMode = SKSceneScaleMode.aspectFill
scene.size = skview.bounds.size
skview.presentScene(scene)

Wynik:

wprowadź opis obrazu tutaj


0 dla odpowiedzi № 3

Jedną z metod jest użycie UIView z kolorem tła. Spróbuj czegoś takiego.

let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
let redLine = UIView()
redline.backgroundColor = UIColor.red
redLine.frame = GCRect(x: screenWidth / 2, y: screenHeight / 2, width: 0, height: 0)

UIView.animate(withDuration: 2, animations: {
redLine.frame = GCRect(x: screenWidth / 2, y: screenHeight / 2, width: 0, height: (screenHeight / 2) - 4)
}) { finished in
redLine.frame = GCRect(x: screenWidth / 2, y: (screenHeight / 2) - 4, width: 0, height: 1)
}

Dzięki temu możesz osiągnąć dowolną ilość ruchu czerwonej linii.

Inną metodą jest narysowanie linii. Nie powiem o tym szczegółowo, ale polecam Ten artykuł.

Ostatnia rzecz... W przepełnieniu stosu doceniamy ludzi, którzy pokazują, że właściwie badali dany temat, zanim zadają pytanie. Używając google, mogłem szybko wymyślić wiele samouczków, jak robić to, czego szukasz. Postaraj się przeprowadzić badania samemu, ponieważ często samouczek będzie miał o wiele więcej szczegółów, niż jest to konieczne.