12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- //
- // KMSyncDot.swift
- // PDF Reader Pro
- //
- // Created by lizhe on 2024/2/29.
- //
- import Cocoa
- import QuartzCore
- class KMSyncDot: NSObject {
- var point: NSPoint
- var page: CPDFPage?
- private var phase: Int = 0
- private var timer: Timer?
- private var handler: ((Bool) -> Void)?
- init(point: NSPoint, page: CPDFPage?, updateHandler: ((Bool) -> Void)?) {
- self.point = point
- self.page = page
- self.handler = updateHandler
- super.init()
- setup()
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- private func setup() {
- timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(animate(_:)), userInfo: nil, repeats: true)
- }
- deinit {
- timer?.invalidate()
- handler = nil
- }
- @objc private func finish(_ timer: Timer) {
- timer.invalidate()
- if let handler = handler {
- handler(true)
- }
- }
- @objc private func animate(_ timer: Timer) {
- phase += 1
- if phase >= 10 {
- timer.invalidate()
- self.timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(finish(_:)), userInfo: nil, repeats: false)
- }
- if let handler = handler {
- handler(false)
- }
- }
- func invalidate() {
- timer?.invalidate()
- }
-
- func bounds() -> NSRect {
- return KMRectFromCenterAndSquareSize(center: point, size: 22.0) ?? CGRectZero
- }
- func draw(in ctx: CGContext) {
- ctx.saveGState()
- var s: CGFloat = 6.0
- OSMemoryBarrier()
- if phase < 10 {
- s += 8.0 * sin(CGFloat(phase) * 0.1 * .pi)
- let components: [CGFloat] = [1.0, 0.3, 0.3, 1.0, 1.0, 0.0, 0.0, 1.0]
- let locations: [CGFloat] = [0.0, 1.0]
- let colorspace = CGColorSpaceCreateDeviceRGB()
- if let gradient = CGGradient(colorSpace: colorspace, colorComponents: components, locations: locations, count: 2) {
- ctx.addEllipse(in: CGRect(x: point.x - 0.5 * s, y: point.y - 0.5 * s, width: s, height: s))
- ctx.clip()
- ctx.drawRadialGradient(gradient, startCenter: CGPoint(x: point.x, y: point.y + 0.35 * s), startRadius: 0.0, endCenter: CGPoint(x: point.x, y: point.y), endRadius: 0.5 * s, options: [])
- }
- } else {
- ctx.setBlendMode(.multiply)
- ctx.setFillColor(CGColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0))
- ctx.fillEllipse(in: CGRect(x: point.x - 0.5 * s, y: point.y - 0.5 * s, width: s, height: s))
- }
- ctx.restoreGState()
- }
- }
|