写点什么

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

作者:auhgnixgnahz
  • 2025-06-25
    北京
  • 本文字数:5497 字

    阅读完需:约 18 分钟

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




源码:


@Entry@ComponentV2struct 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%') }}
复制代码


发布于: 刚刚阅读数: 3
用户头像

auhgnixgnahz

关注

还未添加个人签名 2018-07-10 加入

欢迎关注:HarmonyOS开发笔记

评论

发布
暂无评论
鸿蒙Next画布Canvas基础使用演示_鸿蒙Next_auhgnixgnahz_InfoQ写作社区