1. 基础语法
@Entry
@Component
struct CanvasCase {
@State message: string = 'Hello World';
private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D()
// 绘制线条
drawLine() {
// 1. 绘制线条, 绘制思路相当于svg中的path路径绘制,可以有n个lineTo
this.canvasContext.beginPath()
// 绘制参数 --- start ---
this.canvasContext.moveTo(100, 100)
this.canvasContext.lineTo(200, 200)
this.canvasContext.strokeStyle = '#0000ff'
this.canvasContext.lineWidth = 5
// 绘制参数 --- end ---
this.canvasContext.stroke() // 开始绘制
this.canvasContext.closePath()
}
// 绘制矩形
drawRect() {
this.canvasContext.beginPath()
this.canvasContext.fillRect(30, 30, 100, 100) // 绘制填充矩形
this.canvasContext.strokeStyle = '#f52'
this.canvasContext.strokeRect(300, 100, 50, 50) // 绘制边框矩形\
this.canvasContext.closePath()
}
// 绘制圆
drawCircle() {
this.canvasContext.beginPath()
this.canvasContext.strokeStyle = '#ff0000'
// 绘制:圆,圆弧,扇形,圆环
this.canvasContext.arc(200, 100, 50, 0, 360)
this.canvasContext.stroke()
this.canvasContext.closePath()
this.canvasContext.beginPath()
this.canvasContext.arc(100, 300, 50, 0, 90)
this.canvasContext.stroke()
this.canvasContext.closePath()
}
// 绘制文字
drawText() {
this.canvasContext.beginPath()
this.canvasContext.font = '30px sans-serif'
this.canvasContext.strokeText('Hello 默语', 330, 330)
this.canvasContext.fillText('Hello 默语', 300, 300)
this.canvasContext.closePath()
}
// 绘制贝塞尔曲线
drawBezierCurve() {
this.canvasContext.beginPath()
this.canvasContext.strokeStyle = '#ff00ff'
this.canvasContext.bezierCurveTo(80, 50, 180, 129, 267, 30);
this.canvasContext.stroke()
this.canvasContext.closePath()
}
// 绘制图片
drawImage() {
this.canvasContext.beginPath()
this.canvasContext.drawImage(new ImageBitmap('assests/YuanShen2024.png'), 0, 0)
this.canvasContext.closePath()
}
build() {
Column() {
Canvas(this.canvasContext).width('100%').aspectRatio(1).backgroundColor('#fff')
.onReady(() => {
this.drawLine()
this.drawRect()
this.drawCircle()
this.drawBezierCurve()
this.drawText()
this.drawImage()
})
}
.height('100%')
.width('100%')
.backgroundColor(Color.Red)
}
}
2. 绘制签字版并保存至沙箱
import fileIo from '@ohos.file.fs'
import { buffer } from '@kit.ArkTS'
import { promptAction } from '@kit.ArkUI'
@Entry
@Component
struct SignBoardCase {
private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D()
@State canvasWidth: number = 0 // 画布宽度
@State canvasHeight: number = 0 // 画布高度
@State imagePath: string = '' // 沙箱读取的图片资源
build() {
Column({ space: 20 }) {
Canvas(this.canvasContext)
.width('100%')
.aspectRatio(1)
.backgroundColor(Color.Pink)
.onAreaChange((oldValue, newValue) => {
this.canvasWidth = newValue.width as number
this.canvasHeight = newValue.height as number
})
.onTouch((event) => {
// 写入数据
if (event.type === TouchType.Down) {
this.canvasContext.beginPath()
this.canvasContext.moveTo(event.touches[0].x, event.touches[0].y)
this.canvasContext.strokeStyle = 2
} else if (event.type === TouchType.Up) {
this.canvasContext.closePath()
} else if (event.type === TouchType.Move) {
this.canvasContext.lineTo(event.touches[0].x, event.touches[0].y)
this.canvasContext.stroke()
}
})
Row({ space: 10 }) {
Button('重置').onClick(() => {
this.canvasContext.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
})
Button('保存').onClick(() => {
try {
const imageUrl = this.canvasContext.toDataURL() // 将签字版转化为base64格式图片
const filePath = getContext().filesDir + '/' + Date.now() + 'name.png'
const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE) // 打开文件
const reg = new RegExp("data:image/\\w+;base64,")
const base64 = imageUrl.replace(reg, ""); // 将base64图片前面的替换为空
const dataBuffer = buffer.from(base64, 'base64') // 转化为buffer对象
fileIo.writeSync(file.fd, dataBuffer.buffer) // 存数据
fileIo.closeSync(file); // 关闭文件
this.imagePath = filePath
promptAction.showToast({
message: '保存成功'
})
} catch (e) {
promptAction.showDialog({
message: '保存失败,请重试'
})
}
})
}
if (this.imagePath !== '') {
Image('file://' + this.imagePath).width('80%').aspectRatio(1)
}
}
.height('100%')
.width('100%')
}
}