Skip to content

注释旋转

注释旋转提供标准stamp注释、自定义Stamp注释、图片注释和电子签名注释的旋转功能,允许用户对注释进行全范围(-180~180度)的旋转。ComPDFKit 为旋转注释提供了方便的 API,同时还提供了demo演示。

以编程方式旋转注释

要以编程方式旋转注释,我们需要初始化注释的时候设置注释的三个属性,分别是annotationRotation、saveSourceRect和saveRectRotationPoints。

  • annotationRotation

    以度为单位设置注释的旋转角度,范围在-180~180

  • saveSourceRect

    旋转前的矩形Rect,值得注意的是只需要在注释缩放和移动时刷新,注释旋转的时候不变。

  • saveRectRotationPoints

    旋转后的所有矩形顶点。我们在下面的示例中如何获取旋转后的顶点方法。

以下是注释旋转的示例代码:

swift
// 创建标准Stamp注释
let stampAnnotation = CPDFStampAnnotation(document: document, type: selectedIndex)
 annotation?.bounds = CGRect(x: 100, y: 100, width: 100, height: 100)

// 设置注释的旋转属性
stampAnnotation.annotationRotation = 0
// rotatePoints初始化为bounds的四个顶点
stampAnnotation.setSaveRectRotationPoints(rotatePoints)
stampAnnotation.updateRotationAppearanceStream()
stampAnnotation.setSaveSourceRect(stampAnnotation.bounds)
stampAnnotation.setSaveRectRotationPoints(rotatePoints)

// 注释旋转
@objc func rotateStampAnnotation(_ stampAnnotation: CPDFStampAnnotation, Roate angleDifference: CGFloat) {
    stampAnnotation.annotationRotation = Int(angleDifference * 180 / .pi)
  // 获取stampAnnotation.saveSourceRect()的四个顶点
    var rotatedVertices = computeRotatedRectVerticesWithMidpoints(bounds: stampAnnotation.saveSourceRect(), annotationRotationDegrees: 0, includeMidpoints: true)
  // rotatedVertices 排序,saveSourceRect的左下脚为第一个点,逆时针顺序排序
    rotatedVertices = sortPointsToFormRectangle(points: rotatedVertices)
    let center =  CGPoint(x: stampAnnotation.saveSourceRect().midX, y: stampAnnotation.saveSourceRect().midY)
    var rotatePoints: [NSValue] = []
    var newRotatedVertices: [CGPoint] = []
    for point in rotatedVertices {
      // 获取旋转后的顶点
        let rotatePoint = rotatePointAroundCenter(point: point, center: center, angleRadians: angleDifference)
        let pointValue = NSValue(cgPoint: rotatePoint)
        rotatePoints.append(pointValue)
        newRotatedVertices.append(rotatePoint)
    }
    stampAnnotation.setSaveRectRotationPoints(rotatePoints)
    stampAnnotation.bounds = boundingRectForPoints(points: newRotatedVertices)
    stampAnnotation.updateRotationAppearanceStream()
    stampAnnotation.setSaveRectRotationPoints(rotatePoints)
}

// 获取旋转后的顶点方法
func rotatePointAroundCenter(point: CGPoint, center: CGPoint, angleRadians: CGFloat) -> CGPoint {
    let s = sin(angleRadians)
    let c = cos(angleRadians)

    //将点平移回原点
    var translatedPoint = CGPoint(x: point.x - center.x, y: point.y - center.y)

    //旋转点
    let xnew = translatedPoint.x * c - translatedPoint.y * s
    let ynew = translatedPoint.x * s + translatedPoint.y * c

    //将点平移回来
    translatedPoint.x = xnew + center.x
    translatedPoint.y = ynew + center.y

    return translatedPoint
}
objective-c
// 创建标准Stamp注释
CPDFStampAnnotation *stampAnnotation = [[CPDFStampAnnotation alloc] initWithDocument:document type:selectedIndex];
stampAnnotation.bounds = CGRectMake(100, 100, 100, 100);

// 设置注释的旋转属性
stampAnnotation.annotationRotation = 0;
// rotatePoints初始化为bounds的四个顶点
[stampAnnotation setSaveRectRotationPoints:rotatedVertices];
[stampAnnotation updateAnnotationRotationAppearanceStream];
[stampAnnotation setSaveRectRotationPoints:rotatedVertices];
[stampAnnotation setSaveSourceRect:stampAnnotation.bounds];

// 注释旋转
- (void)rotateStampAnnotation:(CPDFStampAnnotation *)stampRotation rotateAngle:(CGFloat)currentAngle {
    CGPoint center = CGPointMake(CGRectGetMidX(stampRotation.saveSourceRect), CGRectGetMidY(stampRotation.saveSourceRect));
   // 获取stampAnnotation.saveSourceRect()的四个顶点
    NSMutableArray<NSValue *> *saveSourceRectPoint = computeRotatedRectVerticesWithMidpoints(stampRotation.saveSourceRect, 0, YES);
  // rotatedVertices 排序,saveSourceRect的左下脚为第一个点,逆时针顺序排序
    NSMutableArray<NSValue *> *saveRectPoints = sortPointsToFormRectangle(saveSourceRectPoint);
    
    [stampRotation setAnnotationRotation :currentAngle];
    NSMutableArray<NSValue *> *saveRectRotationPoints = [[NSMutableArray array] mutableCopy];
    for (NSUInteger i = 0; i < saveRectPoints.count ; i ++) {
        NSValue *savePointValue = [saveRectPoints objectAtIndex:i];
        CGPoint savePoint = [savePointValue pointValue];
        CGFloat angleRadians = currentAngle * M_PI / 180.0;
      // 获取旋转后的顶点
        CGPoint saveRotationPoint = rotatePointAroundCenter(savePoint, center, angleRadians);
        [saveRectRotationPoints addObject:[NSValue valueWithPoint:saveRotationPoint]];
    }
    [stampRotation setSaveRectRotationPoints:saveRectRotationPoints];
    stampRotation.bounds = boundingRectForPoints(saveRectRotationPoints);
    [stampRotation updateAnnotationRotationAppearanceStream];
    [stampRotation setSaveRectRotationPoints:saveRectRotationPoints];
    
    [self setNeedsDisplayAnnotationViewForPage:stampRotation.page];
}

// 获取旋转后的顶点方法
CGPoint rotatePointAroundCenter(CGPoint point, CGPoint center, CGFloat angleRadians) {
    CGFloat s = sin(angleRadians);
    CGFloat c = cos(angleRadians);
    
    //将点平移回原点
    point.x -= center.x;
    point.y -= center.y;
    
    //旋转点
    CGFloat xnew = point.x * c - point.y * s;
    CGFloat ynew = point.x * s + point.y * c;
    
    //将点平移回来
    point.x = xnew + center.x;
    point.y = ynew + center.y;
    return point;
}