Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
d9c7a1c5
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
6007
Star
91
Fork
164
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
18
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
18
Issue
18
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
d9c7a1c5
编写于
8月 06, 2024
作者:
H
hdx
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cavnas: 优化结构减少一些重复的逻辑
上级
75386779
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
103 addition
and
281 deletion
+103
-281
pages/component/canvas/canvas.test.js
pages/component/canvas/canvas.test.js
+7
-8
pages/component/canvas/canvas.uvue
pages/component/canvas/canvas.uvue
+96
-273
未找到文件。
pages/component/canvas/canvas.test.js
浏览文件 @
d9c7a1c5
...
...
@@ -25,22 +25,21 @@ describe('Canvas.uvue', () => {
})
it
(
"
测试异步创建canvas上下文
"
,
async
()
=>
{
await
page
.
callMethod
(
'
useAsync
'
);
const
element
=
await
page
.
$
(
'
#testCanvasContext
'
)
expect
(
await
element
.
text
()).
toBe
(
'
true
'
)
})
it
(
"
测试同步创建canvas上下文
"
,
async
()
=>
{
await
page
.
callMethod
(
'
useAsync
'
);
const
element
=
await
page
.
$
(
'
#testCanvasContext
'
)
// const element = await page.$('#testCanvasContext')
expect
(
await
element
.
text
()).
toBe
(
'
true
'
)
})
// it("测试同步创建canvas上下文", async () => {
// await page.callMethod('useAsync');
// const element = await page.$('#testCanvasContext')
// expect(await element.text()).toBe('true')
// })
it
(
'
测试 canvasToDataURL
'
,
async
()
=>
{
await
page
.
callMethod
(
'
canvasToDataURL
'
);
const
element
=
await
page
.
$
(
'
#testToDataURLResult
'
)
expect
(
await
element
.
text
()).
toBe
(
'
true
'
)
})
it
(
'
测试 createImage
'
,
async
()
=>
{
await
page
.
callMethod
(
'
drawImageAPI
'
);
await
page
.
callMethod
(
'
onCreateImage
'
);
await
page
.
waitFor
(
500
)
// 加载图片
const
element
=
await
page
.
$
(
'
#testCreateImage
'
)
expect
(
await
element
.
text
()).
toBe
(
'
true
'
)
...
...
pages/component/canvas/canvas.uvue
浏览文件 @
d9c7a1c5
...
...
@@ -6,8 +6,6 @@
<view>
<text style="padding: 8px 10px;">获取 CanvasContext</text>
</view>
<button class="canvas-drawing-button" id="useAsync" @click="useAsync">异步方式获取 CanvasContext</button>
<button class="canvas-drawing-button" id="useSync" @click="useSync">同步方式获取 CanvasContext</button>
<view class="text-group">
<text>获取 CanvasContext 结果:</text>
<text id="testCanvasContext">{{testCanvasContext}}</text>
...
...
@@ -33,7 +31,7 @@
<text>canvasToDataURL:</text>
<text>{{dataBase64.slice(0,22)}}...</text>
</view>
<button @click="
drawImageAPI
">createImage</button>
<button @click="
onCreateImage
">createImage</button>
<view style="padding: 8px 10px;">CanvasContext API 演示</view>
<view class="grid-view">
<view class="grid-item" v-for="(name, index) in names" :key="index">
...
...
@@ -55,7 +53,6 @@
context.scale(dpr, dpr);
}
export default {
data() {
const API_PATH = ["arc", "arcTo", "bezierCurveTo", "quadraticCurve", "moveTo", "lineTo", "rect", "clip", "pattern"]
...
...
@@ -66,7 +63,8 @@
return {
title: 'Context2D',
canvas: null as UniCanvasElement | null,
canvasContext: null as CanvasRenderingContext2D | null,
canvasContext: null as CanvasContext | null,
renderingContext: null as CanvasRenderingContext2D | null,
canvasWidth: 0,
canvasHeight: 0,
dataBase64: '',
...
...
@@ -75,100 +73,66 @@
testToBlobResult: false,
testToDataURLResult: false,
names: [...API_PATH, ...API_DRAW, ...API_STATE, ...API_PROPERTIES, "measureText"] as string[],
image: null as Image | null,
// 仅测试
testCreateCanvasContextAsyncSuccess: false,
testCreateImage: false
}
},
onReady() {
this.useAsync()
// HBuilderX 4.25+
// 异步调用方式, 跨平台写法
uni.createCanvasContextAsync({
id: 'canvas',
component: this,
success: (context : CanvasContext) => {
this.canvasContext = context;
this.renderingContext = context.getContext('2d')!;
this.canvas = this.renderingContext!.canvas;
hidpi(this.canvas!);
this.canvasWidth = this.canvas!.width;
this.canvasHeight = this.canvas!.height;
// #ifdef WEB
context.toBlob((blob : Blob) => {
this.testToBlobResult = (blob.size > 0 && blob.type == 'image/jpeg')
}, 'image/jpeg', 0.95)
// #endif
this.testToDataURLResult = context.toDataURL().startsWith('data:image/png;base64')
this.testCanvasContext = true
}
})
// 同步调用方式,仅支持 app/web
// let canvas = uni.getElementById("canvas") as UniCanvasElement
// this.renderingContext = canvas.getContext("2d")
// hidpi(canvas);
// this.canvas = canvas;
// this.canvasWidth = canvas.width;
// this.canvasHeight = canvas.height;
},
methods: {
// #ifdef WEB
canvasToBlob() {
this.canvas!.toBlob((blob : Blob) => {
this.canvas
Context
!.toBlob((blob : Blob) => {
this.testToBlobResult = (blob.size > 0 && blob.type == 'image/jpeg')
}, 'image/jpeg', 0.95)
},
// #endif
canvasToDataURL() {
this.dataBase64 = this.canvas!.toDataURL()
this.dataBase64 = this.canvas
Context
!.toDataURL()
},
drawImageAPI() {
uni.createCanvasContextAsync({
id: 'canvas',
success: (res : CanvasContext) => {
this.context = res.getContext('2d');
this.clearCanvasRect()
let image = res.createImage();
image.src = "../../static/logo.png"
image.onload = () => {
this.testCreateImage = true
this.context?.drawImage(image, 0, 0, 100, 100);
}
},
fail: (err : UniError) => {
console.log(err);
}
})
},
useAsync() {
// HBuilderX 4.25+
// 异步调用方式, 跨平台写法
uni.createCanvasContextAsync({
id: 'canvas',
component: this,
success: (context : CanvasContext) => {
const canvasContext = context.getContext('2d')!;
const canvas = canvasContext.canvas;
if (this.canvasContext == null) {
this.canvasContext = canvasContext
this.testCanvasContext = true
hidpi(canvas);
this.canvasWidth = canvas.width;
this.canvasHeight = canvas.height;
canvasContext.save()
}
this.measureText()
this.testToDataURLResult = canvas.toDataURL().startsWith('data:image/png;base64')
this.canvas = canvas;
}
})
},
useSync() {
let canvas = uni.getElementById("canvas") as UniCanvasElement
this.canvasContext = canvas.getContext("2d")
this.testCanvasContext = true
this.canvasContext!.save()
// hidpi(canvas);
this.canvasWidth = canvas.width;
this.canvasHeight = canvas.height;
this.arc()
// #ifdef WEB
canvas.toBlob((blob : Blob) => {
this.testToBlobResult = (blob.size > 0 && blob.type == 'image/jpeg')
}, 'image/jpeg', 0.95)
// #endif
this.testToDataURLResult = canvas.toDataURL().startsWith('data:image/png;base64')
this.canvas = canvas;
},
clearCanvasRect() {
this.canvasContext!.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
onCreateImage() {
// let image = this.canvasContext!.createImage();
// image.src = "../../static/logo.png"
// image.onload = () => {
// this.testCreateImage = true
// this.renderingContext?.drawImage(image, 0, 0, 100, 100);
// }
},
handleCanvasButton(name : string) {
this.renderingContext!.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
this.renderingContext!.save()
switch (name) {
case "arc":
this.arc();
...
...
@@ -295,12 +259,18 @@
default:
break;
}
this.renderingContext!.restore()
},
clearCanvasRect() {
this.renderingContext!.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
},
clearCanvasRectAndRestore() {
this.renderingContext!.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
// this.renderingContext!.restore()
},
arc() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.lineWidth = 2
context.arc(75, 75, 50, 0, Math.PI * 2, true)
...
...
@@ -311,14 +281,10 @@
context.moveTo(95, 65)
context.arc(90, 65, 5, 0, Math.PI * 2, true)
context.stroke()
context.restore()
},
arcTo() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.moveTo(150, 20)
context.arcTo(150, 100, 50, 20, 30)
...
...
@@ -342,14 +308,10 @@
context.beginPath()
context.arc(120, 38, 30, 0, 2 * Math.PI, true)
context.stroke()
context.restore()
},
beginPath() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// First path
context.beginPath()
context.strokeStyle = "blue"
...
...
@@ -363,14 +325,10 @@
context.moveTo(20, 20)
context.lineTo(120, 120)
context.stroke()
context.restore()
},
textAlign() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.moveTo(150, 0)
context.lineTo(150, 150)
...
...
@@ -386,14 +344,10 @@
context.textAlign = "right"
context.fillText("right-aligned", 150, 130)
context.restore()
},
bezierCurveTo() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.moveTo(50, 20)
context.bezierCurveTo(230, 30, 150, 60, 50, 100)
...
...
@@ -410,14 +364,10 @@
context.fillRect(230, 30, 10, 10)
// control point two
context.fillRect(150, 70, 10, 10)
context.restore()
},
clearRect() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// 绘制黄色背景
context.beginPath()
context.fillStyle = "#ff6"
...
...
@@ -434,14 +384,10 @@
// 清除一部分画布
context.clearRect(10, 10, 120, 100)
context.restore()
},
clip() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Create circular clipping region
context.beginPath();
context.arc(100, 75, 50, 0, Math.PI * 2, true)
...
...
@@ -452,14 +398,10 @@
context.fillRect(0, 0, 300, 150)
context.fillStyle = "orange"
context.fillRect(0, 0, 100, 100)
context.restore()
},
closePath() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.lineWidth = 10
context.moveTo(20, 20)
...
...
@@ -467,11 +409,9 @@
context.lineTo(70, 100)
context.closePath()
context.stroke()
context.restore()
},
pattern() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
const image = new Image(100, 100)
image.src = '../../../static/api.png';
...
...
@@ -485,10 +425,8 @@
};
},
createLinearGradient() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Create a linear gradient
// The start gradient point is at x=20, y=0
// The end gradient point is at x=220, y=0
...
...
@@ -502,14 +440,10 @@
// Set the fill style and draw a rectangle
context.fillStyle = gradient
context.fillRect(20, 20, 200, 100)
context.restore()
},
createRadialGradient() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Create a radial gradient
// The inner circle is at x=110, y=90, with radius=30
// The outer circle is at x=100, y=100, with radius=70
...
...
@@ -523,36 +457,24 @@
// Set the fill style and draw a rectangle
context.fillStyle = gradient
context.fillRect(20, 20, 160, 160)
context.restore()
},
fill() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.rect(20, 20, 150, 100)
context.strokeStyle = '#00ff00'
context.fill()
context.restore()
},
fillRect() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.fillStyle = "green"
context.fillRect(20, 10, 150, 100)
context.restore()
},
fillText() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.strokeStyle = '#ff0000'
context.beginPath()
...
...
@@ -573,77 +495,53 @@
context.moveTo(0, 30)
context.lineTo(300, 30)
context.stroke()
context.restore()
},
moveTo() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.moveTo(0, 0)
context.lineTo(300, 150)
context.stroke()
context.restore()
},
lineTo() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.moveTo(20, 20)
context.lineTo(20, 100)
context.lineTo(70, 100)
context.stroke()
context.restore()
},
stroke() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.moveTo(20, 20)
context.lineTo(20, 100)
context.lineTo(70, 100)
context.strokeStyle = '#00ff00'
context.stroke()
context.restore()
},
strokeRect() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.strokeStyle = "green"
context.strokeRect(20, 10, 160, 100)
context.restore()
},
strokeText() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.font = "10px serif"
context.strokeText("Hello world", 50, 90)
context.font = "30px serif"
context.strokeStyle = "blue"
context.strokeText("Hello world", 50, 100)
context.restore()
},
rotate() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Point of transform origin
context.arc(0, 0, 5, 0, 2 * Math.PI, true)
context.fillStyle = "blue"
...
...
@@ -659,14 +557,10 @@
// Reset transformation matrix to the identity matrix
context.setTransform(1, 0, 0, 1, 0, 0)
context.restore()
},
scale() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Scaled rectangle
context.scale(9, 3)
context.fillStyle = "red"
...
...
@@ -678,13 +572,9 @@
// Non-scaled rectangle
context.fillStyle = "gray"
context.fillRect(10, 10, 8, 20)
context.restore()
},
reset() {
const context = this.canvasContext!
context.save()
this.clearCanvasRect()
const context = this.renderingContext!
// Set line width
context.lineWidth = 10
...
...
@@ -696,7 +586,6 @@
context.font = "50px serif";
context.fillText("Rect!", 70, 110)
context.lineWidth = 5
// Stroke out circle
...
...
@@ -710,13 +599,10 @@
// context.reset()
hidpi(uni.getElementById("canvas") as UniCanvasElement)
context.restore()
},
translate() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Moved square
context.translate(110, 30)
context.fillStyle = "red"
...
...
@@ -728,13 +614,10 @@
// Unmoved square
context.fillStyle = "gray"
context.fillRect(0, 0, 80, 80)
context.restore()
},
save() {
const context = this.canvasContext!
this.clearCanvasRect()
context.save()
const context = this.renderingContext!
context.beginPath()
context.strokeStyle = '#00ff00'
context.scale(2, 2)
...
...
@@ -746,12 +629,10 @@
context.save()
context.rect(0, 0, 50, 50)
context.stroke()
context.restore()
},
restore() {
const context = this.
canvas
Context!;
this.clearCanvasRect();
const context = this.
rendering
Context!;
[3, 2, 1].forEach((item) => {
context.save()
context.beginPath()
...
...
@@ -762,8 +643,7 @@
})
},
drawImageLocal() {
const context = this.canvasContext!
this.clearCanvasRect()
const context = this.renderingContext!
const image = new Image(100, 100)
image.src = '../../../static/uni.png'
image.onload = () => {
...
...
@@ -771,8 +651,7 @@
}
},
drawImage() {
const context = this.canvasContext!
this.clearCanvasRect()
const context = this.renderingContext!
const image = new Image(100, 100);
image.src = 'https://web-ext-storage.dcloud.net.cn/uni-app-x/hello-uniappx-qrcode.png'
image.onload = () => {
...
...
@@ -780,21 +659,15 @@
}
},
rect() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.beginPath()
context.rect(20, 20, 150, 100)
context.stroke()
context.restore()
},
quadraticCurveTo() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Quadratic Bézier curve
context.beginPath()
context.moveTo(50, 20)
...
...
@@ -813,14 +686,10 @@
context.beginPath()
context.arc(230, 30, 5, 0, 2 * Math.PI, true)
context.fill()
context.restore()
},
resetTransform() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
// Draw a rotated rectangle
context.rotate((45 * Math.PI) / 180)
context.fillRect(60, 0, 100, 30)
...
...
@@ -829,52 +698,35 @@
context.resetTransform()
context.fillStyle = "red"
context.fillRect(60, 0, 100, 30)
context.restore()
},
transform() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.transform(1, 0.2, 0.8, 1, 0, 0)
context.fillRect(0, 0, 100, 100)
context.restore()
},
setFillStyle() {
const context = this.canvasContext!
context.save()
this.clearCanvasRect();
const context = this.renderingContext!;
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach((item : string, index : number) => {
context.fillStyle = item
context.beginPath()
context.rect(0 + 75 * index, 0, 50, 50)
context.fill()
})
context.restore()
},
setStrokeStyle() {
const context = this.
canvasContext!
const context = this.
renderingContext!;
context.save()
this.clearCanvasRect();
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach((item : string, index : number) => {
context.strokeStyle = item
context.beginPath()
context.rect(0 + 75 * index, 0, 50, 50)
context.stroke()
})
context.restore()
},
setGlobalAlpha() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.fillStyle = '#000000';
[1, 0.5, 0.1].forEach((item : number, index : number) => {
context.globalAlpha = item
...
...
@@ -883,25 +735,18 @@
context.fill()
})
context.globalAlpha = 1
context.restore()
},
setFontSize() {
const context = this.
canvasContext!
const context = this.
renderingContext!;
context.save();
[10, 20, 30, 40].forEach((item : number, index : number) => {
context.font = item + 'px serif'
context.fillText('Hello, world', 20, 20 + 40 * index)
})
context.restore()
},
setLineCap() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.lineWidth = 10;
['butt', 'round', 'square'].forEach((item : string, index : number) => {
context.beginPath()
...
...
@@ -910,14 +755,10 @@
context.lineTo(100, 20 + 20 * index)
context.stroke()
})
context.restore()
},
setLineJoin() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.lineWidth = 10;
['bevel', 'round', 'miter'].forEach((item : string, index : number) => {
context.beginPath()
...
...
@@ -927,14 +768,10 @@
context.lineTo(20 + 80 * index, 100)
context.stroke()
})
context.restore()
},
setLineWidth() {
const context = this.
canvasContext!
const context = this.
renderingContext!;
context.save()
this.clearCanvasRect();
[2, 4, 6, 8, 10].forEach((item : number, index : number) => {
context.beginPath()
context.lineWidth = item
...
...
@@ -942,14 +779,10 @@
context.lineTo(100, 20 + 20 * index)
context.stroke()
})
context.restore()
},
lineDash() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save();
this.clearCanvasRect()
context.setLineDash([4, 16])
// Dashed line with no offset
...
...
@@ -965,14 +798,10 @@
context.moveTo(0, 100)
context.lineTo(300, 100)
context.stroke()
context.restore()
},
setMiterLimit() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
context.lineWidth = 4;
[2, 4, 6, 8, 10].forEach((item : number, index : number) => {
context.beginPath()
...
...
@@ -982,14 +811,10 @@
context.lineTo(20 + 80 * index, 100)
context.stroke()
})
context.restore()
},
measureText() {
const context = this.
canvas
Context!
const context = this.
rendering
Context!
context.save()
this.clearCanvasRect()
const text = "uni-app x,是下一代 uni-app,是一个跨平台应用开发引擎"
context.font = "20px 宋体"
...
...
@@ -999,8 +824,6 @@
const textMetrics = context.measureText(text)
context.strokeText(text, 40, 100)
context.fillText("measure text width:" + textMetrics.width, 40, 80)
context.restore()
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录