ハーマングリッド (Hermann Grid) 視覚トリックを作ってみる。
(XcodeのiOS6 iPhone Simulatorで動かしています。)
概要
黒の上に、格子状に道を通していくと、
交差点に、無いはずの黒っぽい物がちらちらする
という視覚トリックを作ってみます。
交差点を丸くすると、顕著にチラチラがでてくるので、
ボタンで交差点を丸くできるようにしてみます。
ポイント
画面の下の方に、コントロール用のボタンを2つ用意
左のボタン:左右になぞると格子の大きさを変更
右のボタン:交差点を丸い形にする
黒のUIViewを灰色の背景の上に配置することで、
格子を表示する。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
float edge;
float border;
BOOL roundCorner;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
[self createGrid];
[self createUI];
}
– (void)createGrid
{
edge = 20;
border = 5;
[self updateGrid];
}
– (void)createUI
{
// grid size changer
UIView *panel = [[UIView alloc] initWithFrame:CGRectMake(20, 380, 200, 60)];
panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:panel];
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(0, 60)];
[path addLineToPoint:CGPointMake(200, 60)];
[path addLineToPoint:CGPointMake(200, 0)];
CAShapeLayer *s = [[CAShapeLayer alloc] initWithLayer:panel];
s.fillColor = [UIColor blackColor].CGColor;
s.path = path.CGPath;
[panel.layer addSublayer:s];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[panel addGestureRecognizer:pan];
// connector shape
UIView *btn = [[UIView alloc] initWithFrame:CGRectMake(240, 380, 60, 60)];
btn.backgroundColor = [UIColor whiteColor];
[self.view addSubview:btn];
UIBezierPath *path2 = [[UIBezierPath alloc] init];
[path2 moveToPoint:CGPointMake(0, 30)];
[path2 addLineToPoint:CGPointMake(60, 30)];
[path2 moveToPoint:CGPointMake(30, 0)];
[path2 addLineToPoint:CGPointMake(30, 60)];
[path2 moveToPoint:CGPointMake(30, 30)];
[path2 addArcWithCenter:CGPointMake(30, 30) radius:5 startAngle:0 endAngle:M_PI*2 clockwise:NO];
CAShapeLayer *s2 = [[CAShapeLayer alloc] initWithLayer:btn];
s2.fillColor = [UIColor clearColor].CGColor;
s2.strokeColor = [UIColor blackColor].CGColor;
s2.lineWidth = 5.0;
s2.path = path2.CGPath;
[btn.layer addSublayer:s2];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
[btn addGestureRecognizer:tap];
}
– (void)pan:(UIGestureRecognizer*)gr
{
CGPoint p = [gr locationInView:self.view];
if (p.x < 20) {
p.x = 20;
}
if (p.x > 220) {
p.x = 220;
}
edge = p.x / 4.0;
border = edge / 4.0;
[self updateGrid];
}
– (void)updateGrid
{
for (UIView *v in self.view.subviews) {
if (v.tag == 1) {
[v removeFromSuperview];
}
}
CGSize size = self.view.bounds.size;
for (int i=0; i<size.width/(edge+border); i++) {
for (int j=0; j<(size.height)/(edge+border); j++) {
float x = i * (edge + border);
float y = 300 – j * (edge + border);
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(x, y, edge, edge)];
v.backgroundColor = [UIColor blackColor];
v.tag = 1;
[self.view insertSubview:v atIndex:0];
if (roundCorner) {
UIView *round = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2*border, 2*border)];
round.center = CGPointMake(x – border*0.5, y-border*0.5);
round.layer.cornerRadius = border;
round.backgroundColor = [UIColor whiteColor];
round.tag = 1;
[self.view addSubview:round];
}
}
}
}
– (void)tap:(UIGestureRecognizer*)gr
{
roundCorner = !roundCorner;
[self updateGrid];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end