【问题标题】:How do I animate zoom in and out in a NSScrollView so that it is smooth?如何在 NSScrollView 中动画放大和缩小以使其平滑?
【发布时间】:2020-05-26 22:28:56
【问题描述】:

下面是我用来设置滚动视图 documentView 的新大小的函数,但是我不知道如何将帧大小的变化与滚动位置的变化结合起来。如果我对事物应用动画,因为它们的大小会发生变化,并且图像相对于左下角移动,然后图像会滚动回原位。如何组合动画以使大小变化和滚动位置一起变化 - 或任何其他方式来实现平滑放大/缩小。

func zoomIn(zoomFactor: CGFloat = zoomFactor){

        guard let docView = self.docView, let scrollView = self.scrollView else {
            return
        }

        let visible = scrollView.documentVisibleRect
        let newrect = NSInsetRect(visible, NSWidth(visible)*(1 - 1/zoomFactor)/2.0, NSHeight(visible)*(1 - 1/zoomFactor)/2.0);
        let frame = docView.frame

        self.execZoom(docView: docView,
                      size:CGSize(width: zoomFactor, height: zoomFactor),
                      frame:CGRect(x: 0, y: 0, width: frame.size.width * zoomFactor, height: frame.size.height * zoomFactor),
                      origin:newrect.origin)

    }
    func zoomOut(zoomFactor: CGFloat = zoomFactor){
        guard let docView = self.docView, let scrollView = self.scrollView else {
            return
        }
        let visible = scrollView.documentVisibleRect
        let newrect = NSOffsetRect(visible, -NSWidth(visible)*(zoomFactor - 1)/2.0, -NSHeight(visible)*(zoomFactor - 1)/2.0)

        let frame = docView.frame

        self.execZoom(docView: docView,
                      size: CGSize(width: 1/zoomFactor, height: 1/zoomFactor),
                      frame: CGRect(x: 0, y: 0, width: frame.size.width / zoomFactor, height: frame.size.height / zoomFactor),
                      origin: newrect.origin)
    }
    func execZoom(docView: NSView, size: CGSize, frame: CGRect, origin: CGPoint){

            docView.scaleUnitSquare(to: size)

            docView.frame = frame

            docView.scroll(origin)

    }

【问题讨论】:

    标签: zooming nsscrollview


    【解决方案1】:

    有一种使用通用“动画”的简单方法。

    来自文档: 要对放大进行动画处理,请使用对象的动画制作器。默认值为 1.0。 (https://developer.apple.com/documentation/appkit/nsscrollview/1403497-magnification?language=objc)

    “使用对象的动画师”是什么意思?

    而不是:

    self.scrollView.setMagnification(magnification, centeredAt: point)
    

    调用它的动画师:

    self.scrollView.animator().setMagnification(magnification, centeredAt: point)
    

    【讨论】:

      【解决方案2】:

      好吧,扔掉所有这些,然后执行此操作...疯狂快速,流畅,所有带有图像的底层 CALayers 和使用自己的 draw() 方法渲染的可拖动 CALayers 似乎以矢量格式缩放 - 没有字体像素化,线条或图像。

         override func scrollWheel(with event: NSEvent) {
      
              guard event.modifierFlags.contains(.option) else {
                  super.scrollWheel(with: event)
                  return
              }
      
              let dy = event.deltaY
              if dy != 0.0 {
      
                  let magnification = self.scrollView.magnification + dy/30
                  let point = self.scrollView.contentView.convert(event.locationInWindow, from: nil)
      
                  self.scrollView.setMagnification(magnification, centeredAt: point)
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-05
        • 2020-08-03
        • 2023-03-15
        • 2012-07-27
        相关资源
        最近更新 更多