如何在NSImage上按用户指定角度正确绘制倾斜文本
问题根源
现有代码无法达到预期的核心原因:Core Graphics 上下文的 rotate(by:) 方法默认围绕坐标原点(0,0)执行旋转,而非围绕你指定的文本绘制点counterpoint旋转。直接调用旋转后绘制文本,会出现文本位置偏移、旋转锚点错位的问题,无法得到锚点固定的倾斜文本效果。
另外多数人会在这里踩单位的坑:rotate(by:) 接收的参数是弧度值,如果直接传入用户输入的角度值(比如30、-45这类角度制数值),旋转角度会完全不符合预期。
修正实现代码
要实现文本在指定位置按自定义角度倾斜、锚点不偏移的效果,需要先平移上下文原点到文本目标放置点,再执行旋转,最后在新原点位置绘制文本,参考代码如下:
let textSize = text.size(withAttributes: textFontAttributes) // 如果userAngle是角度制数值,先转为弧度:弧度 = 角度 * π / 180 let rotateRadian = CGFloat(userAngle) * .pi / 180 context.saveGState() // 将上下文原点平移到文本目标放置点 context.translateBy(x: counterpoint.x, y: counterpoint.y) // 此时旋转将围绕目标放置点执行,不会出现位置偏移 context.rotate(by: rotateRadian) // 原点已移动到目标位置,直接在零点绘制文本即可 text.draw(at: .zero, withAttributes: textFontAttributes) context.restoreGState()
注意事项
- 如果使用的是翻转坐标系(原点在左上角),需要提前适配y轴偏移逻辑,避免文本上下颠倒
- 如果需要给文本加描边、阴影等效果,直接在
textFontAttributes里添加对应属性即可,不会影响旋转逻辑 - 旋转角度支持正负值:正值为逆时针旋转,负值为顺时针旋转,可根据交互需求调整
- 锚点可自定义:如果需要文本围绕中心、右上角等位置旋转,只需调整
draw(at:)的传入坐标即可,例如中心锚点传入NSPoint(x: -textSize.width/2, y: -textSize.height/2)
内容的提问来源于stack exchange,提问作者techno
相关产品推荐
相关产品推荐

