I want allow users of my app to scroll with an ease-in and ease-out animation using a CGEvent. This answer showed me how to send the scroll event, and I have a simple playground below to attempt to demonstrate what I would like to do. I can't find an easy API to do this, so I figured I would have to scroll a few dozen times (at least) with delays in between. If there's an easier way, I would love to find it! Naturally I could increase the resolution of my scrollY function, but I'm hoping somebody else knows of an easier, smoother way to do this.
extension CGEvent {
public class func scrollMouse(onPoint point: CGPoint, xLines: Int, yLines: Int) {
if #available(OSX 10.13, *) {
guard let scrollEvent = CGEvent(scrollWheelEvent2Source: nil, units: CGScrollEventUnit.line, wheelCount: 2, wheel1: Int32(yLines), wheel2: Int32(xLines), wheel3: 0) else {
return
}
scrollEvent.setIntegerValueField(CGEventField.eventSourceUserData, value: 1)
scrollEvent.post(tap: CGEventTapLocation.cghidEventTap)
} else {
// scroll event is not supported for macOS older than 10.13
}
}
}
func scrollY() {
let y = 12
let sleep: UInt32 = 10000
// The ease-IN portion
for i in stride(from: 1, to: y, by: 1) {
CGEvent.scrollMouse(onPoint: CGPoint.zero, xLines: 0, yLines:-i)
usleep(sleep * UInt32(i))
}
// The ease-OUT portion
for i in stride(from: y, to: 1, by: -1) {
CGEvent.scrollMouse(onPoint: CGPoint.zero, xLines: 0, yLines:-i)
usleep(sleep * UInt32(y + (y - i)))
}
}