如何在拖动鼠标时将绘制的形状绑定为正方形
How to bound the drawn shape to square as mouse dragged
我在鼠标按下事件开始时绘制一个形状,该动画是在鼠标拖动事件上绘制的。下面是使用的代码:
override func mouseDown(with event: NSEvent) {
self.startPoint = self.convert(event.locationInWindow, from: nil)
if self.shapeLayer != nil {
self.shapeLayer.removeFromSuperlayer()
self.shapeLayer = nil
}
var pixelColor: NSColor = NSReadPixel(startPoint) ?? NSColor()
shapeLayer = CAShapeLayer()
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = NSColor.clear.cgColor
if pixelColor == NSColor.black {
pixelColor = NSColor.color_white
} else {
pixelColor = NSColor.black
}
shapeLayer.strokeColor = pixelColor.cgColor
shapeLayer.lineDashPattern = [1]
self.layer?.addSublayer(shapeLayer)
var dashAnimation = CABasicAnimation()
dashAnimation = CABasicAnimation(keyPath: "lineDashPhase")
dashAnimation.duration = 0.75
dashAnimation.fromValue = 0.0
dashAnimation.toValue = 15.0
dashAnimation.repeatCount = 0.0
shapeLayer.add(dashAnimation, forKey: "linePhase")
}
override func mouseDragged(with event: NSEvent) {
let point: NSPoint = self.convert(event.locationInWindow, from: nil)
let path = CGMutablePath()
path.move(to: self.startPoint)
path.addLine(to: NSPoint(x: self.startPoint.x, y: point.y))
path.addLine(to: point)
path.addLine(to: NSPoint(x: point.x, y: self.startPoint.y))
path.closeSubpath()
self.shapeLayer.path = path
}
目前它也会像这样绘制矩形:
我们能否将其绑定为正方形,以便当用户开始拖动鼠标时它将始终沿着正方形移动?
在 mouseDragged
:
- 获取从
startPoint.x
到point.x
的距离
- 获取从
startPoint.y
到point.y
的距离
- 使用这两者的最大值或最小值(abs() 值)作为轮廓形状的宽度和高度
使用MAX会画出一个更大的正方形,当你穿过一个轴时它会“翻转”。使用 MIN 将绘制一个正方形,当您接近轴时该正方形会缩小到中心。查看差异的最简单方法是尝试一下:
var startPoint: CGPoint = .zero
override func mouseDown(with event: NSEvent) {
self.startPoint = self.convert(event.locationInWindow, from: nil)
}
override func mouseDragged(with event: NSEvent) {
let point: NSPoint = self.convert(event.locationInWindow, from: nil)
var newPoint: CGPoint = self.startPoint
let xDiff = point.x - self.startPoint.x
let yDiff = point.y - self.startPoint.y
// using min() will cause the square to "shrink"
// as you get closer to an axis
let dist = min(abs(xDiff), abs(yDiff))
// using max() will cause the square to "flip"
// when crossing an axis
//let dist = max(abs(xDiff), abs(yDiff))
newPoint.x += xDiff > 0 ? dist : -dist
newPoint.y += yDiff > 0 ? dist : -dist
let path = CGMutablePath()
path.move(to: self.startPoint)
path.addLine(to: NSPoint(x: self.startPoint.x, y: newPoint.y))
path.addLine(to: newPoint)
path.addLine(to: NSPoint(x: newPoint.x, y: self.startPoint.y))
path.closeSubpath()
self.shapeLayer.path = path
}
以防有人在 iOS 中寻找类似功能:
var startPoint: CGPoint = .zero
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
startPoint = touch.location(in: self)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let point = touch.location(in: self)
var newPoint: CGPoint = startPoint
let xDiff = point.x - startPoint.x
let yDiff = point.y - startPoint.y
// using min() will cause the square to "shrink"
// as you get closer to an axis
//let dist = min(abs(xDiff), abs(yDiff))
// using max() will cause the square to "flip"
// when crossing an axis
let dist = max(abs(xDiff), abs(yDiff))
newPoint.x += xDiff > 0 ? dist : -dist
newPoint.y += yDiff > 0 ? dist : -dist
let path = CGMutablePath()
path.move(to: startPoint)
path.addLine(to: CGPoint(x: startPoint.x, y: newPoint.y))
path.addLine(to: newPoint)
path.addLine(to: CGPoint(x: newPoint.x, y: startPoint.y))
path.closeSubpath()
shapeLayer.path = path
}
}
我在鼠标按下事件开始时绘制一个形状,该动画是在鼠标拖动事件上绘制的。下面是使用的代码:
override func mouseDown(with event: NSEvent) {
self.startPoint = self.convert(event.locationInWindow, from: nil)
if self.shapeLayer != nil {
self.shapeLayer.removeFromSuperlayer()
self.shapeLayer = nil
}
var pixelColor: NSColor = NSReadPixel(startPoint) ?? NSColor()
shapeLayer = CAShapeLayer()
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = NSColor.clear.cgColor
if pixelColor == NSColor.black {
pixelColor = NSColor.color_white
} else {
pixelColor = NSColor.black
}
shapeLayer.strokeColor = pixelColor.cgColor
shapeLayer.lineDashPattern = [1]
self.layer?.addSublayer(shapeLayer)
var dashAnimation = CABasicAnimation()
dashAnimation = CABasicAnimation(keyPath: "lineDashPhase")
dashAnimation.duration = 0.75
dashAnimation.fromValue = 0.0
dashAnimation.toValue = 15.0
dashAnimation.repeatCount = 0.0
shapeLayer.add(dashAnimation, forKey: "linePhase")
}
override func mouseDragged(with event: NSEvent) {
let point: NSPoint = self.convert(event.locationInWindow, from: nil)
let path = CGMutablePath()
path.move(to: self.startPoint)
path.addLine(to: NSPoint(x: self.startPoint.x, y: point.y))
path.addLine(to: point)
path.addLine(to: NSPoint(x: point.x, y: self.startPoint.y))
path.closeSubpath()
self.shapeLayer.path = path
}
目前它也会像这样绘制矩形:
我们能否将其绑定为正方形,以便当用户开始拖动鼠标时它将始终沿着正方形移动?
在 mouseDragged
:
- 获取从
startPoint.x
到point.x
的距离
- 获取从
startPoint.y
到point.y
的距离
- 使用这两者的最大值或最小值(abs() 值)作为轮廓形状的宽度和高度
使用MAX会画出一个更大的正方形,当你穿过一个轴时它会“翻转”。使用 MIN 将绘制一个正方形,当您接近轴时该正方形会缩小到中心。查看差异的最简单方法是尝试一下:
var startPoint: CGPoint = .zero
override func mouseDown(with event: NSEvent) {
self.startPoint = self.convert(event.locationInWindow, from: nil)
}
override func mouseDragged(with event: NSEvent) {
let point: NSPoint = self.convert(event.locationInWindow, from: nil)
var newPoint: CGPoint = self.startPoint
let xDiff = point.x - self.startPoint.x
let yDiff = point.y - self.startPoint.y
// using min() will cause the square to "shrink"
// as you get closer to an axis
let dist = min(abs(xDiff), abs(yDiff))
// using max() will cause the square to "flip"
// when crossing an axis
//let dist = max(abs(xDiff), abs(yDiff))
newPoint.x += xDiff > 0 ? dist : -dist
newPoint.y += yDiff > 0 ? dist : -dist
let path = CGMutablePath()
path.move(to: self.startPoint)
path.addLine(to: NSPoint(x: self.startPoint.x, y: newPoint.y))
path.addLine(to: newPoint)
path.addLine(to: NSPoint(x: newPoint.x, y: self.startPoint.y))
path.closeSubpath()
self.shapeLayer.path = path
}
以防有人在 iOS 中寻找类似功能:
var startPoint: CGPoint = .zero
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
startPoint = touch.location(in: self)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let point = touch.location(in: self)
var newPoint: CGPoint = startPoint
let xDiff = point.x - startPoint.x
let yDiff = point.y - startPoint.y
// using min() will cause the square to "shrink"
// as you get closer to an axis
//let dist = min(abs(xDiff), abs(yDiff))
// using max() will cause the square to "flip"
// when crossing an axis
let dist = max(abs(xDiff), abs(yDiff))
newPoint.x += xDiff > 0 ? dist : -dist
newPoint.y += yDiff > 0 ? dist : -dist
let path = CGMutablePath()
path.move(to: startPoint)
path.addLine(to: CGPoint(x: startPoint.x, y: newPoint.y))
path.addLine(to: newPoint)
path.addLine(to: CGPoint(x: newPoint.x, y: startPoint.y))
path.closeSubpath()
shapeLayer.path = path
}
}