Skip to content

Commit

Permalink
Refactored, added supported platforms in the Package.swift file.
Browse files Browse the repository at this point in the history
Remade some of the documentation markup to include examples uses for some of the more difficult to use shapes.
  • Loading branch information
Kieran Brown committed Oct 15, 2020
1 parent b9cc0cf commit 3abb30f
Show file tree
Hide file tree
Showing 22 changed files with 383 additions and 267 deletions.
8 changes: 2 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
// swift-tools-version:5.1
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Shapes",
platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "Shapes",
targets: ["Shapes"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/kieranb662/CGExtender.git", from: "1.0.1")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Shapes",
dependencies: ["CGExtender"]),
Expand Down
83 changes: 83 additions & 0 deletions Sources/Shapes/AdaptiveLine.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// AdaptiveLine.swift
//
//
// Created by Kieran Brown on 10/15/20.
//

import SwiftUI
import CGExtender

public struct AdaptiveLine: Shape {
public var angle: Angle
public var animatableData: Angle {
get { self.angle }
set { self.angle = newValue }
}
var insetAmount: CGFloat = 0


/// # Adaptive Line
///
/// This shape creates a line centered inside of and constrained by its bounding box.
/// The end points of the line are the points of intersection of an infinitely long angled line and the container rectangle
/// - Parameters:
/// - angle: The angle of the adaptive line with `.zero` pointing in the positive X direction
///
/// ## Example Usage
///
/// ```
/// struct AdaptiveLineExample: View {
/// @State var angle: Double = 0.5
///
/// var body: some View {
/// ZStack {
/// Color(white: 0.1).edgesIgnoringSafeArea(.all)
/// VStack {
/// AdaptiveLine(angle: Angle(degrees: angle*360))
/// .stroke(Color.white,
/// style: StrokeStyle(lineWidth: 30, lineCap: .round))
/// Slider(value: $angle)
/// }
/// .padding()
/// }
/// }
/// }
/// ```
public init(angle: Angle = .zero) {
self.angle = angle
}

public func path(in rect: CGRect) -> Path {
let rect = rect.insetBy(dx: insetAmount, dy: insetAmount)
let w = rect.width
let h = rect.height
let big: CGFloat = 5000000

let x1 = w/2 + big*CGFloat(cos(self.angle.radians))
let y1 = h/2 + big*CGFloat(sin(self.angle.radians))
let x2 = w/2 - big*CGFloat(cos(self.angle.radians))
let y2 = h/2 - big*CGFloat(sin(self.angle.radians))

let points = lineRectIntersection(x1, y1, x2, y2, rect.minX, rect.minY, w, h)
if points.count < 2 {
return Path { p in
p.move(to: CGPoint(x: rect.minX, y: rect.midY))
p.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
}
}

return Path { p in
p.move(to: points[0])
p.addLine(to: points[1])
}
}
}

extension AdaptiveLine: InsettableShape {
public func inset(by amount: CGFloat) -> some InsettableShape {
var shape = self
shape.insetAmount += amount
return shape
}
}
71 changes: 32 additions & 39 deletions Sources/Shapes/Arrow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,71 +3,64 @@

import SwiftUI



/// An arrow that when small is shaped like this **|--|** but when gets longer looks like this **<---->**
/// - parameters:
/// - arrowOffset: The percent `[0,1]` horizontal offset of the arrow in its container
/// - length: The length of the arrow
@available(iOS 13.0, macOS 10.15, watchOS 6.0 , tvOS 13.0, *)
public struct Arrow: Shape {
public var arrowOffset: CGFloat
public var length: CGFloat


/// An arrow that when small is shaped like this **|--|** but when gets longer looks like this **<---->**
/// - parameters:
/// - arrowOffset: The percent `[0,1]` horizontal offset of the arrow in its container
/// - length: The length of the arrow
///
/// ## Example usage
/// ```
/// struct ExpandingArrowExample: View {
/// @State var val: Double = 10
/// @State var isHidden: Bool = false
///
/// var body: some View {
/// VStack {
/// HStack(spacing: 0) {
/// ForEach(1..<9) { (i) in
/// Arrow(arrowOffset: self.val > 100 ? 1/(2*1.414) : 0, length: CGFloat(self.val))
/// .stroke(Color("Light Green")).animation(.easeIn(duration: Double(i)/4.0))
/// .frame(width: 40)
/// }
/// }
/// .frame(height: 300)
/// Slider(value: $val, in: 1...250).padding()
/// }
/// }
/// }
/// ```
public init(arrowOffset: CGFloat, length: CGFloat) {
self.arrowOffset = arrowOffset
self.length = length
}

public var animatableData: AnimatablePair<CGFloat, CGFloat> {
get { AnimatablePair(arrowOffset, length) }
set {
arrowOffset = newValue.first
length = newValue.second
}
}

public func path(in rect: CGRect) -> Path {
Path { path in
let w = rect.width
let h = rect.height

path.move(to: CGPoint(x: w/2, y: h/2 - self.length/2))
path.addLine(to: CGPoint(x: w/2, y: h/2 + self.length/2))

path.move(to: h > 40 ? CGPoint(x: w*self.arrowOffset, y: w*self.arrowOffset + h/2 - self.length/2) : CGPoint(x: 0, y: h/2 - self.length/2))
path.addLine(to: CGPoint(x: w/2, y: h/2 - self.length/2))
path.addLine(to: h > 40 ? CGPoint(x: w-w*self.arrowOffset, y: w*self.arrowOffset + h/2 - self.length/2) : CGPoint(x: w, y: h/2 - self.length/2))

path.move(to: h > 40 ? CGPoint(x: w*self.arrowOffset, y: h/2 + self.length/2 - w*self.arrowOffset) : CGPoint(x: 0, y: h/2 + self.length/2))
path.addLine(to: CGPoint(x: w/2, y: h/2 + self.length/2))
path.addLine(to: h > 40 ? CGPoint(x: w-w*self.arrowOffset, y: h/2 + self.length/2 - w*self.arrowOffset) : CGPoint(x: w, y: h/2 + self.length/2))


}
}


}
@available(iOS 13.0, macOS 10.15, watchOS 6.0 , tvOS 13.0, *)
public struct ExpandingArrowExample: View {
@State var val: Double = 10
@State var isHidden: Bool = false

public init() {

}
public var body: some View {
VStack {
HStack(spacing: 0) {
ForEach(1..<9) { (i) in
Arrow(arrowOffset: self.val > 100 ? 1/(2*1.414) : 0, length: CGFloat(self.val))
.stroke(Color("Light Green")).animation(.easeIn(duration: Double(i)/4.0))
.frame(width: 40)
}
}.frame(height: 300)
Slider(value: $val, in: 1...250).padding()

}
}
}
9 changes: 3 additions & 6 deletions Sources/Shapes/CartesianGrid.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,21 @@

import SwiftUI


@available(iOS 13.0, macOS 10.15, watchOS 6.0 , tvOS 13.0, *)
public struct CartesianGrid: Shape {
public var xCount: Int
public var yCount: Int

public init(xCount: Int, yCount: Int) {
self.xCount = xCount
self.yCount = yCount
}

public func path(in rect: CGRect) -> Path {
let w = rect.width
let h = rect.height
let rangeX = 1...xCount
let rangeY = 1...yCount

return Path { path in
for i in rangeX {
path.move(to: CGPoint(x: CGFloat(i)*w/CGFloat(self.xCount), y: 0))
Expand All @@ -33,4 +31,3 @@ public struct CartesianGrid: Shape {
}
}
}

6 changes: 3 additions & 3 deletions Sources/Shapes/CircularArc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public struct CircularArc: Shape {
public var startAngle: Angle
public var endAngle: Angle
public var clockwise: Bool

public init(start: CGPoint, center: CGPoint, radius: CGFloat, startAngle: Angle, endAngle: Angle, clockwise: Bool) {
self.start = start
self.center = center
self.radius = radius
self.radius = radius
self.startAngle = startAngle
self.endAngle = endAngle
self.clockwise = clockwise

}

public var animatableData: AnimatablePair<AnimatablePair<AnimatablePair<CGPoint, CGPoint>, AnimatablePair<Double, Double>>, CGFloat> {
Expand Down
4 changes: 1 addition & 3 deletions Sources/Shapes/CubicBezierShape.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ public struct CubicBezierShape: Shape {
public func path(in rect: CGRect) -> Path {
Path { path in
path.move(to: self.start)
path.addCurve(to: self.end,
control1: self.control1,
control2: self.control2)
path.addCurve(to: self.end,control1: self.control1, control2: self.control2)
}
}
}
Expand Down
Loading

0 comments on commit 3abb30f

Please sign in to comment.