Skip to content

Commit 3678eef

Browse files
Added option for rectangular face
1 parent c3396e2 commit 3678eef

File tree

6 files changed

+176
-20
lines changed

6 files changed

+176
-20
lines changed

SpriteKitWatchFace WatchKit App/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<key>CFBundleShortVersionString</key>
2020
<string>1.0</string>
2121
<key>CFBundleVersion</key>
22-
<string>55</string>
22+
<string>56</string>
2323
<key>UISupportedInterfaceOrientations</key>
2424
<array>
2525
<string>UIInterfaceOrientationPortrait</string>

SpriteKitWatchFace WatchKit Extension/FaceScene.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ typedef enum : NSUInteger {
1616
ThemeNavy,
1717
ThemeTidepod,
1818
ThemeBretonnia,
19-
ThemeNoir
19+
ThemeNoir,
20+
ThemeContrast,
21+
ThemeVictoire,
22+
ThemeLiquid
2023
} Theme;
2124

2225
@interface FaceScene : SKScene <SKSceneDelegate>
@@ -30,6 +33,9 @@ typedef enum : NSUInteger {
3033
@property SKColor *markColor;
3134
@property SKColor *textColor;
3235

36+
@property BOOL useProgrammaticLayout;
37+
@property BOOL useRoundFace;
38+
3339
@end
3440

3541

SpriteKitWatchFace WatchKit Extension/FaceScene.m

Lines changed: 165 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,54 @@
1212
#define NSFont UIFont
1313
#endif
1414

15-
@implementation FaceScene
16-
17-
BOOL vectorDisplay = YES;
15+
CGFloat workingRadiusForFaceOfSizeWithAngle(CGSize faceSize, CGFloat angle)
16+
{
17+
CGFloat faceHeight = faceSize.height;
18+
CGFloat faceWidth = faceSize.width;
19+
20+
CGFloat workingRadius = 0;
21+
22+
double vx = cos(angle);
23+
double vy = sin(angle);
24+
25+
double x1 = 0;
26+
double y1 = 0;
27+
double x2 = faceHeight;
28+
double y2 = faceWidth;
29+
double px = faceHeight/2;
30+
double py = faceWidth/2;
31+
32+
double t[4];
33+
double smallestT = 1000;
34+
35+
t[0]=(x1-px)/vx;
36+
t[1]=(x2-px)/vx;
37+
t[2]=(y1-py)/vy;
38+
t[3]=(y2-py)/vy;
39+
40+
for (int m = 0; m < 4; m++)
41+
{
42+
double currentT = t[m];
43+
44+
if (currentT > 0 && currentT < smallestT)
45+
smallestT = currentT;
46+
}
47+
48+
workingRadius = smallestT;
49+
50+
return workingRadius;
51+
}
1852

19-
// 184 x 224
53+
@implementation FaceScene
2054

2155
- (instancetype)initWithCoder:(NSCoder *)coder
2256
{
2357
self = [super initWithCoder:coder];
2458
if (self) {
2559

2660
self.theme = ThemeHermesPink;
61+
self.useProgrammaticLayout = YES;
62+
self.useRoundFace = YES;
2763

2864
[self setupColors];
2965
[self setupScene];
@@ -33,21 +69,21 @@ - (instancetype)initWithCoder:(NSCoder *)coder
3369
return self;
3470
}
3571

36-
-(void)setupTickmarks
72+
-(void)setupTickmarksForRoundFace
3773
{
3874
CGFloat margin = 4.0;
3975
CGFloat labelMargin = 26.0;
4076

4177
SKNode *faceMarkings = [SKNode node];
4278

4379
/* Hardcoded for 44mm Apple Watch */
44-
CGFloat faceWidth = 184;
45-
CGFloat faceHeight = 224;
46-
80+
81+
CGSize faceSize = (CGSize){184, 224};
82+
4783
for (int i = 0; i < 12; i++)
4884
{
4985
CGFloat angle = -(2*M_PI)/12.0 * i;
50-
CGFloat workingRadius = faceWidth/2;
86+
CGFloat workingRadius = faceSize.width/2;
5187
CGFloat longTickHeight = workingRadius/15;
5288

5389
SKSpriteNode *tick = [SKSpriteNode spriteNodeWithColor:self.markColor size:CGSizeMake(2, longTickHeight)];
@@ -73,7 +109,7 @@ -(void)setupTickmarks
73109
for (int i = 0; i < 60; i++)
74110
{
75111
CGFloat angle = - (2*M_PI)/60.0 * i;
76-
CGFloat workingRadius = faceWidth/2;
112+
CGFloat workingRadius = faceSize.width/2;
77113
CGFloat shortTickHeight = workingRadius/20;
78114
SKSpriteNode *tick = [SKSpriteNode spriteNodeWithColor:self.markColor size:CGSizeMake(1, shortTickHeight)];
79115

@@ -87,10 +123,81 @@ -(void)setupTickmarks
87123
}
88124

89125
[self addChild:faceMarkings];
126+
}
127+
128+
-(void)setupTickmarksForRectangularFace
129+
{
130+
CGFloat margin = 5.0;
131+
CGFloat labelYMargin = 30.0;
132+
CGFloat labelXMargin = 24.0;
133+
134+
CGSize faceSize = (CGSize){184, 224};
90135

91-
SKNode *face = [self childNodeWithName:@"Face"];
92-
SKSpriteNode *numbersLayer = (SKSpriteNode *)[face childNodeWithName:@"Numbers"];
93-
numbersLayer.alpha = 0;
136+
/* Major */
137+
for (int i = 0; i < 12; i++)
138+
{
139+
CGFloat angle = -(2*M_PI)/12.0 * i;
140+
CGFloat workingRadius = workingRadiusForFaceOfSizeWithAngle(faceSize, angle);
141+
CGFloat longTickHeight = workingRadius/10.0;
142+
143+
SKSpriteNode *tick = [SKSpriteNode spriteNodeWithColor:self.markColor size:CGSizeMake(2, longTickHeight)];
144+
145+
tick.position = CGPointZero;
146+
tick.anchorPoint = CGPointMake(0.5, (workingRadius-margin)/longTickHeight);
147+
tick.zRotation = angle;
148+
149+
tick.zPosition = 0;
150+
151+
[self addChild:tick];
152+
}
153+
154+
/* Minor */
155+
for (int i = 0; i < 60; i++)
156+
{
157+
158+
CGFloat angle = - (2*M_PI)/60.0 * i;
159+
CGFloat workingRadius = workingRadiusForFaceOfSizeWithAngle(faceSize, angle);
160+
CGFloat shortTickHeight = workingRadius/20;
161+
SKSpriteNode *tick = [SKSpriteNode spriteNodeWithColor:self.markColor size:CGSizeMake(1, shortTickHeight)];
162+
163+
tick.position = CGPointZero;
164+
tick.anchorPoint = CGPointMake(0.5, (workingRadius-margin)/shortTickHeight);
165+
tick.zRotation = angle;
166+
167+
tick.zPosition = 0;
168+
if (i % 5 != 0)
169+
[self addChild:tick];
170+
}
171+
172+
/* Numerals */
173+
for (int i = 1; i <= 12; i++)
174+
{
175+
CGFloat fontSize = 25;
176+
177+
SKSpriteNode *labelNode = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(fontSize, fontSize)];
178+
labelNode.anchorPoint = CGPointMake(0.5,0.5);
179+
180+
if (i == 1 || i == 11 || i == 12)
181+
labelNode.position = CGPointMake(labelXMargin-faceSize.width/2 + ((i+1)%3) * (faceSize.width-labelXMargin*2)/3.0 + (faceSize.width-labelXMargin*2)/6.0, faceSize.height/2-labelYMargin);
182+
else if (i == 5 || i == 6 || i == 7)
183+
labelNode.position = CGPointMake(labelXMargin-faceSize.width/2 + (2-((i+1)%3)) * (faceSize.width-labelXMargin*2)/3.0 + (faceSize.width-labelXMargin*2)/6.0, -faceSize.height/2+labelYMargin);
184+
else if (i == 2 || i == 3 || i == 4)
185+
labelNode.position = CGPointMake(faceSize.height/2-fontSize-labelXMargin, -(faceSize.width-labelXMargin*2)/2 + (2-((i+1)%3)) * (faceSize.width-labelXMargin*2)/3.0 + (faceSize.width-labelYMargin*2)/6.0);
186+
else if (i == 8 || i == 9 || i == 10)
187+
labelNode.position = CGPointMake(-faceSize.height/2+fontSize+labelXMargin, -(faceSize.width-labelXMargin*2)/2 + ((i+1)%3) * (faceSize.width-labelXMargin*2)/3.0 + (faceSize.width-labelYMargin*2)/6.0);
188+
189+
[self addChild:labelNode];
190+
191+
NSDictionary *attribs = @{NSFontAttributeName : [NSFont fontWithName:@"Futura-Medium" size:fontSize], NSForegroundColorAttributeName : self.textColor};
192+
193+
NSAttributedString *labelText = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%i", i] attributes:attribs];
194+
195+
SKLabelNode *numberLabel = [SKLabelNode labelNodeWithAttributedText:labelText];
196+
197+
numberLabel.position = CGPointMake(0, -9);
198+
199+
[labelNode addChild:numberLabel];
200+
}
94201
}
95202

96203
-(void)setupColors
@@ -163,6 +270,36 @@ -(void)setupColors
163270
textColor = [SKColor whiteColor];
164271
break;
165272
}
273+
case ThemeContrast:
274+
{
275+
lightColor = [SKColor whiteColor];
276+
darkColor = [SKColor whiteColor];
277+
inlayColor = [SKColor whiteColor];
278+
markColor = [SKColor blackColor];
279+
handColor = [SKColor blackColor];
280+
textColor = [SKColor blackColor];
281+
break;
282+
}
283+
case ThemeVictoire:
284+
{
285+
lightColor = [SKColor colorWithRed:0.937 green:0.925 blue:0.871 alpha:1.000];
286+
darkColor = [SKColor colorWithRed:0.737 green:0.725 blue:0.671 alpha:1.000];
287+
inlayColor = lightColor;
288+
markColor = [SKColor colorWithRed:0.337 green:0.325 blue:0.271 alpha:1.000];
289+
handColor = [SKColor blackColor];
290+
textColor = [SKColor colorWithRed:0.137 green:0.125 blue:0.071 alpha:1.000];
291+
break;
292+
}
293+
case ThemeLiquid:
294+
{
295+
lightColor = [SKColor colorWithWhite:0.2 alpha:1.0];
296+
darkColor = lightColor;
297+
inlayColor = [SKColor colorWithWhite:0.3 alpha:1.0];
298+
markColor = [SKColor colorWithWhite:0.5 alpha:1.0];
299+
handColor = [SKColor whiteColor];
300+
textColor = [SKColor whiteColor];
301+
break;
302+
}
166303

167304
default:
168305
break;
@@ -213,8 +350,21 @@ -(void)setupScene
213350
minuteHandInlay.color = self.inlayColor;
214351
minuteHandInlay.colorBlendFactor = 1.0;
215352

216-
if (vectorDisplay)
217-
[self setupTickmarks];
353+
if (self.useProgrammaticLayout)
354+
{
355+
SKNode *face = [self childNodeWithName:@"Face"];
356+
SKSpriteNode *numbersLayer = (SKSpriteNode *)[face childNodeWithName:@"Numbers"];
357+
numbersLayer.alpha = 0;
358+
359+
if (self.useRoundFace)
360+
{
361+
[self setupTickmarksForRoundFace];
362+
}
363+
else
364+
{
365+
[self setupTickmarksForRectangularFace];
366+
}
367+
}
218368
}
219369

220370
- (void)update:(NSTimeInterval)currentTime forScene:(SKScene *)scene

SpriteKitWatchFace WatchKit Extension/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<key>CFBundleShortVersionString</key>
2020
<string>1.0</string>
2121
<key>CFBundleVersion</key>
22-
<string>55</string>
22+
<string>56</string>
2323
<key>NSExtension</key>
2424
<dict>
2525
<key>NSExtensionAttributes</key>

SpriteKitWatchFace WatchKit Extension/InterfaceController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ @implementation InterfaceController
2828
- (void)awakeWithContext:(id)context {
2929
[super awakeWithContext:context];
3030

31-
FaceScene *scene = (SKScene *)[FaceScene nodeWithFileNamed:@"FaceScene"];
31+
FaceScene *scene = [FaceScene nodeWithFileNamed:@"FaceScene"];
3232

3333
[self.scene presentScene:scene];
3434
}

SpriteKitWatchFace/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>1.0</string>
1919
<key>CFBundleVersion</key>
20-
<string>55</string>
20+
<string>56</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>UILaunchStoryboardName</key>

0 commit comments

Comments
 (0)