HarmonyOS 鸿蒙Next Canvas组件画线,如何清空画布,代码如下

发布于 1周前 作者 zlyuanteng 来自 鸿蒙OS

HarmonyOS 鸿蒙Next Canvas组件画线,如何清空画布,代码如下 代码如下,在onDrawInit方法中,每次都执行了清空画布的操作,但是貌似不生效,导致图片重叠问题,如图~

代码如下,在onDrawInit方法中,每次都执行了清空画布的操作,但是貌似不生效,导致图片重叠问题。

import { canvasInfo, canvas_option } from '../oldModel/TestModel_2'

@Entry
@Component
struct McLineChart {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  public offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(400, 400, this.settings);
  @State options: canvasInfo = {}
  private pageSize = 20 //屏幕默认显示个数
  private space = 0 //坐标点的间距
  @State @Watch('onDrawInit') startIndex: number = 0 // 起始坐标点的索引
  @State panIndex: number = 0 // 记录上次的起始索引
  @State offsetX: number = 0 // 记录在手指移动过程中,移动的距离
  private min: number = Number.MAX_VALUE //最小值
  private max = 0 //最大值
  // 拖动方向只允许左右移动,
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Left | PanDirection.Right })

  aboutToAppear() {
    this.options = canvas_option
  }

  onDrawInit() {
    this.offContext.clearRect(0, 0, 400, 400);

    this.context.lineWidth = 3
    this.context.lineJoin = 'round'
    if (this.startIndex <= 0) {
      this.startIndex = 0
    }
    let endIndex = this.startIndex + this.pageSize
    if (endIndex > this.options.data!.length) {
      endIndex = this.options.data!.length
    }
    //需要显示的数据
    let viewData = this.options.data!.slice(this.startIndex, endIndex)
    viewData.forEach((item, index) => {
      if (item.value! < this.min) {
        this.min = item.value!
      }
      if (item.value! > this.max) {
        this.max = item.value!
      }
    })
    this.space = 400 / (this.pageSize - 1)
    let pxPerNumber = 400 / (this.max - this.min)
    // this.offContext.clearRect(0, 0, 400, 400)
    this.context.beginPath()
    viewData.forEach((item, index) => {
      let x = this.space * (index)
      let y = 400 - item.value!
      if (index == 0) {
        this.offContext.moveTo(x, y)
      } else {
        this.offContext.lineTo(x, y)
      }
    })
    this.offContext.stroke()
    let image = this.offContext.transferToImageBitmap()
    this.context.transferFromImageBitmap(image)
  }

  build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('50%')
        .backgroundColor('#C0C0C0')
        .onReady(() => {
          this.onDrawInit()
        })
        .gesture(
          PanGesture(this.panOption)
            .onActionStart((event: GestureEvent) => {
            })
            .onActionUpdate((event: GestureEvent) => {
              console.debug(TAG, `手指移动 -> ${event.offsetX}`)
              if (Math.abs(this.offsetX - event.offsetX) < 20) {
                return
              }
              if (this.startIndex >= this.options.data!.length - this.pageSize) {
                this.startIndex = this.options.data!.length - this.pageSize
              }

              if (Math.abs(event.offsetX) > 20) {
                // this.startIndex = Math.floor(this.panIndex - event.offsetX / 20)
                this.startIndex = this.startIndex - Math.round((event.offsetX - this.offsetX) / 20)
                console.debug(TAG, `startIndex -> ${this.startIndex}`)
              }
              this.offsetX = event.offsetX
            })
            .onActionEnd(() => {
              this.panIndex = this.startIndex
            })
        )
      Text(`左侧起始坐标索引${this.startIndex.toString()}`)
    }
  }
}

const TAG: string = 'Pan手势'

更多关于HarmonyOS 鸿蒙Next Canvas组件画线,如何清空画布,代码如下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复
offContext.clearRectr换成context.clearRect试试

```javascript
onDrawInit() {
  // 清空主线程Canvas上下文
  this.context.clearRect(0, 0, 400, 400);
  // 其他代码
}

更多关于HarmonyOS 鸿蒙Next Canvas组件画线,如何清空画布,代码如下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


还有个问题:canvas组件的宽高要和初始化时的值一样,不可以设置百分比,

offContext这个里面是可以拿到你的canvas的宽高,所以你设百分百也没问题。
主要是canvas里面的参数都是px,而不是length属性。

刚刚试了一下,确实和canvas的宽高没关系,百分比也可以,找到罪魁祸首了!

就是初始化的时候,初始了 this.context.beginPath()

但是实际应该使用离屏渲染,初始化-> this.offContext.beginPath()

清空的时候,contextoffContext都要清一下,

this.context.clearRect(0, 0, 400, 400);

除了这个函数有没有全部清空操作啊

暂时不清楚,可以把clearRect后两位参数设置大一点,就可以达到清空操作。

猜测是下面这段代码引起的,那每次绘制时,如何清空上一次的image?

let image = this.offContext.transferToImageBitmap() 
this.context.transferFromImageBitmap(image)

每次绘制的时候,要清空context和offContext的画布,

在HarmonyOS中,使用Canvas组件画线后,如果需要清空画布,可以通过调用CanvasclearRect方法来实现。clearRect方法可以清除指定矩形区域内的内容,若需要清空整个画布,可以将矩形区域设置为画布的整个大小。

以下是一个示例代码,展示如何在鸿蒙Next中使用Canvas组件画线并清空画布:

import { Canvas, CanvasRenderingContext2D } from '@ohos.graphics';

// 假设canvas是已经获取到的Canvas对象
const canvas: Canvas = ...;
const context: CanvasRenderingContext2D = canvas.getContext('2d');

// 画线
context.beginPath();
context.moveTo(10, 10);
context.lineTo(100, 100);
context.stroke();

// 清空画布
context.clearRect(0, 0, canvas.width, canvas.height);

在这段代码中,clearRect(0, 0, canvas.width, canvas.height)会清除整个画布的内容,从坐标(0, 0)开始,到画布的宽度和高度结束。

在HarmonyOS鸿蒙Next中,使用Canvas组件画线后,可以通过调用clearRect方法来清空画布。以下是一个示例代码:

// 获取Canvas上下文
const ctx = canvas.getContext('2d');

// 画线
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(100, 100);
ctx.stroke();

// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);

clearRect方法会清除指定矩形区域内的所有内容,参数为矩形的起始坐标和宽高。通过将整个画布作为矩形区域,即可清空整个画布。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!