From 6b1f8a6342badfb540169eb5554be089957246e4 Mon Sep 17 00:00:00 2001 From: LEO Yoon-Tsaw Date: Wed, 29 Mar 2023 10:44:55 -0400 Subject: [PATCH] Add shadows to rings, make it more 3D --- Chinese Time.xcodeproj/project.pbxproj | 13 ++-- .../xcschemes/ChineseTime.xcscheme | 2 +- ChineseTime/WatchFace.swift | 61 ++++++++++++++----- layout.txt | 37 ----------- 4 files changed, 54 insertions(+), 59 deletions(-) delete mode 100644 layout.txt diff --git a/Chinese Time.xcodeproj/project.pbxproj b/Chinese Time.xcodeproj/project.pbxproj index 73ded87..64f6256 100644 --- a/Chinese Time.xcodeproj/project.pbxproj +++ b/Chinese Time.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 53; objects = { /* Begin PBXBuildFile section */ @@ -112,8 +112,9 @@ D2E4E0DA26F7C73E002F3716 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1250; - LastUpgradeCheck = 1420; + LastUpgradeCheck = 1430; TargetAttributes = { D2E4E0E126F7C73E002F3716 = { CreatedOnToolsVersion = 12.5.1; @@ -310,7 +311,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 48; + CURRENT_PROJECT_VERSION = 50; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 28HU5A7B46; ENABLE_HARDENED_RUNTIME = YES; @@ -322,7 +323,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - MARKETING_VERSION = 3.2; + MARKETING_VERSION = 3.3; PRODUCT_BUNDLE_IDENTIFIER = "Chinese-Time"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -338,7 +339,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 48; + CURRENT_PROJECT_VERSION = 50; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 28HU5A7B46; ENABLE_HARDENED_RUNTIME = YES; @@ -350,7 +351,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - MARKETING_VERSION = 3.2; + MARKETING_VERSION = 3.3; PRODUCT_BUNDLE_IDENTIFIER = "Chinese-Time"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/Chinese Time.xcodeproj/xcshareddata/xcschemes/ChineseTime.xcscheme b/Chinese Time.xcodeproj/xcshareddata/xcschemes/ChineseTime.xcscheme index 7f57004..ca4d346 100644 --- a/Chinese Time.xcodeproj/xcshareddata/xcschemes/ChineseTime.xcscheme +++ b/Chinese Time.xcodeproj/xcshareddata/xcschemes/ChineseTime.xcscheme @@ -1,6 +1,6 @@ RoundedRect { + return RoundedRect(rect: _boundBox, nodePos: _nodePos, ankorPos: _ankorPos) + } + private func drawPath(vertex: Array) -> CGMutablePath { let path = CGMutablePath() var previousPoint = vertex[vertex.count-1] @@ -567,7 +571,7 @@ class WatchFaceView: NSView { return shape } - func drawRing(ringPath: CGPath, roundedRect: RoundedRect, gradient: WatchLayout.Gradient, ticks: ChineseCalendar.Ticks, startingAngle: CGFloat, fontSize: CGFloat, minorLineWidth: CGFloat, majorLineWidth: CGFloat) -> CALayer { + func drawRing(ringPath: CGPath, roundedRect: RoundedRect, gradient: WatchLayout.Gradient, ticks: ChineseCalendar.Ticks, startingAngle: CGFloat, fontSize: CGFloat, minorLineWidth: CGFloat, majorLineWidth: CGFloat, drawShadow: Bool) -> CALayer { let ringLayer = CALayer() let ringShadow = applyGradient(to: ringPath, gradient: gradient, alpha: watchLayout.shadeAlpha, startingAngle: startingAngle) ringLayer.addSublayer(ringShadow) @@ -621,7 +625,9 @@ class WatchFaceView: NSView { let finishedRingLayer = CALayer() let textLayers = CALayer() + let shadowLayer = CALayer() finishedRingLayer.addSublayer(ringLayerAfterMinor) + finishedRingLayer.addSublayer(shadowLayer) finishedRingLayer.addSublayer(ringMinorTicks) finishedRingLayer.addSublayer(ringMajorTicks) finishedRingLayer.addSublayer(textLayers) @@ -654,6 +660,19 @@ class WatchFaceView: NSView { let textMaskMajor = shapeFrom(path: textMaskPath) ringMajorTicksMask.addSublayer(textMaskMajor) + if drawShadow { + let shadowPath = roundedRect.path + shadowLayer.shadowPath = shadowPath + shadowLayer.shadowOffset = NSMakeSize(0.01 * shortEdge, -0.01 * shortEdge) + shadowLayer.shadowRadius = 0.03 * shortEdge + shadowLayer.shadowOpacity = 0.2 + let shadowMaskPath = CGMutablePath() + shadowMaskPath.addPath(shadowPath) + shadowMaskPath.addPath(CGPath(rect: self.bounds, transform: nil)) + let shadowMask = shapeFrom(path: shadowMaskPath) + shadowLayer.mask = shadowMask + } + return finishedRingLayer } func activeRingAngle(to layer: CALayer, ringPath: CGPath, gradient: WatchLayout.Gradient, angle: CGFloat, startingAngle: CGFloat, outerRing: RoundedRect, ticks: ChineseCalendar.Ticks) { @@ -664,8 +683,8 @@ class WatchFaceView: NSView { layer.sublayers?[0].sublayers?[0].sublayers?[1] = ringActive } for i in 0..= Self.majorUpdateInterval) || (chineseCalendar.preciseMonth != keyStates.month) { let monthTicks = chineseCalendar.monthTicks if (graphicArtifects.firstRingLayer == nil) || (chineseCalendar.year != keyStates.year) || (ChineseCalendar.globalMonth != keyStates.globalMonth) || (chineseCalendar.timezone != keyStates.timezone) { - graphicArtifects.firstRingLayer = drawRing(ringPath: graphicArtifects.firstRingOuterPath!, roundedRect: graphicArtifects.firstRingOuter!, gradient: watchLayout.firstRing, ticks: monthTicks, startingAngle: phase.firstRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth) + graphicArtifects.firstRingLayer = drawRing(ringPath: graphicArtifects.firstRingOuterPath!, roundedRect: graphicArtifects.firstRingOuter!, gradient: watchLayout.firstRing, ticks: monthTicks, startingAngle: phase.firstRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth, drawShadow: true) keyStates.year = chineseCalendar.year } graphicArtifects.firstRingMarks = drawMark(at: chineseCalendar.planetPosition, on: graphicArtifects.firstRingOuter!, startingAngle: phase.firstRing, maskPath: graphicArtifects.firstRingOuterPath!, colors: watchLayout.planetIndicator, radius: 0.012 * shortEdge) @@ -822,7 +841,7 @@ class WatchFaceView: NSView { if (graphicArtifects.secondRingLayer == nil) || (chineseCalendar.year != keyStates.year) || (chineseCalendar.preciseMonth != keyStates.month) || (ChineseCalendar.globalMonth != keyStates.globalMonth) || (chineseCalendar.timezone != keyStates.timezone) || (abs(chineseCalendar.time.distance(to: keyStates.monthUpdatedTime)) >= Self.minorUpdateInterval) || (chineseCalendar.day != keyStates.day) { let dayTicks = chineseCalendar.dayTicks if (graphicArtifects.secondRingLayer == nil) || (chineseCalendar.year != keyStates.year) || (chineseCalendar.preciseMonth != keyStates.month) || (chineseCalendar.timezone != keyStates.timezone) || (ChineseCalendar.globalMonth != keyStates.globalMonth) { - graphicArtifects.secondRingLayer = drawRing(ringPath: graphicArtifects.secondRingOuterPath!, roundedRect: graphicArtifects.secondRingOuter!, gradient: watchLayout.secondRing, ticks: dayTicks, startingAngle: phase.secondRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth) + graphicArtifects.secondRingLayer = drawRing(ringPath: graphicArtifects.secondRingOuterPath!, roundedRect: graphicArtifects.secondRingOuter!, gradient: watchLayout.secondRing, ticks: dayTicks, startingAngle: phase.secondRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth, drawShadow: true) graphicArtifects.secondRingMarks = addMarks(position: chineseCalendar.eventInMonth, on: graphicArtifects.secondRingOuter!, startingAngle: phase.secondRing, maskPath: graphicArtifects.secondRingOuterPath!, radius: 0.012 * shortEdge) keyStates.month = chineseCalendar.preciseMonth keyStates.globalMonth = ChineseCalendar.globalMonth @@ -836,7 +855,7 @@ class WatchFaceView: NSView { // Third Ring let hourTicks = chineseCalendar.hourTicks if (graphicArtifects.thirdRingLayer == nil) || (chineseCalendar.dateString != keyStates.dateString) || (chineseCalendar.year != keyStates.year) || (chineseCalendar.timezone != keyStates.timezone) { - graphicArtifects.thirdRingLayer = drawRing(ringPath: graphicArtifects.thirdRingOuterPath!, roundedRect: graphicArtifects.thirdRingOuter!, gradient: watchLayout.thirdRing, ticks: hourTicks, startingAngle: phase.thirdRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth) + graphicArtifects.thirdRingLayer = drawRing(ringPath: graphicArtifects.thirdRingOuterPath!, roundedRect: graphicArtifects.thirdRingOuter!, gradient: watchLayout.thirdRing, ticks: hourTicks, startingAngle: phase.thirdRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth, drawShadow: true) graphicArtifects.thirdRingMarks = addMarks(position: chineseCalendar.eventInDay, on: graphicArtifects.thirdRingOuter!, startingAngle: phase.thirdRing, maskPath: graphicArtifects.thirdRingOuterPath!, radius: 0.012 * shortEdge) graphicArtifects.thirdRingMarks?.addSublayer(addIntradayMarks(positions: chineseCalendar.sunMoonPositions, on: graphicArtifects.thirdRingInner!, startingAngle: phase.thirdRing, maskPath: graphicArtifects.thirdRingOuterPath!, radius: 0.012 * shortEdge)) keyStates.day = chineseCalendar.day @@ -851,7 +870,7 @@ class WatchFaceView: NSView { let subhourTicks = chineseCalendar.subhourTicks if (graphicArtifects.fourthRingLayer == nil) || (chineseCalendar.startHour != keyStates.priorHour) || (chineseCalendar.timezone != keyStates.timezone) { if (graphicArtifects.fourthRingLayer == nil) || (chineseCalendar.startHour != keyStates.priorHour) { - graphicArtifects.fourthRingLayer = drawRing(ringPath: graphicArtifects.fourthRingOuterPath!, roundedRect: graphicArtifects.fourthRingOuter!, gradient: fourthRingColor, ticks: subhourTicks, startingAngle: phase.fourthRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth) + graphicArtifects.fourthRingLayer = drawRing(ringPath: graphicArtifects.fourthRingOuterPath!, roundedRect: graphicArtifects.fourthRingOuter!, gradient: fourthRingColor, ticks: subhourTicks, startingAngle: phase.fourthRing, fontSize: fontSize, minorLineWidth: minorLineWidth, majorLineWidth: majorLineWidth, drawShadow: true) keyStates.priorHour = chineseCalendar.startHour } graphicArtifects.fourthRingMarks = addMarks(position: chineseCalendar.eventInHour, on: graphicArtifects.fourthRingOuter!, startingAngle: phase.fourthRing, maskPath: graphicArtifects.fourthRingOuterPath!, radius: 0.012 * shortEdge) @@ -862,9 +881,21 @@ class WatchFaceView: NSView { self.layer?.addSublayer(graphicArtifects.fourthRingLayer!) self.layer?.addSublayer(graphicArtifects.fourthRingMarks!) + // Inner Ring if (graphicArtifects.innerBox == nil) { graphicArtifects.innerBox = shapeFrom(path: graphicArtifects.innerBoundPath!) graphicArtifects.innerBox!.fillColor = isDark ? watchLayout.innerColorDark.cgColor : watchLayout.innerColor.cgColor + let shadowLayer = CALayer() + shadowLayer.shadowPath = graphicArtifects.innerBoundPath! + shadowLayer.shadowOffset = NSMakeSize(0.01 * shortEdge, -0.01 * shortEdge) + shadowLayer.shadowRadius = 0.03 * shortEdge + shadowLayer.shadowOpacity = 0.2 + let shadowMaskPath = CGMutablePath() + shadowMaskPath.addPath(graphicArtifects.innerBoundPath!) + shadowMaskPath.addPath(CGPath(rect: self.bounds, transform: nil)) + let shadowMask = shapeFrom(path: shadowMaskPath) + shadowLayer.mask = shadowMask + graphicArtifects.innerBox?.addSublayer(shadowLayer) } self.layer?.addSublayer(graphicArtifects.innerBox!) diff --git a/layout.txt b/layout.txt deleted file mode 100644 index ce3d3d7..0000000 --- a/layout.txt +++ /dev/null @@ -1,37 +0,0 @@ -globalMonth: true -apparentTime: true -backAlpha: 1.0 -firstRing: locations: 0.0, 0.25, 0.5, 0.75; colors: 0xFFDB8174, 0xFFAE74B9, 0xFF7033E7, 0xFF6173BC; loop: true -secondRing: locations: 0.0, 0.25, 0.5, 0.75; colors: 0xFFB765B7, 0xFF4B5FC1, 0xFF4598D9, 0xFF4B5FC1; loop: true -thirdRing: locations: 0.0, 0.5; colors: 0xFFCB6693, 0xFF5E44D3; loop: true -innerColor: 0x66FFFFFF -majorTickColor: 0x00000000 -majorTickAlpha: 0.0 -minorTickColor: 0x00000000 -minorTickAlpha: 0.5 -fontColor: 0xFFFFFFFF -centerFontColor: locations: 0.25, 0.75; colors: 0xFF523A6D, 0xFF5A3136; loop: false -evenSolarTermTickColor: 0xFF000000 -oddSolarTermTickColor: 0xFF555555 -innerColorDark: 0x66FFFFFF -majorTickColorDark: 0x00000000 -minorTickColorDark: 0x007F7F7F -fontColorDark: 0xFF000000 -evenSolarTermTickColorDark: 0xFFFFFFFF -oddSolarTermTickColorDark: 0xFFAAAAAA -planetIndicator: 0xFF3C1E0A, 0xFFAABEC8, 0xFF2830D2, 0xFF5AB43C, 0xFF3296AA, 0xFF74EFDC -eclipseIndicator: 0xFF804427 -fullmoonIndicator: 0xFF3BEFFF -oddStermIndicator: 0xFFAAAAAA -evenStermIndicator: 0xFFFFFFFF -sunPositionIndicator: 0xFF000000, 0xFFAAADFF, 0xFF0A36B1, 0xFF6EBCD3 -moonPositionIndicator: 0xFFE6B8AF, 0xFFE56572, 0xFF9E1E67 -shadeAlpha: 0.1986916089965398 -textFont: SourceHanSansKVF-Regular -centerFont: SourceHanSansKVF-Heavy -centerTextOffset: -1.1 -verticalTextOffset: -0.96 -horizontalTextOffset: 0.1 -watchWidth: 396.0 -watchHeight: 484.0 -cornerRadiusRatio: 0.32