HarmonyOS CanvasRenderingContext2D绘制刮刮卡特效的问题

CanvasRenderingContext2D绘制刮刮卡特效动画的问题设置this.context.globalCompositeOperation = 'xor’时候随着手势的刮开 效果出现问题

代码如下:

import image from '@ohos.multimedia.image' 
 
@Component 
export struct FillStyleExample { 
  private settings: RenderingContextSettings = new RenderingContextSettings(true) 
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) 
  // private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600) 
  @State x: number = 0 
  @State y: number = 0 
  @State x_left: number = 0 
  @State y_top: number = 0 
  @State iconVisible: boolean = false 
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
      Canvas(this.context) 
        .width('100%') 
        .height('100%') 
        .backgroundColor(Color.Transparent) 
        .onReady(() => { 
          this.getPixmapFromMedia($r('app.media.test')).then((image) => { 
            this.context.drawImage(image, this.x, this.y) 
          }) 
          this.context.lineWidth = 40 
          this.context.beginPath() 
          this.context.fillStyle = Color.Transparent 
          this.context.lineCap = 'round' //round square 
          this.context.globalCompositeOperation = 'xor' //xor 
 
        }) 
      Image($r('app.media.icon')) 
        .width('30') 
        .height('30') 
        .margin({ 
          left: this.x_left, 
          top: this.y_top 
        }) 
        .visibility(this.iconVisible ? Visibility.Visible : Visibility.None) 
 
    } 
    .width('100%') 
    .height('100%') 
    .gesture( 
      PanGesture({ direction: PanDirection.All }) 
        .onActionStart((event) => { 
          this.context?.moveTo(event.fingerList[0].localX, event.fingerList[0].localY) 
        }) 
        .onActionUpdate((event) => { 
          this.iconVisible = true 
          this.x_left = event.fingerList[0].localX 
          this.y_top = event.fingerList[0].localY 
          this.context?.lineTo(this.x_left, this.y_top) 
          this.context?.stroke() 
          this.context?.restore() 
        }) 
        .onActionEnd((event) => { 
          this.iconVisible = false 
        })) 
 
  } 
 
  private async getPixmapFromMedia(resource: Resource) { 
    let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({ 
      bundleName: resource.bundleName, 
      moduleName: resource.moduleName, 
      id: resource.id 
    }) 
    let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength)) 
    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ 
      desiredPixelFormat: image.PixelMapFormat.RGB_565, 
      desiredSize: { 
        width: 1080, 
        height: 1170 
      } 
    }) 
    await imageSource.release() 
    return createPixelMap 
  } 
}
HarmonyOS
2024-08-08 18:04:36
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa
import image from '@ohos.multimedia.image' 
 
@Entry 
@Component 
export struct Page { 
  private settings: RenderingContextSettings = new RenderingContextSettings(true) 
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) 
  @State x: number = 0 
  @State y: number = 0 
  @State x_left: number = 0 
  @State y_top: number = 0 
  @State iconVisible: boolean = false 
  isDrawing: boolean = false 
  lastX: number = 0 
  lastY: number = 0 
 
  draw(ctx: CanvasRenderingContext2D, fromX: number, fromY: number, toX: number, toY: number) { 
    // 使用贝塞尔曲线来绘制平滑路径 
    ctx.beginPath() 
    ctx.moveTo(fromX, fromY) 
    ctx.lineTo(toX, toY) 
    ctx.strokeStyle = '#000' 
    ctx.lineWidth = 40 
    ctx.lineCap = 'round' 
    ctx.lineJoin = 'round' 
    ctx.stroke() 
    ctx.closePath() 
  } 
 
  scratch(event: TouchEvent) { 
    if (!this.isDrawing) { 
      return 
    } 
 
    const touch = event.touches[0] 
    const x = touch.x 
    const y = touch.y 
 
    this.draw(this.context, this.lastX, this.lastY, x, y) 
 
    this.lastX = x 
    this.lastY = y 
  } 
 
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
      Image($r("app.media.bg")).width(px2vp(698)) 
      Canvas(this.context) 
        .width('100%') 
        .height('100%') 
        .backgroundColor(Color.Transparent) 
        .onReady(() => { 
          this.getPixmapFromMedia($r('app.media.img')).then((image) => { 
            this.context.drawImage(image, this.x, this.y) 
            // 设置刮开涂层效果,注意需要先绘制背景在设置 
            this.context.globalCompositeOperation = 'destination-out' 
          }) 
        }) 
        .onTouch((event) => { 
          switch (event.type) { 
            case 0: 
              this.isDrawing = true 
              const touch = event.touches[0] 
              this.lastX = touch.x 
              this.lastY = touch.y 
              this.scratch(event) 
              break 
            case 1: 
              this.isDrawing = false 
              break 
            case 2: 
              this.scratch(event) 
              break
分享
微博
QQ
微信
回复
2024-08-08 20:54:07
相关问题
XComponent、NativeDrawing实现2D图形绘制
698浏览 • 1回复 待解决
使用Drawing进行2d图像绘制
594浏览 • 1回复 待解决
XComponent、openGL实现3D图形绘制
952浏览 • 1回复 待解决
ArkGraphics 2D有什么优势?
130浏览 • 1回复 待解决
ArkGraphics 2D都有哪些使用场景?
168浏览 • 1回复 待解决
HarmonyOS SDK .d.ts 声明问题
194浏览 • 1回复 待解决
harmony surfaceProvider绘制不显示问题
9811浏览 • 4回复 待解决
HarmonyOS Sm2和DES加解密问题
84浏览 • 1回复 待解决
独立指定帧率来运行UI绘制
528浏览 • 1回复 待解决
鸿蒙如何实现位图绘制
9503浏览 • 1回复 待解决
如何操作canvas重新绘制
650浏览 • 1回复 待解决
SurfaceProvider绘制延迟
7033浏览 • 4回复 已解决