鉤形メアンダー文、もしくは、ギリシア雷文という
紋様を見たので、今日はそれを書いてみる。
紀元前の幾何模様をアニメーション描画するのは、
プログラムの練習にちょうど良さそう。
サンプルプログラムを組んでみる。

ポイント
CAShapeLayerにBasicAnimationを設定することで、
UIBezierPathのパスをアニメーションさせる。
CABasicAnimation の KeyPathに@”strokeEnd”を指定して、
from,to に 0から1を指定すればOK。

環境
今回つくったiPhoneアプリサンプルは、
XcodeのiOS6 iPhone Simulatorで動かしています。


サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    NSTimer *timer;

    float length;

    CAShapeLayer *lines;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor blackColor];

    

    [self createLines];

}

– (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [self startTimer];

}

– (void)createLines

{

    lines = [[CAShapeLayer alloc] initWithLayer:self.view.layer];

    lines.lineWidth = 8.0;

    lines.fillColor = [UIColor clearColor].CGColor;

    lines.strokeColor = [UIColor blueColor].CGColor;

    [self.view.layer addSublayer:lines];

}

– (CAShapeLayer*)createGreekKey

{

    //rate 2 : 1 : 1

    float w = 40;

    CGPoint p1 = CGPointMake(0, 0);

    CGPoint p2 = CGPointMake(2*w, 0);

    CGPoint p3 = CGPointMake(2*w, -w);

    CGPoint p4 = CGPointMake(w, -w);

    

    UIBezierPath *path = [[UIBezierPath alloc] init];

    [path moveToPoint:p1];

    [path addLineToPoint:p2];

    [path addLineToPoint:p3];

    [path addLineToPoint:p4];

    

    CAShapeLayer *sl = [[CAShapeLayer alloc] initWithLayer:self.view.layer];

    sl.path = path.CGPath;

    sl.lineWidth = 10.0;

    sl.fillColor = [UIColor clearColor].CGColor;

    sl.strokeColor = [UIColor blueColor].CGColor;

    

    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];

    pathAnimation.duration = 7.0;

    pathAnimation.fromValue = @(0.0f);

    pathAnimation.toValue = @(1.0f);

    [sl addAnimation:pathAnimation forKey:@”strokeEnd”];

    

    return sl;

}

– (void)startTimer

{

    timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];

}

– (void)tick:(NSTimer*)sender

{    

    float w = 100;

    length += 0.2;

    

    UIBezierPath *path = [[UIBezierPath alloc] init];

    [path moveToPoint:CGPointMake(10, 160)];

    [path addLineToPoint:CGPointMake(10 + length, 160)];

    [path moveToPoint:CGPointMake(10, 160 + w)];

    [path addLineToPoint:CGPointMake(10 + length, 160 + w)];

    lines.path = path.CGPath;

    

    static int counter = 400;

    if (counter == 400) {

        CAShapeLayer *sl = [self createGreekKey];

        sl.position = CGPointMake(10 + length, 160 + w);

        sl.transform = CATransform3DMakeRotation(M_PI*0.5, 0, 0, 1);

        sl.transform = CATransform3DTranslate(sl.transform, -w, 0, 0);

        [self.view.layer addSublayer:sl];

        counter = 0;

    } else if (counter == 300) {

        CAShapeLayer *sl = [self createGreekKey];

        sl.position = CGPointMake(10 + length, 160 + w);

        sl.transform = CATransform3DMakeRotation(-M_PI*0.5, 0, 0, 1);

        [self.view.layer addSublayer:sl];

    }

    

    

    counter++;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end