如何在CALayer上进行转换? [英] How to do transforms on a CALayer?

查看:123
本文介绍了如何在CALayer上进行转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在写这个问题之前,我已经






  • 要在 CALayer 上进行转换,将图层的转换属性设置为 CATransform3D 类型。例如,要翻译图层,您可以执行以下操作:

      myLayer.transform = CATransform3DMakeTranslation(20,30,0 )

    单词 Make 用于用于创建初始转换的名称:CATransform3D 生成转换。应用的后续转换省略 Make 。例如,请参阅此轮换后跟翻译:

     让rotation = CATransform3DMakeRotation(CGFloat.pi * 30.0 / 180.0,20 ,20,0)
    myLayer.transform = CATransform3DTranslate(轮换,20,30,0)



    <现在我们已经有了如何进行变换的基础,让我们看看如何做每个变换的一些例子。首先,我将展示如何设置项目,以防你想要玩它。



    设置



    对于以下示例,我设置了一个单视图应用程序,并在故事板中添加了一个浅蓝色背景的 UIView 。我使用以下代码将视图连接到视图控制器:

      import UIKit 

    class ViewController :UIViewController {

    var myLayer = CATextLayer()
    @IBOutlet weak var myView:UIView!

    覆盖func viewDidLoad(){
    super.viewDidLoad()

    //设置子图层
    addSubLayer()

    //执行转换
    transformExample()
    }

    func addSubLayer(){
    myLayer.frame = CGRect(x:0,y:0,width :100,身高:40)
    myLayer.backgroundColor = UIColor.blue.cgColor
    myLayer.string =你好
    myView.layer.addSublayer(myLayer)
    }

    // ********用以下示例替换此函数********

    func transformExample(){

    //在此处添加转换代码...


    }

    }



    在iOS中,坐标系的原点位于左上方,所以如果我们想将图层向右移动90点,向下移动50点,我们就可以以下:

      myLayer.transform = CATransform3DMakeTranslation(90,50,0)

    注释




    • 请记住,您可以将其粘贴到上面项目代码中的transformExample()方法。

    • 由于我们这里只处理两个维度, tz 设置为 0

    • 上图中的红线从原始位置的中心到新位置的中心。这是因为变换是相对于锚点完成的,默认情况下锚点位于图层的中心。



    缩放



    缩放变换拉伸或取消图层。基本语法是

      CATransform3DMakeScale(sx:CGFloat,sy:CGFloat,sz:CGFloat)

    其中 sx sy sz 分别是缩放(乘)x,y和z坐标的数字。



    示例





    如果我们想要宽度的一半和高度的三倍,我们将执行以下操作

      myLayer.transform = CATransform3DMakeScale(0.5,3.0,1.0)

    备注




    • 由于我们只是在两个维度上工作,我们只需将z坐标乘以1.0即可使它们不受影响。

    • 上图中的红点代表锚点。注意如何相对于锚点完成缩放。也就是说,一切都朝向或远离锚点拉伸。



    旋转



    旋转变换围绕锚点旋转图层(默认情况下为图层的中心)。基本语法是

      CATransform3DMakeRotation(角度:CGFloat,x:CGFloat,y:CGFloat,z:CGFloat)

    其中 angle 是图层应以弧度表示的角度旋转和 x y z 是轴关于哪个旋转。将轴设置为0可取消围绕该特定轴的旋转。



    示例





    如果我们想要将图层顺时针旋转30度,我们会执行以下操作:

     让度= 30.0 
    让radians = CGFloat(度* Double.pi / 180)
    myLayer.transform = CATransform3DMakeRotation(弧度) ,0.0,0.0,1.0)

    注释




    • 由于我们在两个维度上工作,我们只希望xy平面围绕z轴旋转。因此,我们将 x y 设置为 0.0 并设置 z 1.0

    • 这会以顺时针方向旋转图层。我们可以通过将 z 设置为 -1.0 来逆时针旋转。

    • 红点显示锚点的位置。旋转是在锚点周围完成的。



    多次转换



    In为了组合多个变换我们可以像这样使用连接

      CATransform3DConcat(a:CATransform3D,b:CATransform3D)

    但是,我们将一个接一个地做。第一个转换将在其名称中使用 Make 。以下转换不会使用生成,但它们会将之前的转换作为参数。



    示例





    这次我们结合所有三个先前的变换。

     让度= 30.0 
    让radians = CGFloat(度* Double.pi / 180)

    //翻译
    var transform = CATransform3DMakeTranslation(90,50,0)

    //旋转
    transform = CATransform3DRotate(transform,radians ,0.0,0.0,1.0)

    //缩放
    变换= CATransform3DScale(变换,0.5,3.0,1.0)

    //应用变换
    myLayer.transform = transform

    注释




    • 转换完成的顺序。

    • 一切都是关于锚点(红点)完成的。



    A Note关于锚点和位置



    我们在不改变锚点的情况下完成了上述所有变换。有时候有必要改变它,就像你想要围绕中心的其他点旋转一样。但是,这可能有点棘手。



    锚点和位置都在同一个地方。锚点表示为图层坐标系的单位(默认为 0.5,0.5 ),位置在超层坐标系中表示。它们可以像这样设置

      myLayer.anchorPoint = CGPoint(x:0.0,y:1.0)
    myLayer。 position = CGPoint(x:50,y:50)

    如果你只设置锚点而不改变位置,然后框架改变,使位置在正确的位置。或者更确切地说,基于新的锚点和旧位置重新计算框架。这通常会产生意外结果。以下两篇文章对此进行了很好的讨论。





    参见




    Before writing this question, I've

    However, I'm still having trouble understanding how to do basic transforms on a layer. Finding explanations and simple examples for translate, rotate and scale has been difficult.

    Today I finally decided to sit down, make a test project, and figure them out. My answer is below.

    Notes:

    • I only do Swift, but if someone else wants to add the Objective-C code, be my guest.
    • At this point I am only concerned with understanding 2D transforms.

    解决方案

    Basics

    There are a number of different transforms you can do on a layer, but the basic ones are

    • translate (move)
    • scale
    • rotate

    To do transforms on a CALayer, you set the layer's transform property to a CATransform3D type. For example, to translate a layer, you would do something like this:

    myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
    

    The word Make is used in the name for creating the initial transform: CATransform3DMakeTranslation. Subsequent transforms that are applied omit the Make. See, for example, this rotation followed by a translation:

    let rotation = CATransform3DMakeRotation(CGFloat.pi * 30.0 / 180.0, 20, 20, 0)
    myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
    

    Now that we have the basis of how to make a transform, let's look at some examples of how to do each one. First, though, I'll show how I set up the project in case you want to play around with it, too.

    Setup

    For the following examples I set up a Single View Application and added a UIView with a light blue background to the storyboard. I hooked up the view to the view controller with the following code:

    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 ...
    
    
        }
    
    } 
    

    There are many different kinds of CALayer, but I chose to use CATextLayer so that the transforms will be more clear visually.

    Translate

    The translation transform moves the layer. The basic syntax is

    CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
    

    where tx is the change in the x coordinates, ty is the change in y, and tz is the change in z.

    Example

    In iOS the origin of the coordinate system is in the top left, so if we wanted to move the layer 90 points to the right and 50 points down, we would do the following:

    myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
    

    Notes

    • Remember that you can paste this into the transformExample() method in the project code above.
    • Since we are just going to deal with two dimensions here, tz is set to 0.
    • The red line in the image above goes from the center of the original location to the center of the new location. That's because transforms are done in relation to the anchor point and the anchor point by default is in the center of the layer.

    Scale

    The scale transform stretches or squishes the layer. The basic syntax is

    CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
    

    where sx, sy, and sz are the numbers by which to scale (multiply) the x, y, and z coordinates respectively.

    Example

    If we wanted to half the width and triple the height, we would do the following

    myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
    

    Notes

    • Since we are only working in two dimensions, we just multiply the z coordinates by 1.0 to leave them unaffected.
    • The red dot in the image above represents the anchor point. Notice how the scaling is done in relation to the anchor point. That is, everything is either stretched toward or away from the anchor point.

    Rotate

    The rotation transform rotates the layer around the anchor point (the center of the layer by default). The basic syntax is

    CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
    

    where angle is the angle in radians that the layer should be rotated and x, y, and z are the axes about which to rotate. Setting an axis to 0 cancels a rotation around that particular axis.

    Example

    If we wanted to rotate a layer clockwise 30 degrees, we would do the following:

    let degrees = 30.0
    let radians = CGFloat(degrees * Double.pi / 180)
    myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
    

    Notes

    • Since we are working in two dimentions, we only want the xy plane to be rotated around the z axis. Thus we set x and y to 0.0 and set z to 1.0.
    • This rotated the layer in a clockwise direction. We could have rotated counterclockwise by setting z to -1.0.
    • The red dot shows where the anchor point is. The rotation is done around the anchor point.

    Multiple transforms

    In order to combine multiple transforms we could use concatination like this

    CATransform3DConcat(a: CATransform3D, b: CATransform3D)
    

    However, we will just do one after another. The first transform will use the Make in its name. The following transforms will not use Make, but they will take the previous transform as a parameter.

    Example

    This time we combine all three of the previous transforms.

    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
    

    Notes

    • The order that the transforms are done in matters.
    • Everything was done in relation to the anchor point (red dot).

    A Note about Anchor Point and Position

    We did all our transforms above without changing the anchor point. Sometimes it is necessary to change it, though, like if you want to rotate around some other point besides the center. However, this can be a little tricky.

    The anchor point and position are both at the same place. The anchor point is expressed as a unit of the layer's coordinate system (default is 0.5, 0.5) and the position is expressed in the superlayer's coordinate system. They can be set like this

    myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
    myLayer.position = CGPoint(x: 50, y: 50)
    

    If you only set the anchor point without changing the position, then the frame changes so that the position will be in the right spot. Or more precisely, the frame is recalculated based on the new anchor point and old position. This usually gives unexpected results. The following two articles have an excellent discussion of this.

    See also

    这篇关于如何在CALayer上进行转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆