canvas 是 Ark 的组件,罕用于自定义量绘制、绘制 UI、其灵便等长处,被宽泛开发框架内的 UI 开发。
一、画布介绍
- 什么是画布?
在 Web 浏览器中,画布是一个可自定义的宽度、高度的正方形画,画布左上角为坐标原点,以布为单位,程度为 x 轴,垂直向上为 y 轴,布内所有元素的如图 1 所示,咱们画出了一个宽度 = 1500px,高度 = 900px 的空白布,还须要笔”轻描绘出。渲染机制,JS 为“笔画”管制布图,以实现间接绘制画面。
图 1 画布画布
- canvas 的“画笔”
画布自身尽管不具备绘制能力,实现获取具备“笔”的办法。3D 图像绘制。
目前,开发者中的图像 WebGL2.3DGL2 能力正在欠缺中,所以 0D 帧规范介绍 2D 的画面,是物体渲染上下文 2D 的图像。0 及 Web2 显示的局部是对象渲染上下文 2D 的局部 2 图像办法,A 绘制文本的办法让开发者可能绘制出正方形、图片、等。
图 2 图像提取办法
另外,开发者还能够将上下文 2D 对象进行脱离渲染的开发方式。绘图办法能够同受骗放的比较复杂的屏幕渲染。Canvas 会删除重绘时的场景,很多时候能够依据本人的需要来获取画布的渲染。内容,灵便的开发者能够依据本人的需要通过提供者来到屏幕出现的形式,创立作为一个作品,而后将须要先将屏幕外的 Canvas 画在屏幕上,再将屏幕外的 Canvas 拖到主布上,进步画布性能,绘图以品质。
二、画布根底绘制办法
通过上节对 canvas 组件的根本介绍,大家对 canvas 组件有肯定的意识,咱们曾经在基于 Web 浏览器中应用 Web 开发框架中的理论应用程序 UI 浏览器中的办法。设计,并在“类 Web”及“申明式开发式”中进行提供,而后咱们将介绍不同的开发式中画布的应用。
- 开发范式中画布的画法类 Web
WebWebWebWebWebMLML 文件进行基于类的形容,并通过 CSS 文件的示例解决,并通过 CSS 文件进行开发款式进行语言形容。JS 语言的 canvas 组件根底应用办法。
(1)方形填充
Canvasing 提供 fillRect (x, y, width,height) 用于,在上下文中增加一个填充物上所设置的正方形的上角绝对(原点)的尺寸,宽度和高度则有一个正方形的尺寸。
图 3 填充的方形
示例代码如下:
// 创立一个 width=1500px,height=900px 的画布
<!-- xxx.hml -->
<div>
<canvas ref="canvas" style="width: 1500px; height: 900px;"></canvas>
</div>
//xxx.js
export default {onShow() {
const el =this.$refs.canvas;
// 获取 2D 绘制对象
const ctx = el.getContext('2d');
// 设置填充为彩色
ctx.fillStyle = '#000000';
// 设置填充矩形的坐标及尺寸
ctx.fillRect(200, 200, 300, 300);
}
}
(2)缩放与抱着
Canvas Context2scale(xD,参数 x 示意缩放比例的缩放数字,纵向示意缩放的缩放数字),缩放过程中的缩放比例。,通过上个 办法缩放示例中的填充正方形(2,1.5)进行缩放,并通过暗影含糊加上拖后的成果。
图 4 缩放与增加抱后的成果
示例代码如下:
//xxx.js
export default {onShow() {
const el =this.$refs.canvas;
const ctx = el.getContext('2d');
// 设置绘制暗影的含糊级别
ctx.shadowBlur = 80;
ctx.shadowColor = 'rgb(0,0,0)';
ctx.fillStyle = 'rgb(0,0,0)';
// x Scale to 200%,y Scale to 150%
ctx.scale(2, 1.5);
ctx.fillRect(200, 200, 300, 300);
}
}
- 开发式中 canvas 的申明绘制办法
采纳 TS 语言并申明式 UI 扩大语法,从组件、动效和治理三个维度提供了款式式的 UI。目前,e TS 语言曾经提供了画布式绘图能力,但始终完满地实现了绘图能力上面咱们将通过两个示例,展现申明式开发范式中 canvas 组件的根底应用办法。
(1)图片
5 张演示文稿,图片是主动笼罩的效果图,是通过图片主动笼罩的图片。原来的图像,实在后果。
图 5 图片
扩大的 TS 采纳更靠近天然开发者的语言编程形式,让代码地形容 UI 界面示例形式如下:
@Entry
@Component
struct IndexCanvas1 {private settings:RenderingContextSettings = new RenderingContextSettings(true);
// 获取绘图对象
private ctx: RenderingContext = new RenderingContext(this.settings);
// 列出所要用到的图片
private img:ImageBitmap = new ImageBitmap("common/bg.jpg");
build() {Column() {
// 创立 canvas
Canvas(this.ctx)
.width(1500)
.height(900)
.border({color:"blue",width:1,})
.backgroundColor('#ffff00')
// 开始绘制
.onReady(() => {this.ctx.drawImage( this.img,400,200,540,300);
this.ctx.drawImage(this.img,500,300,540,300);
this.ctx.drawImage(this.img,600,400,540,300);
})
}
.width('100%')
.height('100%')
}
}
(2)点击创立线性排列
6 个演示文稿,中是一个线性按钮扩大效果器。基于画布的按钮是一个组件,通过点击“点击”,触发点击(点击),并通过本发明调用 createLinearGradient() 办法,绘制一个按钮线性变动色。
图 6 图片上增加文字
示例代码如下:
@Entry
@Component
struct GradientExample {private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: RenderingContext = new RenderingContext(this.settings);
private gra: CanvasGradient = new CanvasGradient();
build() {Column({ space: 5}) {
// 创立一个画布
Canvas(this.context)
.width(1500)
.height(900)
.backgroundColor('#ffff00')
Column() {
// 设置按钮的款式
Button('Click').width(250).height(100).backgroundColor('#000000')
.onClick(() => {
// 创立一个线性渐变色
var grad = this.context.createLinearGradient(600, 200, 400, 750)
grad.addColorStop(0.0, 'red');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1.0, 'green');
this.context.fillStyle = grad;
this.context.fillRect(400, 200, 550, 550);
})
}.alignItems(HorizontalAlign.center)
}
}
}
三、飞机大战小游戏绘画实际
7 经典的演示,是一款相似“飞机”的小游戏,通过游戏控制机的挪动方舟开发战机。如何应用 UI 组件框架实现简略的实现代码的小游戏及敌方游戏的关键点
图 7 飞机大战小游戏
1. 首先游戏所用的图片。
private imgList:Array<string> = ["xx.png","xx.png"…];
2. 将图片渲染到 canvas 画布上。
let img:ImageBitmap = new ImageBitmap("图片门路(如 common/images)/"+this.imgList[ 数组下标]);
this.ctx.drawImage(img,150/* x 坐标 */, 150/* y 坐标 */, 600/* 宽 */, 600/* 高 */)
3. 绘制背景的图片和战机减少挪动成果。
this.ctx.drawImage(this.bg, 0, this.bgY);
this.ctx.drawImage(this.bg, 0, this.bgY - 480);
this.bgY++ == 480 && (this.bgY = 0);
-
应用 Math.round 游戏更改随时获取敌机图片并渲染到布上。并且敌机 Y 轴坐标,等级静止。
Efight = Math.round(Math.random()*7); // 前七张为敌机图片。let img:ImageBitmap = new ImageBitmap("common/img"+this.imgList[Efight]); this.ctx.drawImage(img, 0, this.Eheight + 50);// 渲染敌机
-
每年呈现 120 颗子弹,而后在一颗或几颗(x,y)轴的子弹射出。
let i= 0; setInterval(()=>{this.ctx.drawImage(this.bulImg1,image.x – 10 – (i *10) , image.x + (i *10)) this.ctx.drawImage(this.bulimg2, this. bulImg1,image.x – (i *10) , i image.x + (i *10)) this.ctx.drawImage(this.bulimg3, image.x + 10 + (i *10), image.x + (i *10)) i ++; },120)
6. 应用战机挪动地位,让战机近距离的近距离接触,让战机近距离接触近距离接触成果。
.onTouch((event)=>{var offsetX = event.localX ||event.touches[0].localX;
var offsetY = event.localY ||event.touches[0].localY;
var w = this.heroImg[0].width,
h = this.heroImg[0].height;
var nx = offsetX - w / 2,
ny = offsetY - h / 2;
nx < 20 - w / 2 ? nx = 20 - w / 2 : nx > (this.windowWidth - w / 2 - 20) ? nx =
(this.windowWidth - w / 2 - 20) : 0;
ny < 0 ? ny = 0 : ny > (this.windowHeight - h / 2) ? ny = (this.windowHeight –
h/2) : 0;
this.hero.x = nx;
this.hero.y = ny;
this.hero.count = 2;
注:本示例援用了局部开源资源:https://github.com/xs528/game,资源的开发者可在此开源,联合文中的实现思路补全代码。
更多开发者能够通过 canvas 组件的办法绘制本期能够出本期的精美图片,点击链接“浏览原文”到官网进行学习。