1. 程式人生 > 其它 >心形流水燈製作

心形流水燈製作

1.效果圖

2.實現程式碼

// MARK: -XJHeartView

class XJHeartView: UIView {

// 圓半徑

let R: CGFloat = 100

// 繪製路徑

var pathArray: [UIBezierPath] = []

// 所有的view

var allArray: [UIView] = []

// 左邊

var leftArray: [UIView] = []

// 右邊

var rightArray: [UIView] = []

// 左上邊

var leftUpArray: [UIView] = []

// 左下邊

var leftDownArray: [UIView] = []

// 右上邊

var rightUpArray: [UIView] = []

// 右下邊

var rightDownArray: [UIView] = []

override init(frame: CGRect) {

super.init(frame: frame)

self.backgroundColor = UIColor.white

let centerX = self.width * 0.5

let centerY = self.height * 0.5

// (centerX ,centerY + sqrt(2)R)

// (centerX - sqrt(2)R ,centerY)

// (centerX + sqrt(2)R ,centerY)

// (centerX - sqrt(2)R * 0.5 ,centerY - sqrt(2)R * 0.5)

// (centerX + sqrt(2)R * 0.5 ,centerY - sqrt(2)R * 0.5)

let lLine = UIBezierPath()

lLine.move(to: CGPoint(x: centerX, y: centerY + sqrt(2) * R))

lLine.addLine(to: CGPoint(x: centerX - sqrt(2) * R, y: centerY))

let lArc = UIBezierPath(arcCenter: CGPoint(x: centerX - sqrt(2) * R * 0.5, y: centerY - sqrt(2) * R * 0.5), radius: R, startAngle: CGFloat(Double.pi * 0.75), endAngle: CGFloat(Double.pi * 1.75), clockwise: true)

let rArc = UIBezierPath(arcCenter: CGPoint(x: centerX + sqrt(2) * R * 0.5, y: centerY - sqrt(2) * R * 0.5), radius: R, startAngle: CGFloat(Double.pi * 1.25), endAngle: CGFloat(Double.pi * 2.25), clockwise: true)

let rLine = UIBezierPath()

rLine.move(to: CGPoint(x: centerX + sqrt(2) * R, y: centerY))

rLine.addLine(to: CGPoint(x: centerX, y: centerY + sqrt(2) * R))

pathArray.append(lLine)

pathArray.append(lArc)

pathArray.append(rArc)

pathArray.append(rLine)

let rightCenter = CGPoint(x: centerX + sqrt(2) * R * 0.5, y: centerY - sqrt(2) * R * 0.5)

let leftCenter = CGPoint(x: centerX - sqrt(2) * R * 0.5, y: centerY - sqrt(2) * R * 0.5)

// 右上

for i in 0..<8 {

let view = UIView()

view.backgroundColor = extinctColor

self.addSubview(view)

view.layer.cornerRadius = 5

view.layer.masksToBounds = true

view.size = CGSize(width: 10, height: 10)

view.center = getPointCenter(center: rightCenter, angle: CGFloat(-20 + i * 20))

rightUpArray.append(view)

}

// 右下

for b in 0..<8 {

let view = UIView()

view.backgroundColor = extinctColor

self.addSubview(view)

view.layer.cornerRadius = 5

view.layer.masksToBounds = true

view.size = CGSize(width: 10, height: 10)

let offsetX: CGFloat = CGFloat(b) * (CGFloat(sqrt(2) * R) / 7) + 10.0

view.center = CGPoint(x: centerX + offsetX, y: centerY + (CGFloat(sqrt(2) * R) - offsetX))

rightDownArray.append(view)

}

// 左上

for j in 0..<8 {

let view = UIView()

view.backgroundColor = extinctColor

self.addSubview(view)

view.layer.cornerRadius = 5

view.layer.masksToBounds = true

view.size = CGSize(width: 10, height: 10)

view.center = getPointCenter(center: leftCenter, angle: CGFloat(60 + j * 20))

leftUpArray.append(view)

}

// 左下

for a in 0..<8 {

let view = UIView()

view.backgroundColor = extinctColor

self.addSubview(view)

view.layer.cornerRadius = 5

view.layer.masksToBounds = true

view.size = CGSize(width: 10, height: 10)

let offsetX: CGFloat = CGFloat(a) * (CGFloat(sqrt(2) * R) / 7) + 10.0

view.center = CGPoint(x: centerX - offsetX, y: centerY + (CGFloat(sqrt(2) * R) - offsetX))

leftDownArray.append(view)

}

// 順時針360

rightUpArray = rightUpArray.reversed()

rightDownArray = rightDownArray.reversed()

leftUpArray = leftUpArray.reversed()

allArray = rightUpArray + rightDownArray + leftDownArray + leftUpArray

// 逆時針180

leftArray = leftUpArray.reversed()

leftArray.append(leftDownArray.reversed())

// 順時針180

rightArray = rightUpArray + rightDownArray

}

func getPointCenter(center: CGPoint, angle: CGFloat) -> CGPoint {

let x = 100 * cosf(Float(angle * CGFloat(Double.pi) / 180))

let y = 100 * sinf(Float(angle * CGFloat(Double.pi) / 180))

return CGPoint(x: center.x + CGFloat(x), y: center.y - CGFloat(y))

}

required init?(coder: NSCoder) {

fatalError("init(coder:) has not been implemented")

}

// Only override draw() if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

override func draw(_ rect: CGRect) {

for path in self.pathArray {

UIColor.red.set()

path.lineWidth = 1

path.lineCapStyle = .round

path.lineJoinStyle = .round

path.stroke()

}

}

}

// MARK: -

XJHeartViewController

/// 迴圈次數

var loopIndex: Int = 0

/// 迴圈時間

var timeInterval: TimeInterval = 0.2

// 熄滅顏色

let extinctColor = UIColor.blue

// 點亮顏色

let lightingColor = UIColor.red

class XJHeartViewController: XJBaseViewController {

lazy var heartView: XJHeartView = {

let heart = XJHeartView(frame: self.view.bounds)

return heart

}()

/// 定時器

var timer: Timer?

override func viewDidLoad() {

super.viewDidLoad()

loopIndex = 0

self.title = "流水燈"

self.view.addSubview(heartView)

self.createTimer(timeInterval, isFire: false)

}

/// 建立定時器

func createTimer(_ timeInterval: TimeInterval, isFire: Bool) {

timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true) {[weak self] (timer) in

guard let self = self else { return }

self.executionTimer()

}

if isFire {

// timer?.fireDate = .distantPast

} else {

timer?.fireDate = .distantFuture

}

}

/// 銷燬定時器

func invalidateTimer() {

guard let timer = timer else { return }

timer.invalidate()

}

/// 觸發定時器

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

timer?.fireDate = .distantPast

}

/// 點選返回

override func backBtnClick(_ button: UIButton) {

self.invalidateTimer()

super.backBtnClick(button)

}

/// 熄滅所有

func extinctAll() {

for view in heartView.allArray {

view.backgroundColor = extinctColor

}

}

/// 執行定時器

func executionTimer() {

let index = loopIndex % heartView.allArray.count

let loopNum = loopIndex / heartView.allArray.count

print("\(loopIndex)---\(index)---\(loopNum)")

// 迴圈一週

if index == 0 && loopIndex != 0 {

// 熄滅所有

self.extinctAll()

// 下次迴圈時間

let loopTime = timeInterval - Double(loopNum) * 0.05

if loopTime == 0 { return }

// 銷燬舊定時器

self.invalidateTimer()

// 創新新定時器

self.createTimer(loopTime, isFire: true)

}

let view = heartView.allArray[index]

view.backgroundColor = lightingColor

loopIndex += 1

}

}

3.詳細程式碼

https://github.com/CoderLR/XJSwiftKit.git