鸿蒙Next画布Canvas基础使用演示

2025-06-27 22:54:32
105次阅读
0个评论

本文将Canvas基础方法和属性罗列出来,通过不同按钮实现不同的绘制,可直观的看到每个功能的绘制结果。感兴趣的同学,可以复制源码,运行起来点点。 功能按键.png

演示.gif 源码:

@Entry
@ComponentV2
struct CanvasTest{
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  @Local canvasLength:number=300
  private img: ImageBitmap = new ImageBitmap('resource://base/media/reba.png');
  build() {
    Column({space:10}){
      Canvas(this.context)
        .width(this.canvasLength)
        .height(this.canvasLength)

      Scroll(){
        Column({space:10}){
          Row({space:10}){
            Button('清空').onClick(()=>{
              this.context.reset()
            })
            Button('移动画布中心点').onClick(()=>{
              this.context.translate(this.canvasLength/2,this.canvasLength/2)
            })
          }
          Row({space:10}){
            Button('绘制XY轴').onClick(()=>{
              this.context.beginPath()
              this.context.lineWidth = 4;
              this.context.strokeStyle = Color.Black;
              this.context.moveTo(0, 0);
              this.context.lineTo(0, this.canvasLength);
              this.context.stroke();
              this.context.moveTo(0, 0);
              this.context.lineTo(this.canvasLength,0);
              this.context.stroke();
            })
            Button('旋转').onClick(()=>{
              this.context.rotate(45 * Math.PI / 180)
            })
            Button('放大*2').onClick(()=>{
              this.context.scale(2, 2) // Scale to 200%
            })
            Button('缩小*0.5').onClick(()=>{
              this.context.scale(0.5, 0.5)
            })
          }
          Row({space:10}){
            Button('绘制矩形框').onClick(()=>{
              // 左上角x,y 坐标 宽,高
              this.context.strokeRect(10, 10, 100, 50)
            })

            Button('填充矩形').onClick(()=>{
              this.context.lineWidth = 2;
              this.context.fillStyle  = Color.Red;
              // 左上角x,y 坐标 宽,高
              this.context.fillRect(120, 10, 100, 50)
            })

            Button('清空矩形区域').onClick(()=>{
              this.context.fillStyle = Color.Gray
              this.context.fillRect(20,20,200,200)
              this.context.clearRect(30,30,150,100)
            })

          }

          Row({space:10}){
            Button('绘制文本').onClick(()=>{
              // ctx.font='font-style font-weight font-size font-family'
              // 常规字体样式,常规粗细,字体大小为20vp,字体系列为sans-serif
              this.context.fillStyle  = Color.Red;
              this.context.font = 'normal normal 30vp sans-serif'
              this.context.fillText("HarmonyOS", this.canvasLength/2, this.canvasLength/2)
            })

            Button('水平对齐方式').onClick(()=>{
              //以绘制顶点平行于Y轴的参考线在文字水平方向的位置
              this.context.save()
              this.context.textAlign = 'end'
              this.context.fillStyle  = Color.Yellow;
              this.context.font = 'normal normal 30vp sans-serif'
              this.context.fillText('HarmonyOS', this.canvasLength/2, this.canvasLength/2)
              this.context.restore()
            })
            Button('垂直对齐方式').onClick(()=>{
              //以绘制顶点平行于X轴的参考线在文字垂直方向的位置
              this.context.save()
              this.context.textBaseline = 'middle'
              this.context.font = 'normal normal 30vp sans-serif'
              this.context.fillStyle  = Color.Blue;
              this.context.fillText('HarmonyOS',this.canvasLength/2, this.canvasLength/2)
              this.context.restore()
            })
          }
          Row({space:10}){
            Button('绘制弧线').onClick(()=>{
              this.context.beginPath()
              //参数  圆心x,y,弧线的圆半径,起始弧度,终止弧度
              this.context.arc(this.canvasLength/2, this.canvasLength/2, 100, 0, Math.PI)
              this.context.stroke()
            })

            Button('控制点和圆弧半径创建圆弧').onClick(()=>{
              // 起始点
              this.context.beginPath();
              this.context.fillStyle = '#00ff00';
              this.context.arc(280, 20, 4, 0, 2 * Math.PI);
              this.context.fill();

              // 控制点
              this.context.beginPath();
              this.context.fillStyle = '#ff0000';
              this.context.arc(280, 170, 4, 0, 2 * Math.PI);
              this.context.arc(110, 170, 4, 0, 2 * Math.PI);
              this.context.fill();

              // 切线
              this.context.beginPath()
              this.context.strokeStyle = '#808080'
              this.context.lineWidth = 1.5;
              this.context.moveTo(280, 20);
              this.context.lineTo(280, 170);
              this.context.lineTo(110, 170);
              this.context.stroke();

              // 圆弧
              this.context.beginPath()
              this.context.strokeStyle = '#000000'
              this.context.lineWidth = 3;
              this.context.moveTo(280, 20)
              this.context.arcTo(280, 170, 110, 170, 150)
              this.context.stroke()
            })
          }
          Row({space:10}){
            Button('绘制原图').onClick(()=>{
              this.context.drawImage(new ImageBitmap('resource://base/media/circle_bg_drafts.png'), 0, 0)
            })
            Button('200*50').onClick(()=>{
              this.context.drawImage(new ImageBitmap('resource://base/media/circle_bg_drafts.png'), 0, 80, 200, 50)
            })
            Button('裁剪中间区域').onClick(()=>{
              //图片资源后面8个参数的含义
              //裁切源图像时距离源图像左上角的x坐标值
              //裁切源图像时距离源图像左上角的y坐标值
              //裁切源图像时需要裁切的宽度
              //裁切源图像时需要裁切的高度
              //绘制区域左上角在x轴的位置
              //绘制区域左上角在y轴的位置
              //绘制区域的宽度
              //绘制区域的高度
              this.context.drawImage(new ImageBitmap('resource://base/media/circle_bg_drafts.png'),100, 0, 100, 100, 100, 150, 100, 100)
            })
          }

          Row(){
            Button('无滤镜').onClick(()=>{
              this.context.drawImage(this.img, 0, 0, 100, 100)
            })
            Button('高斯模糊').onClick(()=>{ //blur
              this.context.filter = 'blur(5px)'
              this.context.drawImage(this.img, 100, 0, 100, 100)
            })
            Button('更亮').onClick(()=>{  //brightness
              this.context.filter = 'brightness(1.4)'
              this.context.drawImage(this.img, 200, 0, 100, 100)
            })
            Button('对比度').onClick(()=>{ //contrast
              this.context.filter = 'contrast(200%)'
              this.context.drawImage(this.img, 0, 100, 100, 100)
            })

          }
          Row(){
            Button('饱和度').onClick(()=>{  //saturate
              this.context.filter = 'saturate(1.5)'
              this.context.drawImage(this.img, 100, 100, 100, 100)
            })
            Button('色相旋转').onClick(()=>{  //hue-rotate
              this.context.filter = 'hue-rotate(150deg)'
              this.context.drawImage(this.img, 200, 100, 100, 100)
            })
            Button('透明度').onClick(()=>{  //opacity
              this.context.filter = 'opacity(0.8)'
              this.context.drawImage(this.img, 0, 200, 100, 100)
            })
            Button('灰度图').onClick(()=>{  //grayscale
              this.context.filter = 'grayscale(0.5)'
              this.context.drawImage(this.img, 100, 200, 100, 100)
            })
            Button('组合').onClick(()=>{
              this.context.filter = 'opacity(0.8) contrast(200%) saturate(1.5)'
              this.context.drawImage(this.img, 200, 200, 100, 100)
            })
          }

          Text('图层管理')

          Row({space:10}){
            Button('清空').onClick(()=>{
              this.context.reset()
            })
            Button('绘制矩形1').onClick(()=>{
              this.context.fillStyle = "#0000ff"
              this.context.fillRect(50,100,300,150)
            })
            Button('绘制矩形2').onClick(()=>{

              this.context.fillStyle = "#ff0000"
              this.context.fillRect(100,50,150,300)
              this.context.restoreLayer()
            })
          }
          Row(){
            Text('source')
            Column({space:10}){
              Button('现有绘制内容上显示新绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'source-over'
                this.context.saveLayer()
              })
              Button('现有绘制内容顶部显示新绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'source-atop'
                this.context.saveLayer()
              })
              Button('现有绘制内容中显示新绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'source-in'
                this.context.saveLayer()
              })
              Button('现有绘制内容之外显示新绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'source-out'
                this.context.saveLayer()
              })
            }
          }.border({width:1})
          Row(){
            Text('destination')
            Column({space:10}){
              Button('新绘制内容上方显示现有绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'destination-over'
                this.context.saveLayer()
              })
              Button('新绘制内容顶部显示现有绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'destination-atop'
                this.context.saveLayer()
              })
              Button('新绘制内容中显示现有绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'destination-in'
                this.context.saveLayer()
              })
              Button('新绘制内容外显示现有绘制内容').onClick(()=>{
                this.context.globalCompositeOperation = 'destination-out'
                this.context.saveLayer()
              })
            }
          }.border({width:1})
          Column({space:10}){
            Button('lighter 显示新绘制内容和现有绘制内容').onClick(()=>{
              this.context.globalCompositeOperation = 'lighter'
              this.context.saveLayer()
            })
            Button('copy 显示新绘制内容而忽略现有绘制内容').onClick(()=>{
              this.context.globalCompositeOperation = 'copy'
              this.context.saveLayer()
            })
            Button('xor 使用异或操作对新绘制内容与现有绘制内容进行融合').onClick(()=>{
              this.context.globalCompositeOperation = 'xor'
              this.context.saveLayer()
            })
          }
        }

      }.layoutWeight(1)

    }.width('100%')
  }
}
收藏00

登录 后评论。没有帐号? 注册 一个。