Jak zrobić transformacje na kalejdoskopie?
Zanim napiszę to pytanie, mam
- miał doświadczenie z Affinish transforms for views
- przeczytaj transformuje dokumentację W Quartz 2D Programming Guide
- Zobacz ten szczegółowy samouczek Calayera
- Pobierz i uruchom projekt LayerPlayer z Github
Nadal jednak mam problem ze zrozumieniem, jak wykonać podstawowe transformacje na warstwie . Znajdowanie wyjaśnień i proste przykłady tłumaczenia, obracania i skalowania były trudne.
Dzisiaj w końcu postanowiłem usiąść, zrobić projekt testowy i je rozgryźć. Moja odpowiedź jest poniżej.
Uwagi:
- robię tylko Swift, ale jeśli ktoś chce dodać kod Objective-C, proszę bardzo.
- w tym momencie zajmuję się tylko zrozumieniem przekształceń 2D.
1 answers
Podstawy
Istnieje wiele różnych przekształceń, które można wykonać na warstwie, ale podstawowe to
- translate (move)
- skala
- rotate
Aby wykonać transformacje na CALayer
, należy ustawić właściwość transform
warstwy na typ CATransform3D
. Na przykład, aby przetłumaczyć warstwę, wykonałbyś coś takiego:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
Słowo Make
jest używane w nazwie do tworzenia przekształcenia początkowego: CATransform3DMake Tłumaczenie. Kolejne transformaty, które są stosowane, pomijają Make
. Zobacz, na przykład, ten obrót, po którym następuje tłumaczenie:
let rotation = CATransform3DMakeRotation(CGFloat.pi * 30.0 / 180.0, 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
Teraz, gdy mamy podstawy, jak dokonać transformacji, spójrzmy na kilka przykładów, jak zrobić każdą z nich. Najpierw jednak pokażę, jak skonfigurowałem projekt, gdybyś też chciał się nim bawić.
Setup
W poniższych przykładach skonfigurowałem aplikację Single View i dodałem UIView
z jasnoniebieskie tło do storyboardu. PodĹ 'Ä ... czyĹ' em widok do kontrolera widoku nastÄ ™ pujÄ ... cym kodem:
import UIKit
class ViewController: UIViewController {
var myLayer = CATextLayer()
@IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// setup the sublayer
addSubLayer()
// do the transform
transformExample()
}
func addSubLayer() {
myLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
myLayer.backgroundColor = UIColor.blue.cgColor
myLayer.string = "Hello"
myView.layer.addSublayer(myLayer)
}
//******** Replace this function with the examples below ********
func transformExample() {
// add transform code here ...
}
}
Istnieje wiele różnych rodzajów CALayer
, ale zdecydowałem się użyć CATextLayer
, aby transformaty były bardziej wyraźne wizualnie.
Tłumacz
Transformata translacji przesuwa warstwę. Podstawowa składnia to
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
Gdzie tx
jest zmianą współrzędnych x, ty
jest zmianą w y, a tz
jest zmianą w z.
Przykład
W systemie iOS początek układu współrzędnych znajduje się w lewym górnym rogu, więc gdybyśmy chcieli przesunąć warstwę o 90 punktów w prawo i o 50 punktów w dół, wykonalibyśmy następujące czynności:]}myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
Uwagi
- pamiętaj, że możesz to wkleić do metody
transformExample()
w powyższym kodzie projektu. - ponieważ mamy tu do czynienia z dwoma wymiarami,
tz
jest ustawione na0
. - czerwona linia w powyższy obraz przechodzi od środka oryginalnej lokalizacji do środka nowej lokalizacji. Dzieje się tak dlatego, że transformacje są wykonywane w odniesieniu do punktu kontrolnego, a punkt kontrolny domyślnie znajduje się w środku warstwy.
Skala
Transformata skali rozciąga lub zgniata warstwę. Podstawowa składnia to
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
Gdzie sx
, sy
, i sz
są liczbami, przez które można skalować (mnożyć) odpowiednio współrzędne x, y i Z.
Przykład
Jeśli chcemy połowę szerokości i potroić wysokość, wykonamy następujące czynności]}myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
Uwagi
- ponieważ pracujemy tylko w dwóch wymiarach, po prostu pomnożymy współrzędne z przez 1.0, aby pozostawić je bez zmian.
- czerwona kropka na powyższym obrazku reprezentuje punkt kontrolny. Zwróć uwagę, jak skalowanie odbywa się w odniesieniu do punktu kontrolnego. Oznacza to, że wszystko jest albo rozciągnięte w kierunku lub z dala od punktu kotwiczenia.
Rotate
Transformata obrotu obraca warstwę wokół punktu kontrolnego (domyślnie środek warstwy). Podstawowa składnia to
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
Gdzie angle
jest kątem w radianach, że warstwa powinna być obrócona i x
, y
, i z
są osiami, wokół których można się obracać. Ustawienie osi na 0 anuluje obrót wokół tej konkretnej oś.
Przykład
Jeśli chcemy obrócić warstwę zgodnie z ruchem wskazówek zegara o 30 stopni, wykonamy następujące czynności:]}let degrees = 30.0
let radians = CGFloat(degrees * Double.pi / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
Uwagi
- ponieważ pracujemy w dwóch wymiarach, chcemy tylko, aby płaszczyzna xy była obracana wokół osi Z. Tak więc ustawiamy
x
iy
na0.0
i ustawiamyz
na1.0
.
To obróciło warstwę w kierunku zgodnym z ruchem wskazówek zegara. Możemy obracać się w kierunku przeciwnym do ruchu wskazówek zegara, ustawiając - czerwona kropka pokazuje, gdzie znajduje się punkt kontrolny. Obrót odbywa się wokół punktu kontrolnego.
z
na -1.0
.
Wiele przekształceń
W celu połączenia wielu przekształceń możemy użyć konkatinacji w ten sposób
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
[46]}jednakże, będziemy po prostu robić jeden po drugim. Pierwsza transformacja użyje Make
w swojej nazwie. Poniższe transformacje nie będą używać Make
, ale przyjmą poprzednią transformację jako parametr.
Przykład
Tym razem połączymy wszystkie trzy poprzednie transformacje.
let degrees = 30.0
let radians = CGFloat(degrees * Double.pi / 180)
// translate
var transform = CATransform3DMakeTranslation(90, 50, 0)
// rotate
transform = CATransform3DRotate(transform, radians, 0.0, 0.0, 1.0)
// scale
transform = CATransform3DScale(transform, 0.5, 3.0, 1.0)
// apply the transforms
myLayer.transform = transform
Uwagi
- kolejność dokonywania przekształceń w sprawach.
- wszystko zostało zrobione w odniesieniu do punktu kontrolnego (czerwona kropka).
Uwaga o punkcie kotwiczenia i pozycji
Wykonaliśmy wszystkie nasze transformacje powyżej bez zmiany punktu kotwiczenia. Czasami konieczna jest zmiana to, chociaż, jeśli chcesz obrócić wokół innego punktu poza centrum. Jednak może to być trochę trudne.
Punkt kontrolny i pozycja znajdują się w tym samym miejscu. Punkt kontrolny jest wyrażony jako jednostka układu współrzędnych warstwy (domyślnie 0.5, 0.5
), a pozycja jest wyrażona w układzie współrzędnych warstwy. Można je ustawić tak:
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
Jeśli ustawisz tylko punkt kontrolny bez zmiany pozycji, to ramka zmieni się tak, że pozycja będzie we właściwym miejscu. A dokładniej, ramka jest przeliczana na podstawie nowego punktu kotwiczenia i starej pozycji. Zwykle daje to nieoczekiwane rezultaty. Poniższe dwa artykuły mają doskonałą dyskusję na ten temat.
Zobacz też
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:41