HarmonyOS OffscreenCanvasRenderingContext2D scale 不支持中心点问题

在其他系统中Canvas 支持Matrix变换操作 其中 Matrix提供 postScale(scale, scale, midPoint.x, midPoint.y) 缩放支持指定中心点。

目前在HarmonyOS OffscreenCanvasRenderingContext2D transform scale不支持指定中心点,使用如下函数单次缩放可以实现一样的效果

private scaleWithPoint(
  ctx: OffscreenCanvasRenderingContext2D,
sx: number,
sy: number,
cx: number = 0,
cy: number = 0
) {
  if (cx == 0 && cy == 0) {
    ctx.scale(sx, sy)
    return
  }

  let offsetX = this.canvasWidth / 2 - cx
  let offsetY = this.canvasHeight / 2 - cy

  ctx.translate(-offsetX, -offsetY)
  ctx.scale(sx, sy)
  ctx.translate(offsetX, offsetY)
}

现在存在问题:

  1. 如果第二次希望在上次缩放基础再次缩放,则会出现闪动。希望能协助给出和Matrix 多次postScale等价效果代码实现。目前实现缩放逻辑在 demo的 ZoomMoveImpl 中

  2. 帮忙确认matrix4.identity() 多次指定中心点的缩放 是否和 Matrix postScale等价

  3. 帮忙确认如果是使用Canvas控件外部的transform方法,这个方法支持matrix4 矩阵变换,如何将绘制内容同步到 OffscreenCanvasRenderingContext2D 中

HarmonyOS
21h前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
put_get

参考示例代码:

xxx.ets

@Entry
@Component
struct Scale {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  ScaleBaseOnPoint(x: number, y: number, scaleX: number, scaleY: number) {
    let dx = x * scaleX
    let dy = y * scaleY
    let translateX = x - dx
    let translateY = y - dy
    this.context.setTransform(scaleX, 0, 0, scaleY, translateX, translateY)
  }
  /**
   * Stroke Specify Rectangular Area
   *
   * @param { number } x - 矩形的左上角x坐标
   * @param { number } y - 矩形的左上角y坐标
   * @param { number } width - 矩形的宽度
   * @param { number } height - 矩形的高度
   * @param { number } scaleX - 水平方向的缩放值
   * @param { number } scaleY - 垂直方向的缩放值
   */
  ScaleRect(x: number, y: number, width: number, height: number, scaleX: number, scaleY: number) {
    this.context.save()
    let pointX = x + width/2
    let pointY = y + height/2
    this.ScaleBaseOnPoint(pointX, pointY, scaleX, scaleY)
    this.context.strokeStyle = Color.Black
    this.context.strokeRect(x, y, width, height)
    this.context.restore()
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#ffff00')
        .onReady(() =>{
          this.context.lineWidth = 3
          this.context.strokeStyle = Color.Red
          this.context.strokeRect(100, 100, 50, 50)
          this.ScaleRect(100, 100, 50, 50, 2, 2)
          this.ScaleRect(100, 100, 50, 50, 4, 4)
          this.ScaleRect(100, 100, 50, 50, 0.5, 0.5)
          this.ScaleRect(100, 100, 50, 50, 2, 0.5)
        })
    }
    .width('100%')
    .height('100%')
  }
}
分享
微博
QQ
微信
回复
18h前
相关问题
如何可以获取组件的中心点坐标
736浏览 • 1回复 待解决
HarmonyOS关于mqtt不支持ssl协议问题
543浏览 • 2回复 待解决
web组件不支持localstorage
837浏览 • 1回复 待解决
HarmonyOS CanvasRenderingContext2D使用问题
36浏览 • 1回复 待解决
HarmonyOS Span不支持n换行
36浏览 • 1回复 待解决
HarmonyOS image不支持mask吗
52浏览 • 1回复 待解决
HarmonyOS RN使用datetimePicker显示不支持
110浏览 • 1回复 待解决
http类不支持cancel方法
207浏览 • 1回复 待解决
HarmonyOS Matrix2D的用法问题
27浏览 • 1回复 待解决
HarmonyOS Object不支持 ... 展开符吗?
288浏览 • 1回复 待解决
HarmonyOS ets不支持匿名类吗?
243浏览 • 2回复 待解决