提交 e708b2d4 编写于 作者: DCloud-WZF's avatar DCloud-WZF 💬

refactor: 代码格式化

上级 d8ff71f3
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<button @click="startRequestAnimationFrame">requestAnimationFrame</button> <button @click="startRequestAnimationFrame">requestAnimationFrame</button>
<button @click="stopRequestAnimationFrame">cancelAnimationFrame</button> <button @click="stopRequestAnimationFrame">cancelAnimationFrame</button>
<text class="frame-count">FPS: {{FPSString}}</text> <text class="frame-count">FPS: {{FPSString}}</text>
<text class="frame-count">FrameCount: {{testFrameCount}}</text> <text class="frame-count">FrameCount: {{testFrameCount}}</text>
<text class="tips">提示: 在当前测试例子中,每增加一次调用 requestAnimationFrame 帧率翻倍,cancelAnimationFrame 后恢复</text> <text class="tips">提示: 在当前测试例子中,每增加一次调用 requestAnimationFrame 帧率翻倍,cancelAnimationFrame 后恢复</text>
</view> </view>
</template> </template>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
data() { data() {
return { return {
title: 'AnimationFrame', title: 'AnimationFrame',
taskId: 0, taskId: 0,
FPSString: '- / -ms', FPSString: '- / -ms',
lastTime: 0, lastTime: 0,
frameCount: 0, frameCount: 0,
...@@ -29,25 +29,25 @@ ...@@ -29,25 +29,25 @@
methods: { methods: {
startRequestAnimationFrame() { startRequestAnimationFrame() {
this.taskId = requestAnimationFrame((timestamp : number) => { this.taskId = requestAnimationFrame((timestamp : number) => {
this.updateFPS(timestamp) this.updateFPS(timestamp)
this.testFrameCount++ this.testFrameCount++
this.startRequestAnimationFrame() this.startRequestAnimationFrame()
}) })
}, },
stopRequestAnimationFrame() { stopRequestAnimationFrame() {
cancelAnimationFrame(this.taskId) cancelAnimationFrame(this.taskId)
this.lastTime = 0 this.lastTime = 0
this.frameCount = 0 this.frameCount = 0
this.FPSString = '- / -ms' this.FPSString = '- / -ms'
}, },
updateFPS(timestamp : number) { updateFPS(timestamp : number) {
this.frameCount++ this.frameCount++
if (timestamp - this.lastTime >= 1000) { if (timestamp - this.lastTime >= 1000) {
const timeOfFrame = (1000 / this.frameCount) const timeOfFrame = (1000 / this.frameCount)
this.FPSString = `${this.frameCount} / ${timeOfFrame.toFixed(3)}ms` this.FPSString = `${this.frameCount} / ${timeOfFrame.toFixed(3)}ms`
this.frameCount = 0 this.frameCount = 0
this.lastTime = timestamp this.lastTime = timestamp
} }
} }
} }
} }
...@@ -60,11 +60,11 @@ ...@@ -60,11 +60,11 @@
.frame-count { .frame-count {
margin-top: 15px; margin-top: 15px;
} }
.tips { .tips {
font-size: 12px; font-size: 12px;
margin-top: 30px; margin-top: 30px;
opacity: 0.7; opacity: 0.7;
} }
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view class="page-scroll-view"> <scroll-view class="page-scroll-view">
<!-- #endif --> <!-- #endif -->
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-common-mt"> <view class="uni-common-mt">
<view class="uni-list"> <view class="uni-list">
<view class="uni-list-cell cell-pd"> <view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label"> <view class="uni-list-cell-left uni-label">
图片来源 图片来源
</view> </view>
<view class="uni-list-cell-right" @click="chooseImageSource"> <view class="uni-list-cell-right" @click="chooseImageSource">
<text class="click-t">{{sourceType[sourceTypeIndex]}}</text> <text class="click-t">{{sourceType[sourceTypeIndex]}}</text>
</view> </view>
</view> </view>
<view class="uni-list-cell cell-pd"> <view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label"> <view class="uni-list-cell-left uni-label">
图片质量 图片质量
</view> </view>
<view class="uni-list-cell-right" @click="chooseImageType"> <view class="uni-list-cell-right" @click="chooseImageType">
<text class="click-t">{{sizeType[sizeTypeIndex]}}</text> <text class="click-t">{{sizeType[sizeTypeIndex]}}</text>
</view> </view>
</view> </view>
<view class="uni-list-cell cell-pd"> <view class="uni-list-cell cell-pd">
<view class="uni-list-cell-left uni-label"> <view class="uni-list-cell-left uni-label">
数量限制 数量限制
</view> </view>
<view class="uni-list-cell-right"> <view class="uni-list-cell-right">
<input class="click-t" :value="countIndex+1" type="number" :maxlength="1" @confirm="chooseImageCount" confirm-type="done" /> <input class="click-t" :value="countIndex+1" type="number" :maxlength="1" @confirm="chooseImageCount"
</view> confirm-type="done" />
</view> </view>
<view class="uni-list-cell cell-pd"> </view>
<view class="uni-list-cell-left uni-label"> <view class="uni-list-cell cell-pd">
图像裁剪 <view class="uni-list-cell-left uni-label">
</view> 图像裁剪
<view class="uni-list-cell-right"> </view>
<switch :checked="isCrop" @change="switchCrop"></switch> <view class="uni-list-cell-right">
</view> <switch :checked="isCrop" @change="switchCrop"></switch>
</view> </view>
<view ref="cropOptionNode" class="crop-option" :style="{'height':isCrop?'200px':'0px','margin-bottom':isCrop?'11px':'0px'}"> </view>
<view class="uni-list-cell cell-pd"> <view ref="cropOptionNode" class="crop-option"
<view class="uni-list-cell-left item_width"> :style="{'height':isCrop?'200px':'0px','margin-bottom':isCrop?'11px':'0px'}">
图片质量(%) <view class="uni-list-cell cell-pd">
</view> <view class="uni-list-cell-left item_width">
<view class="uni-list-cell-right"> 图片质量(%)
<input :value="cropPercent" @confirm="cropPercentConfim" type="number" maxlength="-1"/> </view>
</view> <view class="uni-list-cell-right">
</view> <input :value="cropPercent" @confirm="cropPercentConfim" type="number" maxlength="-1" />
<view class="uni-list-cell cell-pd"> </view>
<view class="uni-list-cell-left item_width"> </view>
裁剪宽度(px) <view class="uni-list-cell cell-pd">
</view> <view class="uni-list-cell-left item_width">
<view class="uni-list-cell-right"> 裁剪宽度(px)
<input :value="cropWidth" @confirm="cropWidthConfim" type="number" maxlength="-1"/> </view>
</view> <view class="uni-list-cell-right">
</view> <input :value="cropWidth" @confirm="cropWidthConfim" type="number" maxlength="-1" />
<view class="uni-list-cell cell-pd"> </view>
<view class="uni-list-cell-left item_width"> </view>
裁剪高度(px) <view class="uni-list-cell cell-pd">
</view> <view class="uni-list-cell-left item_width">
<view class="uni-list-cell-right"> 裁剪高度(px)
<input :value="cropHeight" @confirm="cropHeightConfim" type="number" maxlength="-1"/> </view>
</view> <view class="uni-list-cell-right">
</view> <input :value="cropHeight" @confirm="cropHeightConfim" type="number" maxlength="-1" />
<view class="uni-list-cell cell-pd"> </view>
<view class="uni-list-cell-left item_width"> </view>
保留原宽高 <view class="uni-list-cell cell-pd">
</view> <view class="uni-list-cell-left item_width">
<view class="uni-list-cell-right"> 保留原宽高
<switch :checked="cropResize" @change="cropResizeChange"></switch> </view>
</view> <view class="uni-list-cell-right">
</view> <switch :checked="cropResize" @change="cropResizeChange"></switch>
</view> </view>
</view> </view>
</view>
<view class="uni-list list-pd" style="padding: 15px;"> </view>
<view class="uni-flex" style="margin-bottom: 10px;">
<view class="uni-list-cell-left">点击可预览选好的图片</view> <view class="uni-list list-pd" style="padding: 15px;">
<view style="margin-left: auto;"> <view class="uni-flex" style="margin-bottom: 10px;">
<text class="click-t">{{imageList.length}}/{{countIndex+1}}</text> <view class="uni-list-cell-left">点击可预览选好的图片</view>
</view> <view style="margin-left: auto;">
</view> <text class="click-t">{{imageList.length}}/{{countIndex+1}}</text>
<view class="uni-flex" style="flex-wrap: wrap;"> </view>
<view v-for="(image,index) in imageList" :key="index" class="uni-uploader__input-box" style="border: 0;"> </view>
<image style="width: 104px; height: 104px;" :src="image" :data-src="image" @tap="previewImage(index)"> <view class="uni-flex" style="flex-wrap: wrap;">
</image> <view v-for="(image,index) in imageList" :key="index" class="uni-uploader__input-box" style="border: 0;">
<image src="/static/plus.png" class="image-remove" @click="removeImage(index)"></image> <image style="width: 104px; height: 104px;" :src="image" :data-src="image" @tap="previewImage(index)">
</view> </image>
<image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image> <image src="/static/plus.png" class="image-remove" @click="removeImage(index)"></image>
</view> </view>
</view> <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image>
</view> </view>
</view> </view>
<!-- #ifdef APP --> </view>
</scroll-view> </view>
<!-- #endif --> <!-- #ifdef APP -->
</template> </scroll-view>
<!-- #endif -->
<script> </template>
var sourceTypeArray = [
['camera'], <script>
['album'], var sourceTypeArray = [
['camera', 'album'] ['camera'],
] ['album'],
var sizeTypeArray = [ ['camera', 'album']
['compressed'], ]
['original'], var sizeTypeArray = [
['compressed', 'original'] ['compressed'],
] ['original'],
export default { ['compressed', 'original']
data() { ]
return { export default {
title: 'chooseImage', data() {
imageList: [] as Array<string>, return {
sourceTypeIndex: 2, title: 'chooseImage',
sourceType: ['拍照', '相册', '拍照或相册'], imageList: [] as Array<string>,
sizeTypeIndex: 2, sourceTypeIndex: 2,
sizeType: ['压缩', '原图', '压缩或原图'], sourceType: ['拍照', '相册', '拍照或相册'],
countIndex: 8, sizeTypeIndex: 2,
count: [1, 2, 3, 4, 5, 6, 7, 8, 9], sizeType: ['压缩', '原图', '压缩或原图'],
isCrop: false, countIndex: 8,
cropPercent: 80, count: [1, 2, 3, 4, 5, 6, 7, 8, 9],
cropWidth: 100, isCrop: false,
cropHeight: 100, cropPercent: 80,
cropResize: false cropWidth: 100,
} cropHeight: 100,
}, cropResize: false
onUnload() { }
this.imageList = []; },
this.sourceTypeIndex = 2 onUnload() {
this.sourceType = ['拍照', '相册', '拍照或相册'] this.imageList = [];
this.sizeTypeIndex = 2 this.sourceTypeIndex = 2
this.sizeType = ['压缩', '原图', '压缩或原图'] this.sourceType = ['拍照', '相册', '拍照或相册']
this.countIndex = 8 this.sizeTypeIndex = 2
}, this.sizeType = ['压缩', '原图', '压缩或原图']
methods: { this.countIndex = 8
cropHeightConfim(e : InputConfirmEvent) { },
let value = parseInt(e.detail.value) methods: {
if (value > 0) { cropHeightConfim(e : InputConfirmEvent) {
this.cropHeight = value let value = parseInt(e.detail.value)
} else { if (value > 0) {
uni.showToast({ this.cropHeight = value
position: "bottom", } else {
title: "裁剪高度需要大于0" uni.showToast({
}) position: "bottom",
} title: "裁剪高度需要大于0"
}, })
cropWidthConfim(e : InputConfirmEvent) { }
let value = parseInt(e.detail.value) },
if (value > 0) { cropWidthConfim(e : InputConfirmEvent) {
this.cropWidth = value let value = parseInt(e.detail.value)
} else { if (value > 0) {
uni.showToast({ this.cropWidth = value
position: "bottom", } else {
title: "裁剪宽度需要大于0" uni.showToast({
}) position: "bottom",
} title: "裁剪宽度需要大于0"
}, })
cropPercentConfim(e : InputConfirmEvent) { }
let value = parseInt(e.detail.value) },
if (value > 0 && value <= 100) { cropPercentConfim(e : InputConfirmEvent) {
this.cropPercent = value let value = parseInt(e.detail.value)
} else { if (value > 0 && value <= 100) {
uni.showToast({ this.cropPercent = value
position: "bottom", } else {
title: "请输入0~100之间的值" uni.showToast({
}) position: "bottom",
} title: "请输入0~100之间的值"
}, })
cropResizeChange(e : UniSwitchChangeEvent) { }
this.cropResize = e.detail.value },
}, cropResizeChange(e : UniSwitchChangeEvent) {
switchCrop(e : UniSwitchChangeEvent) { this.cropResize = e.detail.value
this.isCrop = e.detail.value },
}, switchCrop(e : UniSwitchChangeEvent) {
removeImage(index : number) { this.isCrop = e.detail.value
this.imageList.splice(index, 1) },
}, removeImage(index : number) {
chooseImageSource() { this.imageList.splice(index, 1)
uni.showActionSheet({ },
itemList: ['拍照', '相册', '拍照或相册'], chooseImageSource() {
success: (e) => { uni.showActionSheet({
this.sourceTypeIndex = e.tapIndex! itemList: ['拍照', '相册', '拍照或相册'],
} success: (e) => {
}) this.sourceTypeIndex = e.tapIndex!
}, }
chooseImageType() { })
uni.showActionSheet({ },
itemList: ['压缩', '原图', '压缩或原图'], chooseImageType() {
success: (e) => { uni.showActionSheet({
this.sizeTypeIndex = e.tapIndex! itemList: ['压缩', '原图', '压缩或原图'],
} success: (e) => {
}) this.sizeTypeIndex = e.tapIndex!
}, }
chooseImageCount(event : InputConfirmEvent) { })
let count = parseInt(event.detail.value) - 1 },
if (count < 0) { chooseImageCount(event : InputConfirmEvent) {
uni.showToast({ let count = parseInt(event.detail.value) - 1
position: "bottom", if (count < 0) {
title: "图片数量应该大于0" uni.showToast({
}) position: "bottom",
return title: "图片数量应该大于0"
} })
this.countIndex = count return
}, }
chooseImage: function () { this.countIndex = count
// var cropOption:ChooseImageCropOptions|null = this.isCrop ? null : new ChooseImageCropOptions( ) },
if (this.imageList.length >= 9) { chooseImage: function () {
uni.showToast({ // var cropOption:ChooseImageCropOptions|null = this.isCrop ? null : new ChooseImageCropOptions( )
position: "bottom", if (this.imageList.length >= 9) {
title: "已经有9张图片了,请删除部分图片之后重新选择" uni.showToast({
}) position: "bottom",
return title: "已经有9张图片了,请删除部分图片之后重新选择"
} })
uni.chooseImage({ return
sourceType: sourceTypeArray[this.sourceTypeIndex], }
sizeType: sizeTypeArray[this.sizeTypeIndex], uni.chooseImage({
crop: this.isCrop ? { "quality": this.cropPercent, "width": this.cropWidth, "height": this.cropHeight, "resize": this.cropResize } as ChooseImageCropOptions : null, sourceType: sourceTypeArray[this.sourceTypeIndex],
count: this.imageList.length + this.count[this.countIndex] > 9 ? 9 - this.imageList.length : this.count[this.countIndex], sizeType: sizeTypeArray[this.sizeTypeIndex],
success: (res) => { crop: this.isCrop ? { "quality": this.cropPercent, "width": this.cropWidth, "height": this.cropHeight, "resize": this.cropResize } as ChooseImageCropOptions : null,
this.imageList = this.imageList.concat(res.tempFilePaths); count: this.imageList.length + this.count[this.countIndex] > 9 ? 9 - this.imageList.length : this.count[this.countIndex],
}, success: (res) => {
fail: (err) => { this.imageList = this.imageList.concat(res.tempFilePaths);
console.log("err: ", JSON.stringify(err)); },
} fail: (err) => {
}) console.log("err: ", JSON.stringify(err));
}, }
previewImage: function (index : number) { })
uni.previewImage({ },
current: index, previewImage: function (index : number) {
urls: this.imageList uni.previewImage({
}) current: index,
} urls: this.imageList
} })
} }
</script> }
}
<style> </script>
.cell-pd {
padding: 11px 15px; <style>
} .cell-pd {
padding: 11px 15px;
.click-t { }
color: darkgray;
} .click-t {
color: darkgray;
.list-pd { }
margin-top: 25px;
} .list-pd {
margin-top: 25px;
.uni-uploader__input-box { }
margin: 5px;
width: 104px; .uni-uploader__input-box {
height: 104px; margin: 5px;
border: 1px solid #D9D9D9; width: 104px;
} height: 104px;
border: 1px solid #D9D9D9;
.uni-uploader__input { }
position: absolute;
z-index: 1; .uni-uploader__input {
top: 0; position: absolute;
left: 0; z-index: 1;
width: 100%; top: 0;
height: 100%; left: 0;
opacity: 0; width: 100%;
} height: 100%;
opacity: 0;
.image-remove { }
transform: rotate(45deg);
width: 25px; .image-remove {
height: 25px; transform: rotate(45deg);
position: absolute; width: 25px;
top: 0; height: 25px;
right: 0; position: absolute;
border-radius: 13px; top: 0;
background-color: rgba(200, 200, 200, 0.8); right: 0;
} border-radius: 13px;
background-color: rgba(200, 200, 200, 0.8);
.item_width { }
width: 130px;
} .item_width {
width: 130px;
.crop-option { }
margin-left: 11px;
margin-right: 11px; .crop-option {
border-radius: 11px; margin-left: 11px;
background-color: #eee; margin-right: 11px;
transition-property: height, margin-bottom; border-radius: 11px;
transition-duration: 200ms; background-color: #eee;
} transition-property: height, margin-bottom;
transition-duration: 200ms;
}
</style> </style>
<template> <template>
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view style="background:#FFFFFF; padding:40rpx;"> <view style="background:#FFFFFF; padding:40rpx;">
<view class="uni-hello-text uni-center">当前位置信息</view> <view class="uni-hello-text uni-center">当前位置信息</view>
<block v-if="hasLocation === false"> <block v-if="hasLocation === false">
<view class="uni-h2 uni-center uni-common-mt">未选择位置</view> <view class="uni-h2 uni-center uni-common-mt">未选择位置</view>
</block> </block>
<block v-if="hasLocation === true"> <block v-if="hasLocation === true">
<view class="uni-hello-text uni-center" style="margin-top:10px;"> <view class="uni-hello-text uni-center" style="margin-top:10px;">
{{locationAddress}} {{locationAddress}}
</view> </view>
<view class="uni-h2 uni-center uni-common-mt"> <view class="uni-h2 uni-center uni-common-mt">
<text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text> <text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text>
<text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text> <text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text>
</view> </view>
</block> </block>
</view> </view>
<view class="uni-btn-v"> <view class="uni-btn-v">
<view class="tips">注意:需要正确配置地图服务商的Key才能正常选择位置</view> <view class="tips">注意:需要正确配置地图服务商的Key才能正常选择位置</view>
<button type="primary" @tap="chooseLocation">选择位置</button> <button type="primary" @tap="chooseLocation">选择位置</button>
<button @tap="clear">清空</button> <button @tap="clear">清空</button>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script lang="uts"> <script lang="uts">
function formatLocation (longitude, latitude) { function formatLocation(longitude, latitude) {
if (typeof longitude === 'string' && typeof latitude === 'string') { if (typeof longitude === 'string' && typeof latitude === 'string') {
longitude = parseFloat(longitude) longitude = parseFloat(longitude)
latitude = parseFloat(latitude) latitude = parseFloat(latitude)
} }
longitude = longitude.toFixed(2) longitude = longitude.toFixed(2)
latitude = latitude.toFixed(2) latitude = latitude.toFixed(2)
return { return {
longitude: longitude.toString().split('.'), longitude: longitude.toString().split('.'),
latitude: latitude.toString().split('.') latitude: latitude.toString().split('.')
} }
} }
export default { export default {
data () { data() {
return { return {
title: 'chooseLocation', title: 'chooseLocation',
hasLocation: false, hasLocation: false,
location: {}, location: {},
locationAddress: '' locationAddress: ''
} }
}, },
methods: { methods: {
chooseLocation: function () { chooseLocation: function () {
uni.chooseLocation({ uni.chooseLocation({
success: (res) => { success: (res) => {
console.log(res, 123) console.log(res, 123)
this.hasLocation = true this.hasLocation = true
this.location = formatLocation(res.longitude, res.latitude) this.location = formatLocation(res.longitude, res.latitude)
this.locationAddress = res.address this.locationAddress = res.address
} }
}) })
}, },
clear: function () { clear: function () {
this.hasLocation = false this.hasLocation = false
} }
} }
} }
</script> </script>
<style> <style>
.page-body-info { .page-body-info {
padding-bottom: 0; padding-bottom: 0;
height: 440rpx; height: 440rpx;
} }
.tips { .tips {
font-size: 12px; font-size: 12px;
margin-top: 15px; margin-top: 15px;
opacity: .8; opacity: .8;
} }
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view style="flex:1"> <scroll-view style="flex:1">
<!-- #endif --> <!-- #endif -->
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<video class="video" :src="src" :controls="true"></video> <video class="video" :src="src" :controls="true"></video>
<view class="uni-title"> <view class="uni-title">
<text class="uni-subtitle-text">视频信息</text> <text class="uni-subtitle-text">视频信息</text>
</view> </view>
<text>{{videoInfo}}</text> <text>{{videoInfo}}</text>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button type="primary" @click="chooseVideo">选取视频</button> <button type="primary" @click="chooseVideo">选取视频</button>
</view> </view>
<enum-data title="视频来源" :items="sourceTypeItemTypes" @change="onSourceTypeChange"></enum-data> <enum-data title="视频来源" :items="sourceTypeItemTypes" @change="onSourceTypeChange"></enum-data>
<enum-data title="摄像头" :items="cameraItemTypes" @change="onCameraChange"></enum-data> <enum-data title="摄像头" :items="cameraItemTypes" @change="onCameraChange"></enum-data>
</view> </view>
<input-data title="最长拍摄时间,单位秒" defaultValue="60" type="number" @confirm="onMaxDurationConfirm"></input-data> <input-data title="最长拍摄时间,单位秒" defaultValue="60" type="number" @confirm="onMaxDurationConfirm"></input-data>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<boolean-data title="是否压缩" :defaultValue="true" @change="onCompressedChange"></boolean-data> <boolean-data title="是否压缩" :defaultValue="true" @change="onCompressedChange"></boolean-data>
</view> </view>
<!-- #endif --> <!-- #endif -->
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
import { ItemType } from '@/components/enum-data/enum-data'; import { ItemType } from '@/components/enum-data/enum-data';
type Camera = "back" | "front" type Camera = "back" | "front"
type Source = "album" | "camera" type Source = "album" | "camera"
export default { export default {
data() { data() {
return { return {
title: "chooseVideo", title: "chooseVideo",
src: "", src: "",
sourceTypeItemTypes: [{ "value": 0, "name": "从相册中选择视频" }, { "value": 1, "name": "拍摄视频" }, { "value": 2, "name": "从相册中选择视频或拍摄视频" }] as ItemType[], sourceTypeItemTypes: [{ "value": 0, "name": "从相册中选择视频" }, { "value": 1, "name": "拍摄视频" }, { "value": 2, "name": "从相册中选择视频或拍摄视频" }] as ItemType[],
sourceTypeItems: [["album"], ["camera"], ["album", "camera"]] as Source[][], sourceTypeItems: [["album"], ["camera"], ["album", "camera"]] as Source[][],
cameraItemTypes: [{ "value": 0, "name": "后置摄像头" }, { "value": 1, "name": "前置摄像头" }] as ItemType[], cameraItemTypes: [{ "value": 0, "name": "后置摄像头" }, { "value": 1, "name": "前置摄像头" }] as ItemType[],
cameraItems: ["back", "front"] as Camera[], cameraItems: ["back", "front"] as Camera[],
sourceType: ["album", "camera"] as Source[], sourceType: ["album", "camera"] as Source[],
compressed: true, compressed: true,
maxDuration: 60, maxDuration: 60,
camera: "back" as Camera, camera: "back" as Camera,
videoInfo: "" videoInfo: ""
} }
}, },
methods: { methods: {
chooseVideo() { chooseVideo() {
uni.chooseVideo({ uni.chooseVideo({
sourceType: this.sourceType, sourceType: this.sourceType,
// #ifdef APP // #ifdef APP
compressed: this.compressed, compressed: this.compressed,
// #endif // #endif
maxDuration: this.maxDuration, maxDuration: this.maxDuration,
camera: this.camera, camera: this.camera,
success: (res) => { success: (res) => {
console.log("chooseVideo success", JSON.stringify(res)); console.log("chooseVideo success", JSON.stringify(res));
this.src = res.tempFilePath; this.src = res.tempFilePath;
this.videoInfo = `视频长度: ${res.duration}s\n视频大小: ${Math.ceil(res.size / 1024)}KB\n视频宽度: ${res.width}\n视频高度: ${res.height}\n`; this.videoInfo = `视频长度: ${res.duration}s\n视频大小: ${Math.ceil(res.size / 1024)}KB\n视频宽度: ${res.width}\n视频高度: ${res.height}\n`;
}, },
fail: (err) => { fail: (err) => {
uni.showModal({ uni.showModal({
title: "选择视频失败", title: "选择视频失败",
content: JSON.stringify(err), content: JSON.stringify(err),
showCancel: false showCancel: false
}); });
} }
}); });
}, },
onSourceTypeChange(value : number) { onSourceTypeChange(value : number) {
this.sourceType = this.sourceTypeItems[value]; this.sourceType = this.sourceTypeItems[value];
}, },
onCompressedChange(value : boolean) { onCompressedChange(value : boolean) {
this.compressed = value; this.compressed = value;
}, },
onMaxDurationConfirm(value : number) { onMaxDurationConfirm(value : number) {
this.maxDuration = value; this.maxDuration = value;
}, },
onCameraChange(value : number) { onCameraChange(value : number) {
this.camera = this.cameraItems[value]; this.camera = this.cameraItems[value];
} }
} }
} }
</script> </script>
<style> <style>
.video { .video {
align-self: center; align-self: center;
width: 300px; width: 300px;
height: 225px; height: 225px;
} }
</style> </style>
<template> <template>
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view class="uni-title">请输入剪贴板内容</view> <view class="uni-title">请输入剪贴板内容</view>
<view class="uni-list"> <view class="uni-list">
<view class="uni-list-cell"> <view class="uni-list-cell">
<input class="uni-input" type="text" placeholder="请输入剪贴板内容" :value="data" @input="dataChange"/> <input class="uni-input" type="text" placeholder="请输入剪贴板内容" :value="data" @input="dataChange" />
</view> </view>
</view> </view>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button type="primary" @click="setClipboard">存储数据</button> <button type="primary" @click="setClipboard">存储数据</button>
<button @tap="getClipboard">读取数据</button> <button @tap="getClipboard">读取数据</button>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'get/setClipboardData', title: 'get/setClipboardData',
data: '', data: '',
// 自动化测试 // 自动化测试
getDataTest:'', getDataTest: '',
setClipboardTest: false setClipboardTest: false
} }
}, },
methods: { methods: {
dataChange: function (e) { dataChange: function (e) {
this.data = e.detail.value this.data = e.detail.value
}, },
getClipboard: function () { getClipboard: function () {
uni.getClipboardData({ uni.getClipboardData({
success: (res) => { success: (res) => {
console.log(res.data); console.log(res.data);
this.getDataTest = res.data; this.getDataTest = res.data;
const content = res.data ? '剪贴板内容为:' + res.data : '剪贴板暂无内容'; const content = res.data ? '剪贴板内容为:' + res.data : '剪贴板暂无内容';
uni.showModal({ uni.showModal({
content, content,
title: '读取剪贴板', title: '读取剪贴板',
showCancel: false showCancel: false
}) })
}, },
fail: () => { fail: () => {
uni.showModal({ uni.showModal({
content: '读取剪贴板失败!', content: '读取剪贴板失败!',
showCancel: false showCancel: false
}) })
} }
}); });
}, },
setClipboard: function () { setClipboard: function () {
if (this.data.length === 0) { if (this.data.length === 0) {
uni.showModal({ uni.showModal({
title: '设置剪贴板失败', title: '设置剪贴板失败',
content: '内容不能为空', content: '内容不能为空',
showCancel: false showCancel: false
}) })
} else { } else {
uni.setClipboardData({ uni.setClipboardData({
data: this.data, data: this.data,
success: () => { success: () => {
this.setClipboardTest = true this.setClipboardTest = true
// 成功处理 // 成功处理
uni.showToast({ uni.showToast({
title: '设置剪贴板成功', title: '设置剪贴板成功',
icon: "success", icon: "success",
mask: !1 mask: !1
}) })
}, },
fail: () => { fail: () => {
// bug:自动化测试时设置成功也进入了fail // bug:自动化测试时设置成功也进入了fail
this.setClipboardTest = false this.setClipboardTest = false
// 失败处理 // 失败处理
uni.showToast({ uni.showToast({
title: '储存数据失败!', title: '储存数据失败!',
icon: "none", icon: "none",
mask: !1 mask: !1
}) })
} }
}); });
} }
} }
} }
} }
</script> </script>
<style> <style>
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view class="page-scroll-view"> <scroll-view class="page-scroll-view">
<!-- #endif --> <!-- #endif -->
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt"> <view class="uni-padding-wrap uni-common-mt">
<view class="uni-btn-v uni-common-mt"> <view class="uni-btn-v uni-common-mt">
<button type="primary" @click="uploadFile">选择文件上传</button> <button type="primary" @click="uploadFile">选择文件上传</button>
<button type="primary" @click="chooseAndUploadFile">一个接口选择文件并上传</button> <button type="primary" @click="chooseAndUploadFile">一个接口选择文件并上传</button>
</view> </view>
</view> </view>
</view> </view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: '云存储' title: '云存储'
} }
}, },
onLoad() { onLoad() {
}, },
onUnload() { onUnload() {
}, },
methods: { methods: {
uploadFile: function () { uploadFile: function () {
uni.chooseImage({ uni.chooseImage({
count: 1, count: 1,
success(res) : void { success(res) : void {
uni.showLoading({ uni.showLoading({
title: '上传中...' title: '上传中...'
}) })
const tempFilePath = res.tempFilePaths[0] const tempFilePath = res.tempFilePaths[0]
uniCloud.uploadFile({ uniCloud.uploadFile({
filePath: tempFilePath, filePath: tempFilePath,
cloudPath: 'test.jpg' cloudPath: 'test.jpg'
}) })
.then(function (res) { .then(function (res) {
uni.hideLoading() uni.hideLoading()
console.log(res) console.log(res)
uni.showModal({ uni.showModal({
content: '上传成功', content: '上传成功',
showCancel: false showCancel: false
}); });
}) })
.catch(function (err : any | null) { .catch(function (err : any | null) {
uni.hideLoading() uni.hideLoading()
const error = err as UniCloudError const error = err as UniCloudError
uni.showModal({ uni.showModal({
content: '上传失败,' + error.errMsg, content: '上传失败,' + error.errMsg,
showCancel: false showCancel: false
}); });
}) })
// .finally((_: number) : void => { // .finally((_: number) : void => {
// uni.hideLoading() // uni.hideLoading()
// }) // })
}, },
fail(err) : void { fail(err) : void {
console.error('chooseImage fail: ', err) console.error('chooseImage fail: ', err)
} }
}) })
}, },
chooseAndUploadFile() { chooseAndUploadFile() {
uniCloud.chooseAndUploadFile({ uniCloud.chooseAndUploadFile({
type: 'image' type: 'image'
}).then(function (res) { }).then(function (res) {
uni.hideLoading() uni.hideLoading()
console.log(res) console.log(res)
uni.showModal({ uni.showModal({
content: '上传成功', content: '上传成功',
showCancel: false showCancel: false
}); });
}) })
.catch(function (err : any | null) { .catch(function (err : any | null) {
uni.hideLoading() uni.hideLoading()
const error = err as UniCloudError const error = err as UniCloudError
uni.showModal({ uni.showModal({
content: '上传失败,' + error.errMsg, content: '上传失败,' + error.errMsg,
showCancel: false showCancel: false
}); });
}) })
} }
} }
} }
</script> </script>
<style> <style>
</style> </style>
<template> <template>
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view class="uni-hello-text uni-center" style="padding-bottom:50rpx;"> <view class="uni-hello-text uni-center" style="padding-bottom:50rpx;">
旋转手机即可获取方位信息 旋转手机即可获取方位信息
</view> </view>
<view class="direction"> <view class="direction">
<view class="bg-compass-line"></view> <view class="bg-compass-line"></view>
<image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'"></image> <image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'">
<view class="direction-value"> </image>
<text>{{direction}}</text> <view class="direction-value">
<text class="direction-degree">o</text> <text>{{direction}}</text>
</view> <text class="direction-degree">o</text>
</view> </view>
</view> </view>
</view> </view>
</template> </view>
<script> </template>
export default { <script>
data() { export default {
return { data() {
title: 'onCompassChange', return {
direction: 0 title: 'onCompassChange',
} direction: 0
}, }
onReady: function () { },
uni.onCompassChange((res) => { onReady: function () {
console.log('onCompassChange', res) uni.onCompassChange((res) => {
this.direction = res.direction console.log('onCompassChange', res)
}) this.direction = res.direction
}, })
onUnload() { },
uni.stopCompass(); onUnload() {
this.direction = 0; uni.stopCompass();
} this.direction = 0;
} }
</script> }
</script>
<style>
.direction { <style>
position: relative; .direction {
margin-top: 70rpx; position: relative;
display: flex; margin-top: 70rpx;
width: 540rpx; display: flex;
height: 540rpx; width: 540rpx;
align-items: center; height: 540rpx;
justify-content: center; align-items: center;
margin:0 auto; justify-content: center;
} margin: 0 auto;
}
.direction-value {
position: relative; .direction-value {
font-size: 200rpx; position: relative;
color: #353535; font-size: 200rpx;
line-height: 1; color: #353535;
z-index: 1; line-height: 1;
} z-index: 1;
}
.direction-degree {
position: absolute; .direction-degree {
top: 0; position: absolute;
right: -40rpx; top: 0;
font-size: 60rpx; right: -40rpx;
} font-size: 60rpx;
}
.bg-compass {
position: absolute; .bg-compass {
top: 0; position: absolute;
left: 0; top: 0;
width: 540rpx; left: 0;
height: 540rpx; width: 540rpx;
transition: .1s; height: 540rpx;
} transition: .1s;
}
.bg-compass-line {
position: absolute; .bg-compass-line {
left: 267rpx; position: absolute;
top: -10rpx; left: 267rpx;
width: 6rpx; top: -10rpx;
height: 56rpx; width: 6rpx;
background-color: #1AAD19; height: 56rpx;
border-radius: 999rpx; background-color: #1AAD19;
z-index: 1; border-radius: 999rpx;
} z-index: 1;
}
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view style="flex:1"> <scroll-view style="flex:1">
<!-- #endif --> <!-- #endif -->
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view class="image-container"> <view class="image-container">
<image class="image" :src="beforeCompressPath" mode="aspectFit"></image> <image class="image" :src="beforeCompressPath" mode="aspectFit"></image>
<image class="image" :src="afterCompressPath" mode="aspectFit"></image> <image class="image" :src="afterCompressPath" mode="aspectFit"></image>
</view> </view>
<view class="uni-title"> <view class="uni-title">
<text class="uni-subtitle-text">压缩前图片信息</text> <text class="uni-subtitle-text">压缩前图片信息</text>
</view> </view>
<text>{{beforeCompressImageInfo}}</text> <text>{{beforeCompressImageInfo}}</text>
<view class="uni-title"> <view class="uni-title">
<text class="uni-subtitle-text">压缩后图片信息</text> <text class="uni-subtitle-text">压缩后图片信息</text>
</view> </view>
<text>{{afterCompressImageInfo}}</text> <text>{{afterCompressImageInfo}}</text>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button type="primary" @click="chooseImage">从相册中选取待压缩的图片</button> <button type="primary" @click="chooseImage">从相册中选取待压缩的图片</button>
</view> </view>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button type="primary" @click="compressImage">压缩图片</button> <button type="primary" @click="compressImage">压缩图片</button>
</view> </view>
</view> </view>
<input-data defaultValue="80" title="压缩质量,范围0~100,数值越小,质量越低,压缩率越高(仅对jpg有效)" type="number" <input-data defaultValue="80" title="压缩质量,范围0~100,数值越小,质量越低,压缩率越高(仅对jpg有效)" type="number"
@confirm="onQualityConfirm"></input-data> @confirm="onQualityConfirm"></input-data>
<input-data title="压缩后图片的宽度,单位px" type="string" @confirm="onCompressedWidthConfirm"></input-data> <input-data title="压缩后图片的宽度,单位px" type="string" @confirm="onCompressedWidthConfirm"></input-data>
<input-data title="压缩后图片的高度,单位px" type="string" @confirm="onCompressedHeightConfirm"></input-data> <input-data title="压缩后图片的高度,单位px" type="string" @confirm="onCompressedHeightConfirm"></input-data>
<input-data defaultValue="0" title="旋转度数,范围0~360" type="number" @confirm="onRotateConfirm"></input-data> <input-data defaultValue="0" title="旋转度数,范围0~360" type="number" @confirm="onRotateConfirm"></input-data>
</view> </view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
import FileInputStream from 'java.io.FileInputStream'; import FileInputStream from 'java.io.FileInputStream';
// #endif // #endif
export default { export default {
data() { data() {
return { return {
title: "compressImage", title: "compressImage",
beforeCompressImageInfo: "", beforeCompressImageInfo: "",
afterCompressImageInfo: "", afterCompressImageInfo: "",
beforeCompressPath: "", beforeCompressPath: "",
afterCompressPath: "", afterCompressPath: "",
quality: 80, quality: 80,
compressedWidth: null as number | null, compressedWidth: null as number | null,
compressedHeight: null as number | null, compressedHeight: null as number | null,
rotate: 0, rotate: 0,
// 自动化测试 // 自动化测试
imageInfoForTest: null, imageInfoForTest: null,
imageSrcForTest: '/static/test-image/logo.png' imageSrcForTest: '/static/test-image/logo.png'
} }
}, },
methods: { methods: {
compressImage() { compressImage() {
if (this.beforeCompressPath == "") { if (this.beforeCompressPath == "") {
uni.showToast({ uni.showToast({
title: "请先选择图片", title: "请先选择图片",
icon: "error" icon: "error"
}); });
return; return;
} }
uni.showLoading({ uni.showLoading({
title: "图片压缩中" title: "图片压缩中"
}); });
uni.compressImage({ uni.compressImage({
src: this.beforeCompressPath, src: this.beforeCompressPath,
quality: this.quality, quality: this.quality,
compressedWidth: this.compressedWidth, compressedWidth: this.compressedWidth,
compressedHeight: this.compressedHeight, compressedHeight: this.compressedHeight,
rotate: this.rotate, rotate: this.rotate,
success: (res) => { success: (res) => {
console.log("compressImage success", JSON.stringify(res)); console.log("compressImage success", JSON.stringify(res));
this.afterCompressPath = res.tempFilePath; this.afterCompressPath = res.tempFilePath;
uni.showToast({ uni.showToast({
title: "压缩成功", title: "压缩成功",
icon: null icon: null
}); });
uni.getImageInfo({ uni.getImageInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (_res) => { success: (_res) => {
this.afterCompressImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n`; this.afterCompressImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n`;
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
const size = new FileInputStream(res.tempFilePath.substring("file://".length)).available() / 1024; const size = new FileInputStream(res.tempFilePath.substring("file://".length)).available() / 1024;
this.afterCompressImageInfo = this.afterCompressImageInfo.concat(`图片大小: ${size}KB`); this.afterCompressImageInfo = this.afterCompressImageInfo.concat(`图片大小: ${size}KB`);
// #endif // #endif
} }
}); });
}, },
fail: (err) => { fail: (err) => {
uni.showModal({ uni.showModal({
title: "压缩图片失败", title: "压缩图片失败",
content: JSON.stringify(err), content: JSON.stringify(err),
showCancel: false showCancel: false
}); });
}, },
complete: (_) => { complete: (_) => {
uni.hideLoading(); uni.hideLoading();
} }
}); });
}, },
chooseImage() { chooseImage() {
uni.chooseImage({ uni.chooseImage({
count: 1, count: 1,
sizeType: ["original"], sizeType: ["original"],
sourceType: ["album"], sourceType: ["album"],
success: (res) => { success: (res) => {
this.beforeCompressPath = res.tempFilePaths[0]; this.beforeCompressPath = res.tempFilePaths[0];
uni.getImageInfo({ uni.getImageInfo({
src: res.tempFilePaths[0], src: res.tempFilePaths[0],
success: (_res) => { success: (_res) => {
this.beforeCompressImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n`; this.beforeCompressImageInfo = `图片宽度: ${_res.width}\n图片高度: ${_res.height}\n`;
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
const size = new FileInputStream(res.tempFilePaths[0].substring("file://".length)).available() / 1024; const size = new FileInputStream(res.tempFilePaths[0].substring("file://".length)).available() / 1024;
this.beforeCompressImageInfo = this.beforeCompressImageInfo.concat(`图片大小: ${size}KB`); this.beforeCompressImageInfo = this.beforeCompressImageInfo.concat(`图片大小: ${size}KB`);
// #endif // #endif
} }
}); });
} }
}); });
}, },
onQualityConfirm(value : number) { onQualityConfirm(value : number) {
this.quality = value; this.quality = value;
}, },
onCompressedWidthConfirm(value : string) { onCompressedWidthConfirm(value : string) {
this.compressedWidth = parseInt(value); this.compressedWidth = parseInt(value);
}, },
onCompressedHeightConfirm(value : string) { onCompressedHeightConfirm(value : string) {
this.compressedHeight = parseInt(value); this.compressedHeight = parseInt(value);
}, },
onRotateConfirm(value : number) { onRotateConfirm(value : number) {
this.rotate = value; this.rotate = value;
}, },
testCompressImage() { testCompressImage() {
uni.compressImage({ uni.compressImage({
src: this.imageSrcForTest, src: this.imageSrcForTest,
quality: 50, quality: 50,
compressedWidth: 100, compressedWidth: 100,
compressedHeight: 100, compressedHeight: 100,
success: (res) => { success: (res) => {
uni.getImageInfo({ uni.getImageInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (_res) => { success: (_res) => {
let beforeCompressSize : number, afterComoressSize : number; let beforeCompressSize : number, afterComoressSize : number;
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
beforeCompressSize = new FileInputStream(UTSAndroid.convert2AbsFullPath(this.imageSrcForTest)).available(); beforeCompressSize = new FileInputStream(UTSAndroid.convert2AbsFullPath(this.imageSrcForTest)).available();
afterComoressSize = new FileInputStream(res.tempFilePath.substring("file://".length)).available(); afterComoressSize = new FileInputStream(res.tempFilePath.substring("file://".length)).available();
// #endif // #endif
this.imageInfoForTest = { this.imageInfoForTest = {
"width": _res.width, "width": _res.width,
"height": _res.height, "height": _res.height,
"isSizeReduce": afterComoressSize < beforeCompressSize "isSizeReduce": afterComoressSize < beforeCompressSize
}; };
} }
}); });
}, },
fail: (_) => { fail: (_) => {
this.imageInfoForTest = null; this.imageInfoForTest = null;
} }
}); });
} }
} }
} }
</script> </script>
<style> <style>
.image { .image {
flex: 1; flex: 1;
} }
.image-container { .image-container {
flex-direction: row; flex-direction: row;
} }
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view style="flex:1"> <scroll-view style="flex:1">
<!-- #endif --> <!-- #endif -->
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view> <view>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<video class="video" :src="beforeCompressPath" :controls="true"></video> <video class="video" :src="beforeCompressPath" :controls="true"></video>
<view class="uni-title"> <view class="uni-title">
<text class="uni-subtitle-text">压缩前视频信息</text> <text class="uni-subtitle-text">压缩前视频信息</text>
</view> </view>
<text>{{beforeCompressVideoInfo}}</text> <text>{{beforeCompressVideoInfo}}</text>
<video class="video" :src="afterCompressPath" :controls="true"></video> <video class="video" :src="afterCompressPath" :controls="true"></video>
<view class="uni-title"> <view class="uni-title">
<text class="uni-subtitle-text">压缩后视频信息</text> <text class="uni-subtitle-text">压缩后视频信息</text>
</view> </view>
<text>{{afterCompressVideoInfo}}</text> <text>{{afterCompressVideoInfo}}</text>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button type="primary" @click="chooseVideo">从相册中选取待压缩的视频</button> <button type="primary" @click="chooseVideo">从相册中选取待压缩的视频</button>
</view> </view>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button type="primary" @click="compressVideo">压缩视频</button> <button type="primary" @click="compressVideo">压缩视频</button>
</view> </view>
<enum-data title="压缩质量" :items="qualityItemTypes" @change="onQualityChange"></enum-data> <enum-data title="压缩质量" :items="qualityItemTypes" @change="onQualityChange"></enum-data>
<view class="uni-common-mt"> <view class="uni-common-mt">
<text class="uni-title uni-title-text">相对于原视频的分辨率比例,取值范围(0, 1]</text> <text class="uni-title uni-title-text">相对于原视频的分辨率比例,取值范围(0, 1]</text>
<slider :min="0.1" :max="1" :step="0.1" :show-value="true" @change="onResolutionChange"></slider> <slider :min="0.1" :max="1" :step="0.1" :show-value="true" @change="onResolutionChange"></slider>
</view> </view>
</view> </view>
</view> </view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
import { ItemType } from '@/components/enum-data/enum-data'; import { ItemType } from '@/components/enum-data/enum-data';
export default { export default {
data() { data() {
return { return {
title: "compressVideo", title: "compressVideo",
beforeCompressVideoInfo: "", beforeCompressVideoInfo: "",
afterCompressVideoInfo: "", afterCompressVideoInfo: "",
beforeCompressPath: "", beforeCompressPath: "",
afterCompressPath: "", afterCompressPath: "",
quality: null as string | null, quality: null as string | null,
bitrate: null as number | null, bitrate: null as number | null,
fps: null as number | null, fps: null as number | null,
resolution: null as number | null, resolution: null as number | null,
qualityItemTypes: [{ "value": 0, "name": "low(低)" }, { "value": 1, "name": "medium(中)" }, { "value": 2, "name": "high(高)" }] as ItemType[], qualityItemTypes: [{ "value": 0, "name": "low(低)" }, { "value": 1, "name": "medium(中)" }, { "value": 2, "name": "high(高)" }] as ItemType[],
qualityItems: ["low", "medium", "high"], qualityItems: ["low", "medium", "high"],
// 自动化测试 // 自动化测试
videoInfoForTest: null, videoInfoForTest: null,
videoSrcForTest: '/static/test-video/10second-demo.mp4' videoSrcForTest: '/static/test-video/10second-demo.mp4'
} }
}, },
methods: { methods: {
compressVideo() { compressVideo() {
if (this.beforeCompressPath == "") { if (this.beforeCompressPath == "") {
uni.showToast({ uni.showToast({
title: "请先选择视频", title: "请先选择视频",
icon: "error" icon: "error"
}); });
return; return;
} }
uni.showLoading({ uni.showLoading({
title: "视频压缩中" title: "视频压缩中"
}); });
uni.compressVideo({ uni.compressVideo({
src: this.beforeCompressPath, src: this.beforeCompressPath,
quality: this.quality, quality: this.quality,
resolution: this.resolution, resolution: this.resolution,
success: (res) => { success: (res) => {
console.log("compressVideo success", JSON.stringify(res)); console.log("compressVideo success", JSON.stringify(res));
this.afterCompressPath = res.tempFilePath; this.afterCompressPath = res.tempFilePath;
uni.showToast({ uni.showToast({
title: "压缩成功", title: "压缩成功",
icon: null icon: null
}); });
uni.getVideoInfo({ uni.getVideoInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (_res) => { success: (_res) => {
this.afterCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`; this.afterCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
} }
}); });
}, },
fail: (err) => { fail: (err) => {
uni.showModal({ uni.showModal({
title: "压缩视频失败", title: "压缩视频失败",
content: JSON.stringify(err), content: JSON.stringify(err),
showCancel: false showCancel: false
}); });
}, },
complete: (_) => { complete: (_) => {
uni.hideLoading(); uni.hideLoading();
} }
}); });
}, },
chooseVideo() { chooseVideo() {
uni.chooseVideo({ uni.chooseVideo({
sourceType: ["album"], sourceType: ["album"],
compressed: false, compressed: false,
success: (res) => { success: (res) => {
this.beforeCompressPath = res.tempFilePath; this.beforeCompressPath = res.tempFilePath;
uni.getVideoInfo({ uni.getVideoInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (_res) => { success: (_res) => {
this.beforeCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`; this.beforeCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
} }
}); });
} }
}); });
}, },
onQualityChange(value : number) { onQualityChange(value : number) {
this.quality = this.qualityItems[value]; this.quality = this.qualityItems[value];
}, },
onResolutionChange(event : UniSliderChangeEvent) { onResolutionChange(event : UniSliderChangeEvent) {
this.resolution = event.detail.value; this.resolution = event.detail.value;
}, },
testCompressVideo() { testCompressVideo() {
let beforeCompressSize : number, afterComoressSize : number; let beforeCompressSize : number, afterComoressSize : number;
uni.compressVideo({ uni.compressVideo({
src: this.videoSrcForTest, src: this.videoSrcForTest,
quality: 'medium', quality: 'medium',
success: (res) => { success: (res) => {
uni.getVideoInfo({ uni.getVideoInfo({
src: this.videoSrcForTest, src: this.videoSrcForTest,
success: (_res) => { success: (_res) => {
beforeCompressSize = Math.trunc(_res.size); beforeCompressSize = Math.trunc(_res.size);
uni.getVideoInfo({ uni.getVideoInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (__res) => { success: (__res) => {
afterComoressSize = Math.trunc(__res.size); afterComoressSize = Math.trunc(__res.size);
this.videoInfoForTest = { this.videoInfoForTest = {
"width": __res.width, "width": __res.width,
"height": __res.height, "height": __res.height,
"isSizeReduce": afterComoressSize < beforeCompressSize "isSizeReduce": afterComoressSize < beforeCompressSize
}; };
} }
}); });
} }
}); });
}, },
fail: (_) => { fail: (_) => {
this.videoInfoForTest = null; this.videoInfoForTest = null;
} }
}); });
} }
} }
} }
</script> </script>
<style> <style>
.video { .video {
align-self: center; align-self: center;
} }
.image-container { .image-container {
flex-direction: row; flex-direction: row;
} }
</style> </style>
<template> <template>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<page-head title="audio"></page-head> <page-head title="audio"></page-head>
<view class="uni-common-mt"> <view class="uni-common-mt">
<slider :value="position" :min="0" :max="duration" @changing="onchanging" @change="onchange"></slider> <slider :value="position" :min="0" :max="duration" @changing="onchanging" @change="onchange"></slider>
</view> </view>
<view class="uni-title"> <view class="uni-title">
<text class="uni-title-text">属性示例</text> <text class="uni-title-text">属性示例</text>
</View> </View>
<text class="uni-text-box uni-common-mt">当前音频播放位置(保留小数点后 6 位):{{currentTime}} s</text> <text class="uni-text-box uni-common-mt">当前音频播放位置(保留小数点后 6 位):{{currentTime}} s</text>
<text class="uni-text-box">音频的长度(单位:s):{{duration}} s</text> <text class="uni-text-box">音频的长度(单位:s):{{duration}} s</text>
<text class="uni-text-box">当前是否停止状态:{{isPaused}}</text> <text class="uni-text-box">当前是否停止状态:{{isPaused}}</text>
<text class="uni-text-box">音频缓冲的时间点:{{buffered}}</text> <text class="uni-text-box">音频缓冲的时间点:{{buffered}}</text>
<text class="uni-text-box">当前音量:{{volume}}</text> <text class="uni-text-box">当前音量:{{volume}}</text>
<!-- 设置音量无效 --> <!-- 设置音量无效 -->
<!-- <button plain :disabled="volume == 1" @click="increaseVolume">增加音量</button> <!-- <button plain :disabled="volume == 1" @click="increaseVolume">增加音量</button>
<button plain :disabled="volume == 0" @click="decreaseVolume">减少音量</button> --> <button plain :disabled="volume == 0" @click="decreaseVolume">减少音量</button> -->
<text class="uni-subtitle-text uni-title">开始播放的位置(单位:s)</text> <text class="uni-subtitle-text uni-title">开始播放的位置(单位:s)</text>
<input :value="startTime" type="number" placeholder="开始播放的位置(单位:s)" class="uni-input" <input :value="startTime" type="number" placeholder="开始播放的位置(单位:s)" class="uni-input"
@input="startTimeInput"></input> @input="startTimeInput"></input>
<boolean-data :defaultValue="false" title="是否自动开始播放" @change="setAutoplay"></boolean-data> <boolean-data :defaultValue="false" title="是否自动开始播放" @change="setAutoplay"></boolean-data>
<boolean-data :defaultValue="false" title="是否循环播放" @change="setLoop"></boolean-data> <boolean-data :defaultValue="false" title="是否循环播放" @change="setLoop"></boolean-data>
<view class="uni-title"> <view class="uni-title">
<text class="uni-title-text">方法示例</text> <text class="uni-title-text">方法示例</text>
</View> </View>
<button :disabled="isPlaying" type="primary" @click="play" class="uni-btn">播放</button> <button :disabled="isPlaying" type="primary" @click="play" class="uni-btn">播放</button>
<button :disabled="!isPlaying" type="primary" @click="pause" class="uni-btn">暂停</button> <button :disabled="!isPlaying" type="primary" @click="pause" class="uni-btn">暂停</button>
<button :disabled="!isPlaying && !isPaused" type="primary" @click="stop" class="uni-btn">停止</button> <button :disabled="!isPlaying && !isPaused" type="primary" @click="stop" class="uni-btn">停止</button>
<button type="primary" @click="onchange(20)" class="uni-btn">跳转到指定位置20</button> <button type="primary" @click="onchange(20)" class="uni-btn">跳转到指定位置20</button>
<view class="uni-title"> <view class="uni-title">
<text class="uni-title-text">格式/路径示例</text> <text class="uni-title-text">格式/路径示例</text>
</View> </View>
<navigator url="/pages/API/create-inner-audio-context/inner-audio-format" class="uni-btn"> <navigator url="/pages/API/create-inner-audio-context/inner-audio-format" class="uni-btn">
<button type="primary" @click="pause">音频格式示例</button> <button type="primary" @click="pause">音频格式示例</button>
</navigator> </navigator>
<navigator url="/pages/API/create-inner-audio-context/inner-audio-path" class="uni-btn uni-common-mb"> <navigator url="/pages/API/create-inner-audio-context/inner-audio-path" class="uni-btn uni-common-mb">
<button type="primary" @click="pause">音频路径示例</button> <button type="primary" @click="pause">音频路径示例</button>
</navigator> </navigator>
</view> </view>
</template> </template>
<script lang="uts"> <script lang="uts">
const audioUrl = 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3' const audioUrl = 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3'
export default { export default {
data() { data() {
return { return {
title: "innerAudioContext", title: "innerAudioContext",
currentTime: 0, currentTime: 0,
duration: 100, duration: 100,
startTime: 0, startTime: 0,
buffered: 0, buffered: 0,
volume: 0.5, volume: 0.5,
isCanplay: false, isCanplay: false,
isPlaying: false, isPlaying: false,
isPaused: true, isPaused: true,
isPlayEnd: false, isPlayEnd: false,
_isChanging: false, _isChanging: false,
_audioContext: null as InnerAudioContext | null, _audioContext: null as InnerAudioContext | null,
// 自动化测试 // 自动化测试
onSeekingTest:false, onSeekingTest: false,
onSeekedTest:false, onSeekedTest: false,
onWaitingTest:false onWaitingTest: false
} }
}, },
computed: { computed: {
position() { position() {
return this.isPlayEnd ? 0 : this.currentTime; return this.isPlayEnd ? 0 : this.currentTime;
}, },
}, },
onReady() { onReady() {
this._audioContext = uni.createInnerAudioContext(); this._audioContext = uni.createInnerAudioContext();
this._audioContext!.src = audioUrl; this._audioContext!.src = audioUrl;
this.volume = this._audioContext!.volume; this.volume = this._audioContext!.volume;
this.onCanplay() this.onCanplay()
}, },
onUnload() { onUnload() {
if (this._audioContext != null && this.isPlaying) { if (this._audioContext != null && this.isPlaying) {
this.stop(); this.stop();
this._audioContext!.destroy() this._audioContext!.destroy()
} }
}, },
methods: { methods: {
onCanplay() { onCanplay() {
this._audioContext!.onCanplay(() => { this._audioContext!.onCanplay(() => {
console.log('音频进入可以播放状态事件'); console.log('音频进入可以播放状态事件');
this.isCanplay = true; this.isCanplay = true;
// 当音频可以播放时,获取缓冲信息 // 当音频可以播放时,获取缓冲信息
this.buffered = this._audioContext!.buffered; this.buffered = this._audioContext!.buffered;
this.duration = this._audioContext!.duration || 0; this.duration = this._audioContext!.duration || 0;
}); });
}, },
onchanging() { onchanging() {
this._isChanging = true; this._isChanging = true;
}, },
onchange(e) { onchange(e) {
console.log(e, 'e'); console.log(e, 'e');
let pos = typeof e === "number" ? e : e.detail.value; let pos = typeof e === "number" ? e : e.detail.value;
this._audioContext!.seek(pos); this._audioContext!.seek(pos);
this.onSeeking() this.onSeeking()
this.onSeeked() this.onSeeked()
this._isChanging = false; this._isChanging = false;
}, },
startTimeInput(e : InputEvent) { startTimeInput(e : InputEvent) {
let startTimeValue = Number(e.detail.value) let startTimeValue = Number(e.detail.value)
this._audioContext!.startTime = startTimeValue; this._audioContext!.startTime = startTimeValue;
this.onchange(startTimeValue) this.onchange(startTimeValue)
}, },
setAutoplay() { setAutoplay() {
this._audioContext!.autoplay = !this._audioContext!.autoplay; this._audioContext!.autoplay = !this._audioContext!.autoplay;
console.log(this._audioContext!.autoplay, 'autoplay'); console.log(this._audioContext!.autoplay, 'autoplay');
}, },
setLoop() { setLoop() {
this._audioContext!.loop = !this._audioContext!.loop; this._audioContext!.loop = !this._audioContext!.loop;
console.log(this._audioContext!.loop, 'loop'); console.log(this._audioContext!.loop, 'loop');
}, },
play() { play() {
if (!this.isCanplay) { if (!this.isCanplay) {
uni.showToast({ uni.showToast({
title: '音频未进入可以播放状态,请稍后再试' title: '音频未进入可以播放状态,请稍后再试'
}); });
return; return;
} }
this.isPlaying = true; this.isPlaying = true;
this._audioContext!.play(); this._audioContext!.play();
this.isPlayEnd = false; this.isPlayEnd = false;
if (this._audioContext!.startTime > 0) { if (this._audioContext!.startTime > 0) {
this.onchange(this._audioContext!.startTime) this.onchange(this._audioContext!.startTime)
} }
this._audioContext!.onPlay(() => { this._audioContext!.onPlay(() => {
this.isPaused = false; this.isPaused = false;
console.log('开始播放',this.isPaused); console.log('开始播放', this.isPaused);
}); });
this.onTimeUpdate() this.onTimeUpdate()
this.onWaiting() this.onWaiting()
this.onError() this.onError()
this.onEnded() this.onEnded()
}, },
onSeeking() { onSeeking() {
this._audioContext!.onSeeking(() => { this._audioContext!.onSeeking(() => {
console.log('音频进行 seek 操作事件'); console.log('音频进行 seek 操作事件');
this.onSeekingTest = true this.onSeekingTest = true
}); });
}, },
onSeeked() { onSeeked() {
this._audioContext!.onSeeked(() => { this._audioContext!.onSeeked(() => {
console.log('音频完成 seek 操作事件'); console.log('音频完成 seek 操作事件');
this.onSeekedTest = true this.onSeekedTest = true
}); });
}, },
onWaiting() { onWaiting() {
this._audioContext!.onWaiting(() => { this._audioContext!.onWaiting(() => {
console.log('音频加载中事件'); console.log('音频加载中事件');
this.onWaitingTest = true this.onWaitingTest = true
}); });
}, },
onTimeUpdate() { onTimeUpdate() {
this._audioContext!.onTimeUpdate(() => { this._audioContext!.onTimeUpdate(() => {
// console.log('onTimeUpdate:音频播放进度更新事件,currentTime',this._audioContext!.currentTime); // console.log('onTimeUpdate:音频播放进度更新事件,currentTime',this._audioContext!.currentTime);
if (this._isChanging === true) { return; } if (this._isChanging === true) { return; }
this.currentTime = this._audioContext!.currentTime || 0; this.currentTime = this._audioContext!.currentTime || 0;
if (this.currentTime > this.buffered) { if (this.currentTime > this.buffered) {
console.log('缓冲不足'); console.log('缓冲不足');
} }
}); });
}, },
increaseVolume() { increaseVolume() {
this.volume = Math.min(this.volume + 0.1, 1); this.volume = Math.min(this.volume + 0.1, 1);
this.volume = parseFloat(this.volume.toFixed(1)); this.volume = parseFloat(this.volume.toFixed(1));
console.log('增加音量', this.volume); console.log('增加音量', this.volume);
}, },
decreaseVolume() { decreaseVolume() {
this.volume = Math.max(this.volume - 0.1, 0); this.volume = Math.max(this.volume - 0.1, 0);
this.volume = parseFloat(this.volume.toFixed(1)); this.volume = parseFloat(this.volume.toFixed(1));
console.log('减少音量', this.volume); console.log('减少音量', this.volume);
}, },
onEnded() { onEnded() {
this._audioContext!.onEnded(() => { this._audioContext!.onEnded(() => {
console.log('播放结束'); console.log('播放结束');
this.currentTime = 0; this.currentTime = 0;
this.startTime = 0 this.startTime = 0
this.isPlaying = false; this.isPlaying = false;
this.isPaused = true; this.isPaused = true;
this.isPlayEnd = true; this.isPlayEnd = true;
}); });
}, },
onError() { onError() {
this._audioContext!.onError((err) => { this._audioContext!.onError((err) => {
console.log('err', err); console.log('err', err);
this.isPlaying = false; this.isPlaying = false;
this.isPaused = true; this.isPaused = true;
}); });
}, },
pause() { pause() {
this._audioContext!.pause(); this._audioContext!.pause();
this._audioContext!.onPause(() => { this._audioContext!.onPause(() => {
console.log('音频暂停事件'); console.log('音频暂停事件');
this.isPaused = true; this.isPaused = true;
}); });
this.isPlaying = false; this.isPlaying = false;
}, },
stop() { stop() {
console.log('stop'); console.log('stop');
this._audioContext!.stop(); this._audioContext!.stop();
this._audioContext!.onStop(() => { this._audioContext!.onStop(() => {
// 第一次点停止时,不触发 // 第一次点停止时,不触发
this.isPaused = true; this.isPaused = true;
console.log('音频停止事件'); console.log('音频停止事件');
}); });
this.isPlaying = false; this.isPlaying = false;
console.log('stop',this.isPaused); console.log('stop', this.isPaused);
} }
} }
} }
</script> </script>
<style> <style>
.play-time-area { .play-time-area {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin-top: 20px; margin-top: 20px;
} }
.duration { .duration {
margin-left: auto; margin-left: auto;
} }
.play-button-area { .play-button-area {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
margin: 50px 0; margin: 50px 0;
} }
.icon-play { .icon-play {
width: 60px; width: 60px;
height: 60px; height: 60px;
} }
</style> </style>
<template> <template>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt"> <view class="uni-padding-wrap uni-common-mt">
<view class="uni-title"> <view class="uni-title">
<text class="uni-title-text">支持的音频格式示例</text> <text class="uni-title-text">支持的音频格式示例</text>
</view> </view>
<view class="formats" v-for="(item,index) in supportFormats" :key="index"> <view class="formats" v-for="(item,index) in supportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text> <text class="uni-subtitle-text">{{item.format}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image> <image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'"
</view> @click="play(item.src,index)"></image>
</view>
<view class="uni-title">
<text class="uni-title-text">不支持的音频格式</text> <view class="uni-title">
</view> <text class="uni-title-text">不支持的音频格式</text>
<view class="formats" v-for="(item,index) in notSupportFormats" :key="index"> </view>
<text class="uni-subtitle-text">{{item.format}}</text> <view class="formats" v-for="(item,index) in notSupportFormats" :key="index">
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image> <text class="uni-subtitle-text">{{item.format}}</text>
</view> <image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'"
</view> @click="play(item.src,index)"></image>
</template> </view>
</view>
<script> </template>
type AudioFormat = {
format : string <script>
src : string type AudioFormat = {
} format : string
export default { src : string
data() { }
return { export default {
title: 'audio-format', data() {
playIndex:0, return {
isPlaying: false, title: 'audio-format',
_audioContext: null as InnerAudioContext | null, playIndex: 0,
supportFormats: [ isPlaying: false,
{ _audioContext: null as InnerAudioContext | null,
format: 'mp3', supportFormats: [
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3' {
}, format: 'mp3',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
format: 'mp4', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp4' {
}, format: 'mp4',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp4'
format: 'm4a', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.m4a' {
}, format: 'm4a',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.m4a'
format: 'aac', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aac' {
}, format: 'aac',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aac'
format: 'flac', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.flac' {
}, format: 'flac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.flac'
{ },
format: 'ogg',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.ogg' {
}, format: 'ogg',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.ogg'
format: 'wav', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wav' {
}, format: 'wav',
] as Array<AudioFormat>, src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wav'
notSupportFormats:[ },
{ ] as Array<AudioFormat>,
format: 'wma', notSupportFormats: [
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wma' {
}, format: 'wma',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wma'
format: 'aiff', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aiff' {
}, format: 'aiff',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aiff'
format: 'caf', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.caf' {
}, format: 'caf',
{ src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.caf'
format: '错误格式', },
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wmaa' {
}, format: '错误格式',
] as Array<AudioFormat> src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wmaa'
} },
}, ] as Array<AudioFormat>
onReady() { }
this._audioContext = uni.createInnerAudioContext(); },
}, onReady() {
onUnload() { this._audioContext = uni.createInnerAudioContext();
if (this._audioContext != null) { },
this.pause(); onUnload() {
this._audioContext!.destroy() if (this._audioContext != null) {
} this.pause();
}, this._audioContext!.destroy()
methods: { }
pause() { },
this._audioContext!.pause(); methods: {
this.isPlaying = false; pause() {
}, this._audioContext!.pause();
play(audioUrl,index){ this.isPlaying = false;
// console.log(index,audioUrl); },
if (this.isPlaying && this.playIndex == index) { play(audioUrl, index) {
this.pause(); // console.log(index,audioUrl);
return; if (this.isPlaying && this.playIndex == index) {
} this.pause();
this.playIndex = index return;
this._audioContext!.src = audioUrl; }
this._audioContext!.play(); this.playIndex = index
this.isPlaying = true; this._audioContext!.src = audioUrl;
this._audioContext!.onPlay(() => { this._audioContext!.play();
console.log('开始播放'); this.isPlaying = true;
}); this._audioContext!.onPlay(() => {
this._audioContext!.onEnded(() => { console.log('开始播放');
console.log('播放结束'); });
this.isPlaying = false; this._audioContext!.onEnded(() => {
}); console.log('播放结束');
this._audioContext!.onError((err) => { this.isPlaying = false;
this.isPlaying = false; });
console.log('err',err); this._audioContext!.onError((err) => {
}); this.isPlaying = false;
}, console.log('err', err);
}, });
} },
</script> },
}
<style> </script>
.formats{
align-items: center; <style>
} .formats {
.icon-play { align-items: center;
width: 60px; }
height: 60px;
margin: 10px; .icon-play {
} width: 60px;
height: 60px;
margin: 10px;
}
</style> </style>
<template> <template>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt"> <view class="uni-padding-wrap uni-common-mt">
<view class="uni-title"> <view class="uni-title">
<text class="uni-title-text">音频路径示例</text> <text class="uni-title-text">音频路径示例</text>
</view> </view>
<view class="formats" v-for="(item,index) in supportPaths" :key="index"> <view class="formats" v-for="(item,index) in supportPaths" :key="index">
<text class="uni-subtitle-text">{{item.description}}</text> <text class="uni-subtitle-text">{{item.description}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image> <image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'"
</view> @click="play(item.src,index)"></image>
</view> </view>
</template> </view>
</template>
<script>
type AudioPath = { <script>
description : string type AudioPath = {
src : string description : string
} src : string
export default { }
data() { export default {
return { data() {
title: 'audio-path', return {
playIndex:0, title: 'audio-path',
isPlaying: false, playIndex: 0,
_audioContext: null as InnerAudioContext | null, isPlaying: false,
supportPaths: [ _audioContext: null as InnerAudioContext | null,
{ supportPaths: [
description: '本地路径:/static方式', {
src: '/static/test-audio/ForElise.mp3' description: '本地路径:/static方式',
}, src: '/static/test-audio/ForElise.mp3'
{ },
description: '本地路径:../static/', {
src: '../../../static/test-audio/ForElise.mp3' description: '本地路径:../static/',
}, src: '../../../static/test-audio/ForElise.mp3'
{ },
description: '网络路径', {
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3' description: '网络路径',
}, src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
{ },
description: '不存在的音频', {
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/invalid_url.mp3' description: '不存在的音频',
}, src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/invalid_url.mp3'
{ },
description: '错误路径', {
src: '../static/test-audio/ForElise.mp3' description: '错误路径',
}, src: '../static/test-audio/ForElise.mp3'
] as Array<AudioPath> },
} ] as Array<AudioPath>
}, }
onReady() { },
this._audioContext = uni.createInnerAudioContext(); onReady() {
}, this._audioContext = uni.createInnerAudioContext();
onUnload() { },
if (this._audioContext != null) { onUnload() {
this.pause(); if (this._audioContext != null) {
this._audioContext!.destroy() this.pause();
} this._audioContext!.destroy()
}, }
methods: { },
pause() { methods: {
this._audioContext!.pause(); pause() {
this.isPlaying = false; this._audioContext!.pause();
}, this.isPlaying = false;
play(audioUrl,index){ },
// console.log(index,audioUrl); play(audioUrl, index) {
if (this.isPlaying && this.playIndex == index) { // console.log(index,audioUrl);
this.pause(); if (this.isPlaying && this.playIndex == index) {
return; this.pause();
} return;
this.playIndex = index }
this._audioContext!.src = audioUrl; this.playIndex = index
this._audioContext!.play(); this._audioContext!.src = audioUrl;
this.isPlaying = true; this._audioContext!.play();
this._audioContext!.onPlay(() => { this.isPlaying = true;
console.log('开始播放'); this._audioContext!.onPlay(() => {
}); console.log('开始播放');
this._audioContext!.onEnded(() => { });
console.log('播放结束'); this._audioContext!.onEnded(() => {
this.isPlaying = false; console.log('播放结束');
}); this.isPlaying = false;
this._audioContext!.onError((err) => { });
this.isPlaying = false; this._audioContext!.onError((err) => {
console.log('err',err); this.isPlaying = false;
}); console.log('err', err);
} });
} }
} }
</script> }
</script>
<style>
.formats{ <style>
align-items: center; .formats {
} align-items: center;
.icon-play { }
width: 60px;
height: 60px; .icon-play {
margin: 10px; width: 60px;
} height: 60px;
margin: 10px;
}
</style> </style>
<template> <template>
<page-head title="插屏广告"></page-head> <page-head title="插屏广告"></page-head>
<button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button> <button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
btnText: "", btnText: "",
btnType: "primary", btnType: "primary",
btnDisable: false, btnDisable: false,
interstitialAd: null as InterstitialAd | null, interstitialAd: null as InterstitialAd | null,
isAdLoadSuccess: false isAdLoadSuccess: false
} }
}, },
onReady() { onReady() {
this.loadAd() this.loadAd()
}, },
methods: { methods: {
loadAd() { loadAd() {
if (this.btnDisable) if (this.btnDisable)
return return
this.btnDisable = true this.btnDisable = true
this.btnText = "正在加载广告" this.btnText = "正在加载广告"
this.btnType = "primary" this.btnType = "primary"
if (this.interstitialAd == null) { if (this.interstitialAd == null) {
this.interstitialAd = uni.createInterstitialAd({ this.interstitialAd = uni.createInterstitialAd({
adpid: "1111111113" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换 adpid: "1111111113" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换
}) })
this.interstitialAd!.onError((_) => { this.interstitialAd!.onError((_) => {
this.btnType = "warn" this.btnType = "warn"
this.btnText = "广告加载失败,点击重试" this.btnText = "广告加载失败,点击重试"
this.btnDisable = false this.btnDisable = false
}) })
this.interstitialAd!.onLoad((_) => { this.interstitialAd!.onLoad((_) => {
this.btnType = "primary" this.btnType = "primary"
this.btnText = "广告加载成功,点击观看" this.btnText = "广告加载成功,点击观看"
this.btnDisable = false this.btnDisable = false
this.isAdLoadSuccess = true this.isAdLoadSuccess = true
}) })
this.interstitialAd!.onClose((e) => { this.interstitialAd!.onClose((e) => {
this.isAdLoadSuccess = false this.isAdLoadSuccess = false
this.loadAd() this.loadAd()
}) })
} }
this.interstitialAd!.load() this.interstitialAd!.load()
}, },
showAd() { showAd() {
if (this.isAdLoadSuccess) { if (this.isAdLoadSuccess) {
this.interstitialAd!.show() this.interstitialAd!.show()
} else { } else {
this.loadAd() this.loadAd()
} }
} }
} }
} }
</script> </script>
<style> <style>
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view style="flex:1"> <scroll-view style="flex:1">
<!-- #endif --> <!-- #endif -->
<page-head title="权限申请监听"></page-head> <page-head title="权限申请监听"></page-head>
<view class="permission-alert" id="permission-alert" :style="{'transform':isPermissionAlertShow ? 'translateY(0)':'translateY(-110px)'}"> <view class="permission-alert" id="permission-alert"
<text style="font-size: 20px;margin-bottom: 10px;margin-top: 5px;">访问日历权限申请说明:</text> :style="{'transform':isPermissionAlertShow ? 'translateY(0)':'translateY(-110px)'}">
<text style="color: darkgray;">uni-app x正在申请访问日历权限用于演示,允许或拒绝均不会获取任何隐私信息。</text> <text style="font-size: 20px;margin-bottom: 10px;margin-top: 5px;">访问日历权限申请说明:</text>
</view> <text style="color: darkgray;">uni-app x正在申请访问日历权限用于演示,允许或拒绝均不会获取任何隐私信息。</text>
<button type="primary" style="margin: 10px;" @click="requestPermission">点击申请日历权限</button> </view>
<button type="primary" style="margin: 10px;" @click="requestPermission">点击申请日历权限</button>
<!-- #ifdef APP -->
</scroll-view> <!-- #ifdef APP -->
<!-- #endif --> </scroll-view>
</template> <!-- #endif -->
</template>
<script>
export default { <script>
data() { export default {
return { data() {
isPermissionAlertShow: false, return {
permissionAlert: null as UniElement | null, isPermissionAlertShow: false,
timeoutId: -1, permissionAlert: null as UniElement | null,
permissionListener: null as RequestPermissionListener | null timeoutId: -1,
} permissionListener: null as RequestPermissionListener | null
}, }
},
onReady() {
this.watchPermissionRRequest() onReady() {
}, this.watchPermissionRRequest()
onUnload() { },
this.permissionListener?.stop() onUnload() {
this.permissionListener = null this.permissionListener?.stop()
clearTimeout(this.timeoutId) this.permissionListener = null
}, clearTimeout(this.timeoutId)
methods: { },
watchPermissionRRequest() { methods: {
this.permissionListener = uni.createRequestPermissionListener() watchPermissionRRequest() {
this.permissionListener!.onConfirm((_) => { this.permissionListener = uni.createRequestPermissionListener()
// TODO 目前onConfirm监听实现的在时间上不够精确,暂时需要延迟弹框,后续修复 this.permissionListener!.onConfirm((_) => {
// TODO 这里的弹框仅为演示,实际开发中监听权限申请的代码应该在app.uvue中,弹框应全局处理,可参考https://gitcode.net/dcloud/uni-api/-/tree/master/uni_modules/uni-prompt/utssdk/app-android 代码自行封装一个uts的全局弹框 // TODO 目前onConfirm监听实现的在时间上不够精确,暂时需要延迟弹框,后续修复
this.timeoutId = setTimeout(() => { // TODO 这里的弹框仅为演示,实际开发中监听权限申请的代码应该在app.uvue中,弹框应全局处理,可参考https://gitcode.net/dcloud/uni-api/-/tree/master/uni_modules/uni-prompt/utssdk/app-android 代码自行封装一个uts的全局弹框
this.isPermissionAlertShow = true this.timeoutId = setTimeout(() => {
}, 100) this.isPermissionAlertShow = true
}) }, 100)
this.permissionListener!.onComplete((_) => { })
clearTimeout(this.timeoutId) this.permissionListener!.onComplete((_) => {
this.isPermissionAlertShow = false clearTimeout(this.timeoutId)
}) this.isPermissionAlertShow = false
}, })
requestPermission() { },
// #ifdef APP-ANDROID requestPermission() {
if (UTSAndroid.checkSystemPermissionGranted(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"])) { // #ifdef APP-ANDROID
uni.showToast({ if (UTSAndroid.checkSystemPermissionGranted(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"])) {
title: "权限已经同意了,不需要再申请", uni.showToast({
position: "bottom" title: "权限已经同意了,不需要再申请",
}) position: "bottom"
return })
} return
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"], (_ : boolean, p : string[]) => { }
console.log(p) UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, ["android.permission.READ_CALENDAR"], (_ : boolean, p : string[]) => {
}, (_ : boolean, p : string[]) => { console.log(p)
uni.showToast({ }, (_ : boolean, p : string[]) => {
title: "权限被拒绝了", uni.showToast({
position: "bottom" title: "权限被拒绝了",
}) position: "bottom"
console.log(p) })
}) console.log(p)
// #endif })
} // #endif
} }
} }
</script> }
</script>
<style>
.permission-alert { <style>
width: 90%; .permission-alert {
height: 100px; width: 90%;
margin: 10px 5%; height: 100px;
position: absolute; margin: 10px 5%;
top: 0px; position: absolute;
z-index: 3; top: 0px;
border-radius: 5px; z-index: 3;
transition-property: transform; border-radius: 5px;
transition-duration: 200ms; transition-property: transform;
background-color: white; transition-duration: 200ms;
padding: 10px; background-color: white;
} padding: 10px;
}
</style> </style>
<template> <template>
<page-head title="激励视频广告"></page-head> <page-head title="激励视频广告"></page-head>
<button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button> <button :type="btnType" style="margin: 10px;" :disabled="btnDisable" @click="showAd()">{{btnText}}</button>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
btnText: "", btnText: "",
btnType: "primary", btnType: "primary",
btnDisable: false, btnDisable: false,
rewardAd: null as RewardedVideoAd | null, rewardAd: null as RewardedVideoAd | null,
isAdLoadSuccess: false isAdLoadSuccess: false
} }
}, },
onReady() { onReady() {
this.loadAd() this.loadAd()
}, },
methods: { methods: {
loadAd() { loadAd() {
if (this.btnDisable) if (this.btnDisable)
return return
this.btnDisable = true this.btnDisable = true
this.btnText = "正在加载广告" this.btnText = "正在加载广告"
this.btnType = "primary" this.btnType = "primary"
if (this.rewardAd == null) { if (this.rewardAd == null) {
this.rewardAd = uni.createRewardedVideoAd({ this.rewardAd = uni.createRewardedVideoAd({
adpid: "1507000689" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换 adpid: "1507000689" //此处为测试广告位,实际开发中请在uni-ad后台申请自己的广告位后替换
}) })
this.rewardAd!.onError((_) => { this.rewardAd!.onError((_) => {
this.btnType = "warn" this.btnType = "warn"
this.btnText = "广告加载失败,点击重试" this.btnText = "广告加载失败,点击重试"
this.btnDisable = false this.btnDisable = false
}) })
this.rewardAd!.onLoad((_) => { this.rewardAd!.onLoad((_) => {
this.btnType = "primary" this.btnType = "primary"
this.btnText = "广告加载成功,点击观看" this.btnText = "广告加载成功,点击观看"
this.btnDisable = false this.btnDisable = false
this.isAdLoadSuccess = true this.isAdLoadSuccess = true
}) })
this.rewardAd!.onClose((e) => { this.rewardAd!.onClose((e) => {
// 测试广告位无法通过服务器回调。实际开发中,使用自己的广告位后,需参考uni-ad文档编写服务器回调的代码,在服务端发放奖励 // 测试广告位无法通过服务器回调。实际开发中,使用自己的广告位后,需参考uni-ad文档编写服务器回调的代码,在服务端发放奖励
this.isAdLoadSuccess = false this.isAdLoadSuccess = false
uni.showToast({ uni.showToast({
title: "激励视频" + (e.isEnded ? "" : "未") + "播放完毕", title: "激励视频" + (e.isEnded ? "" : "未") + "播放完毕",
position: "bottom" position: "bottom"
}) })
this.loadAd() this.loadAd()
}) })
} }
this.rewardAd!.load() this.rewardAd!.load()
}, },
showAd() { showAd() {
if (this.isAdLoadSuccess) { if (this.isAdLoadSuccess) {
this.rewardAd!.show() this.rewardAd!.show()
} else { } else {
this.loadAd() this.loadAd()
} }
} }
} }
} }
</script> </script>
<style> <style>
</style> </style>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view class="page-scroll-view"> <scroll-view class="page-scroll-view">
<!-- #endif --> <!-- #endif -->
<view class="page" id="page"> <view class="page" id="page">
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button> <button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button>
<button class="btn btn-get-all-node-info" @click="getAllNodeInfo">getAllNodeInfo</button> <button class="btn btn-get-all-node-info" @click="getAllNodeInfo">getAllNodeInfo</button>
<view id="rect-1-2" class="rect-1-2"> <view id="rect-1-2" class="rect-1-2">
<view class="rect rect1"></view> <view class="rect rect1"></view>
<view class="rect rect2"></view> <view class="rect rect2"></view>
</view> </view>
<view class="rect-info-1-2"> <view class="rect-info-1-2">
<view class="rect-info" v-for="(nodeInfo, index) in nodeInfoList" :key="index"> <view class="rect-info" v-for="(nodeInfo, index) in nodeInfoList" :key="index">
<view class="node-info-item"> <view class="node-info-item">
<text class="node-info-item-k">left: </text> <text class="node-info-item-k">left: </text>
<text class="node-info-item-v">{{nodeInfo.left}}</text> <text class="node-info-item-v">{{nodeInfo.left}}</text>
</view> </view>
<view class="node-info-item"> <view class="node-info-item">
<text class="node-info-item-k">top: </text> <text class="node-info-item-k">top: </text>
<text class="node-info-item-v">{{nodeInfo.top}}</text> <text class="node-info-item-v">{{nodeInfo.top}}</text>
</view> </view>
<view class="node-info-item"> <view class="node-info-item">
<text class="node-info-item-k">right: </text> <text class="node-info-item-k">right: </text>
<text class="node-info-item-v">{{nodeInfo.right}}</text> <text class="node-info-item-v">{{nodeInfo.right}}</text>
</view> </view>
<view class="node-info-item"> <view class="node-info-item">
<text class="node-info-item-k">bottom: </text> <text class="node-info-item-k">bottom: </text>
<text class="node-info-item-v">{{nodeInfo.bottom}}</text> <text class="node-info-item-v">{{nodeInfo.bottom}}</text>
</view> </view>
<view class="node-info-item"> <view class="node-info-item">
<text class="node-info-item-k">width: </text> <text class="node-info-item-k">width: </text>
<text class="node-info-item-v">{{nodeInfo.width}}</text> <text class="node-info-item-v">{{nodeInfo.width}}</text>
</view> </view>
<view class="node-info-item"> <view class="node-info-item">
<text class="node-info-item-k">height: </text> <text class="node-info-item-k">height: </text>
<text class="node-info-item-v">{{nodeInfo.height}}</text> <text class="node-info-item-v">{{nodeInfo.height}}</text>
</view>
</view> </view>
</view> </view>
</view> <node-child class="node-child"></node-child>
<node-child class="node-child"></node-child> <text>子组件多根节点</text>
<text>子组件多根节点</text> <multi-child ref="multi-child" id="multi-child"></multi-child>
<multi-child ref="multi-child" id="multi-child"></multi-child> <text>子组件多根节点(仅测试,用于验证查询是否超出范围)</text>
<text>子组件多根节点(仅测试,用于验证查询是否超出范围)</text> <multi-child id="multi-child-2"></multi-child>
<multi-child id="multi-child-2"></multi-child> <view>
<view> <text>测试.fields</text>
<text>测试.fields</text> <text>{{fieldsResultContainNode}}</text>
<text>{{fieldsResultContainNode}}</text> </view>
</view> <view>
<view> <text>测试.node</text>
<text>测试.node</text> <text>{{nodeResultContainNode}}</text>
<text>{{nodeResultContainNode}}</text> </view>
</view> <canvas id="canvas1"></canvas>
<canvas id="canvas1"></canvas> </view>
</view> <!-- #ifdef APP -->
<!-- #ifdef APP --> </scroll-view>
</scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
import nodeChild from './nodes-info-child.uvue' import nodeChild from './nodes-info-child.uvue'
import multiChild from './selector-query-child-multi.uvue' import multiChild from './selector-query-child-multi.uvue'
type NodeInfoType = { type NodeInfoType = {
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
export default { export default {
components: { components: {
nodeChild, nodeChild,
multiChild multiChild
}, },
data() { data() {
...@@ -83,21 +83,21 @@ ...@@ -83,21 +83,21 @@
// 仅用于自动化测试 // 仅用于自动化测试
rootNodeInfo: null as NodeInfoType | null, rootNodeInfo: null as NodeInfoType | null,
//供自动化测试使用 //供自动化测试使用
// resizeRectValid: false // resizeRectValid: false
// TODO // TODO
selectCount: 0, selectCount: 0,
selectAllCount: 0, selectAllCount: 0,
fieldsResultContainNode: false, fieldsResultContainNode: false,
nodeResultContainNode: false nodeResultContainNode: false
} }
}, },
onReady() { onReady() {
const instance2 = (this.$refs['multi-child'] as ComponentPublicInstance) const instance2 = (this.$refs['multi-child'] as ComponentPublicInstance)
this.selectCount = instance2.$data['selectCount'] as number this.selectCount = instance2.$data['selectCount'] as number
this.selectAllCount = instance2.$data['selectAllCount'] as number this.selectAllCount = instance2.$data['selectAllCount'] as number
this.testFields() this.testFields()
this.testNode() this.testNode()
}, },
onResize() { onResize() {
//供自动化测试使用 //供自动化测试使用
...@@ -156,31 +156,31 @@ ...@@ -156,31 +156,31 @@
} as NodeInfoType) } as NodeInfoType)
}) })
}) })
}, },
// test .fields // test .fields
testFields() { testFields() {
uni.createSelectorQuery().select('.rect1').fields({ uni.createSelectorQuery().select('.rect1').fields({
node: true node: true
} as NodeField, (ret) => { } as NodeField, (ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement const isElement = (ret as NodeInfo).node instanceof UniElement
if(isElement){ if (isElement) {
this.fieldsResultContainNode = true this.fieldsResultContainNode = true
} else { } else {
this.fieldsResultContainNode = false this.fieldsResultContainNode = false
} }
}).exec() }).exec()
}, },
// test .node // test .node
testNode() { testNode() {
uni.createSelectorQuery().select('#canvas1').node((ret) => { uni.createSelectorQuery().select('#canvas1').node((ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement const isElement = (ret as NodeInfo).node instanceof UniElement
const isCanvasElement = ((ret as NodeInfo).node as UniCanvasElement).tagName == 'CANVAS' const isCanvasElement = ((ret as NodeInfo).node as UniCanvasElement).tagName == 'CANVAS'
if(isElement && isCanvasElement){ if (isElement && isCanvasElement) {
this.nodeResultContainNode = true this.nodeResultContainNode = true
} else { } else {
this.nodeResultContainNode = false this.nodeResultContainNode = false
} }
}).exec() }).exec()
}, },
} }
} }
......
...@@ -12,18 +12,18 @@ ...@@ -12,18 +12,18 @@
} }
}, },
mounted() { mounted() {
uni.createSelectorQuery().in(this).select('.selector-query-child-view').boundingClientRect().exec((ret) => { uni.createSelectorQuery().in(this).select('.selector-query-child-view').boundingClientRect().exec((ret) => {
if (ret.length == 1) { if (ret.length == 1) {
const nodeInfo = ret[0] as NodeInfo; const nodeInfo = ret[0] as NodeInfo;
this.top = nodeInfo.top! this.top = nodeInfo.top!
} }
}) })
} }
} }
</script> </script>
<style> <style>
.selector-query-child-view { .selector-query-child-view {
margin-top: 15px; margin-top: 15px;
} }
</style> </style>
...@@ -17,25 +17,25 @@ ...@@ -17,25 +17,25 @@
return { return {
text1: "", text1: "",
text2: "", text2: "",
text3: "test-text-node", text3: "test-text-node",
viewCount: 0, viewCount: 0,
selectCount: 0, selectCount: 0,
selectAllCount: 0, selectAllCount: 0,
show: false show: false
} }
}, },
mounted() { mounted() {
uni.createSelectorQuery().in(this).select('.selector-query-view').boundingClientRect().exec((ret) => { uni.createSelectorQuery().in(this).select('.selector-query-view').boundingClientRect().exec((ret) => {
this.text1 = JSON.stringify(ret, null, 2) this.text1 = JSON.stringify(ret, null, 2)
if (ret.length == 1) { if (ret.length == 1) {
this.selectCount = ret.length this.selectCount = ret.length
}
})
uni.createSelectorQuery().in(this).selectAll('.selector-query-view').boundingClientRect().exec((ret) => {
this.text2 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectAllCount = (ret[0] as NodeInfo[]).length
} }
})
uni.createSelectorQuery().in(this).selectAll('.selector-query-view').boundingClientRect().exec((ret) => {
this.text2 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectAllCount = (ret[0] as NodeInfo[]).length
}
}) })
} }
} }
......
...@@ -54,14 +54,14 @@ ...@@ -54,14 +54,14 @@
) { ) {
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
} }
dialogPage.$emit('fn1', {from: 'dialog1'}) dialogPage.$emit('fn1', { from: 'dialog1' })
dialogPage.$emit('fn2', null) dialogPage.$emit('fn2', null)
dialogPage.$off('fn2', null) dialogPage.$off('fn2', null)
dialogPage.$emit('fn1', {from: 'dialog1'}) dialogPage.$emit('fn1', { from: 'dialog1' })
dialogPage.$emit('fn2', null) dialogPage.$emit('fn2', null)
dialogPage.$emit('fnOnce', null) dialogPage.$emit('fnOnce', null)
dialogPage.$emit('fnOnce', null) dialogPage.$emit('fnOnce', null)
}, },
onHide() { onHide() {
......
...@@ -75,18 +75,18 @@ ...@@ -75,18 +75,18 @@
closeDialog() { closeDialog() {
uni.closeDialogPage({ uni.closeDialogPage({
success(res) { success(res) {
console.log('closeDialog success', res) console.log('closeDialog success', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
}, },
fail(err) { fail(err) {
console.log('closeDialog fail', err) console.log('closeDialog fail', err)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4) setLifeCycleNum(state.lifeCycleNum - 4)
}, },
complete(res) { complete(res) {
console.log('closeDialog complete', res) console.log('closeDialog complete', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
} }
}) })
...@@ -95,18 +95,18 @@ ...@@ -95,18 +95,18 @@
uni.closeDialogPage({ uni.closeDialogPage({
dialogPage: this.$dialogPage, dialogPage: this.$dialogPage,
success(res) { success(res) {
console.log('closeThisDialog success', res) console.log('closeThisDialog success', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
}, },
fail(err) { fail(err) {
console.log('closeThisDialog fail', err) console.log('closeThisDialog fail', err)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4) setLifeCycleNum(state.lifeCycleNum - 4)
}, },
complete(res) { complete(res) {
console.log('closeThisDialog complete', res) console.log('closeThisDialog complete', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
} }
}) })
......
...@@ -41,41 +41,41 @@ ...@@ -41,41 +41,41 @@
}, },
openDialog1() { openDialog1() {
const dialogPage = uni.openDialogPage({ const dialogPage = uni.openDialogPage({
url: '/pages/API/dialog-page/dialog-1?name=dialog1', url: '/pages/API/dialog-page/dialog-1?name=dialog1',
success(res) { success(res) {
console.log('openDialogPage1 success', res) console.log('openDialogPage1 success', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
}, },
fail(err) { fail(err) {
console.log('openDialogPage1 fail', err) console.log('openDialogPage1 fail', err)
setLifeCycleNum(state.lifeCycleNum - 4) setLifeCycleNum(state.lifeCycleNum - 4)
}, },
complete(res) { complete(res) {
console.log('openDialogPage1 complete', res) console.log('openDialogPage1 complete', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1)
}
}) !
const fn1 = (options: any | null) => {
console.log('dialogPage1 be triggered fn1', options)
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
} }
})! const fn11 = (options: any | null) => {
const fn1 = (options: any | null) => { console.log('dialogPage1 be triggered fn11', options)
console.log('dialogPage1 be triggered fn1', options) setLifeCycleNum(state.lifeCycleNum + 1)
setLifeCycleNum(state.lifeCycleNum + 1) }
} const fn2 = (options: any | null) => {
const fn11 = (options: any | null) => { console.log('dialogPage1 be triggered fn2', options)
console.log('dialogPage1 be triggered fn11', options) setLifeCycleNum(state.lifeCycleNum + 1)
setLifeCycleNum(state.lifeCycleNum + 1) }
} const fnOnce = (options: any | null) => {
const fn2 = (options: any | null) => { console.log('dialogPage1 be triggered fnOnce', options)
console.log('dialogPage1 be triggered fn2', options) setLifeCycleNum(state.lifeCycleNum + 1)
setLifeCycleNum(state.lifeCycleNum + 1) }
} dialogPage.$on('fn1', fn1)
const fnOnce = (options: any | null) => { dialogPage.$on('fn1', fn11)
console.log('dialogPage1 be triggered fnOnce', options) dialogPage.$on('fn2', fn2)
setLifeCycleNum(state.lifeCycleNum + 1)
}
dialogPage.$on('fn1', fn1)
dialogPage.$on('fn1', fn11)
dialogPage.$on('fn2', fn2)
dialogPage.$once('fnOnce', fnOnce) dialogPage.$once('fnOnce', fnOnce)
}, },
openDialog2() { openDialog2() {
......
...@@ -63,25 +63,25 @@ ...@@ -63,25 +63,25 @@
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
} }
}) })
}, },
closeDialog() { closeDialog() {
uni.closeDialogPage({ uni.closeDialogPage({
success(res) { success(res) {
console.log('closeDialog success', res) console.log('closeDialog success', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
}, },
fail(err) { fail(err) {
console.log('closeDialog fail', err) console.log('closeDialog fail', err)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum - 4) setLifeCycleNum(state.lifeCycleNum - 4)
}, },
complete(res) { complete(res) {
console.log('closeDialog complete', res) console.log('closeDialog complete', res)
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1) setLifeCycleNum(state.lifeCycleNum + 1)
} }
}) })
}, },
openDialogPage1ToHomePage() { openDialogPage1ToHomePage() {
const pages = getCurrentPages() const pages = getCurrentPages()
...@@ -98,12 +98,12 @@ ...@@ -98,12 +98,12 @@
console.log('openDialogPage1ToHomePage complete', res) console.log('openDialogPage1ToHomePage complete', res)
} }
}) })
}, },
setLifeCycleNum(value: number) { setLifeCycleNum(value: number) {
setLifeCycleNum(value) setLifeCycleNum(value)
}, },
getLifeCycleNum(): number { getLifeCycleNum(): number {
return state.lifeCycleNum return state.lifeCycleNum
} }
} }
} }
......
...@@ -18,14 +18,13 @@ ...@@ -18,14 +18,13 @@
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
// #ifdef APP
// #ifdef APP import {
import { testInovkeDownloadFile,
testInovkeDownloadFile, CommonOptions
CommonOptions } from '@/uni_modules/test-invoke-network-api'
} from '@/uni_modules/test-invoke-network-api' // #endif
// #endif
export default { export default {
data() { data() {
...@@ -58,10 +57,10 @@ ...@@ -58,10 +57,10 @@
}, },
fail: (err) => { fail: (err) => {
console.log('downloadFile fail, err is:', err) console.log('downloadFile fail, err is:', err)
}, },
complete: (res) => { complete: (res) => {
uni.hideLoading(); uni.hideLoading();
this.task = null; this.task = null;
} }
}); });
this.task?.onProgressUpdate((update) => { this.task?.onProgressUpdate((update) => {
...@@ -79,87 +78,87 @@ ...@@ -79,87 +78,87 @@
this.jest_result = false this.jest_result = false
} }
}); });
}, },
jest_downloadFile_with_uni_env() { jest_downloadFile_with_uni_env() {
uni.downloadFile({ uni.downloadFile({
url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png", url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
filePath: `${uni.env.CACHE_PATH}/a/b/`, filePath: `${uni.env.CACHE_PATH}/a/b/`,
success: () => { success: () => {
this.jest_result = true this.jest_result = true
}, },
fail: () => { fail: () => {
this.jest_result = false this.jest_result = false
} }
}); });
}, },
jest_set_cookie(){ jest_set_cookie() {
uni.request({ uni.request({
url: "https://request.dcloud.net.cn/api/http/header/setCookie", url: "https://request.dcloud.net.cn/api/http/header/setCookie",
method: "GET", method: "GET",
timeout: 6000, timeout: 6000,
sslVerify: false, sslVerify: false,
withCredentials: true, withCredentials: true,
firstIpv4: false, firstIpv4: false,
success: () => { success: () => {
this.jest_cookie_download(true) this.jest_cookie_download(true)
}, },
fail: () => { fail: () => {
this.jest_result = false; this.jest_result = false;
}, },
}); });
}, },
jest_delete_cookie(){ jest_delete_cookie() {
uni.request({ uni.request({
url: "https://request.dcloud.net.cn/api/http/header/deleteCookie", url: "https://request.dcloud.net.cn/api/http/header/deleteCookie",
method: "GET", method: "GET",
timeout: 6000, timeout: 6000,
sslVerify: false, sslVerify: false,
withCredentials: true, withCredentials: true,
firstIpv4: false, firstIpv4: false,
success: () => { success: () => {
this.jest_cookie_download(false) this.jest_cookie_download(false)
}, },
fail: () => { fail: () => {
this.jest_result = false; this.jest_result = false;
}, },
}); });
}, },
jest_cookie_download(needCookie: boolean){ jest_cookie_download(needCookie : boolean) {
uni.downloadFile({ uni.downloadFile({
url: "https://request.dcloud.net.cn/api/http/header/download", url: "https://request.dcloud.net.cn/api/http/header/download",
success: () => { success: () => {
this.jest_result = needCookie ? true : false; this.jest_result = needCookie ? true : false;
}, },
fail: () => { fail: () => {
this.jest_result = needCookie ? false : true; this.jest_result = needCookie ? false : true;
} }
}); });
}, },
jest_uts_module_invoked(){ jest_uts_module_invoked() {
// #ifdef APP // #ifdef APP
testInovkeDownloadFile({ testInovkeDownloadFile({
success:(res: any)=>{ success: (res : any) => {
this.jest_result = true this.jest_result = true
}, },
fail:(err: any)=>{ fail: (err : any) => {
this.jest_result = false this.jest_result = false
} }
} as CommonOptions) } as CommonOptions)
// #endif // #endif
}, },
jest_special_characters_download(){ jest_special_characters_download() {
uni.downloadFile({ uni.downloadFile({
url: "https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/1789834995055525889-你好%23你好.png", url: "https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/1789834995055525889-你好%23你好.png",
success: (res: DownloadFileSuccess) => { success: (res : DownloadFileSuccess) => {
this.jest_result = true; this.jest_result = true;
}, },
fail: () => { fail: () => {
this.jest_result = false; this.jest_result = false;
} }
}); });
} }
} }
} }
......
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view class="page-scroll-view"> <scroll-view class="page-scroll-view">
<!-- #endif --> <!-- #endif -->
<view> <view>
<view class="drawing" id="draw-text-view"></view> <view class="drawing" id="draw-text-view"></view>
<view class="drawing" id="draw-line-view"></view> <view class="drawing" id="draw-line-view"></view>
<view class="drawing" id="draw-circle-view"></view> <view class="drawing" id="draw-circle-view"></view>
<view class="drawing" id="draw-dash-line"></view> <view class="drawing" id="draw-dash-line"></view>
<view class="drawing" id="draw-house"></view> <view class="drawing" id="draw-house"></view>
<view class="drawing" id="draw-style"></view> <view class="drawing" id="draw-style"></view>
<view class="drawing" id="draw-odd"></view> <view class="drawing" id="draw-odd"></view>
<view class="drawing" id="draw-arcto"></view> <view class="drawing" id="draw-arcto"></view>
</view> </view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
var y = 160 var y = 160
export default { export default {
data() { data() {
return { return {
texts: [ texts: [
'HBuilderX,轻巧、极速,极客编辑器', 'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案', 'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务', 'uniCloud,js serverless云服务',
'uts,大一统语言', 'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力', 'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台', 'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心', 'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付', 'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力', 'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台', 'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息', 'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表', 'uni统计,开源、完善、全平台的统计报表',
'......' '......'
] as string[] ] as string[]
} }
}, },
onShow() { onShow() {
}, },
onReady() { onReady() {
this.drawText() this.drawText()
this.drawLines() this.drawLines()
this.drawCircles() this.drawCircles()
this.drawStar() this.drawStar()
this.drawhouse() this.drawhouse()
this.drawPoint() this.drawPoint()
this.drawRect() this.drawRect()
this.drawArcTo() this.drawArcTo()
}, },
onUnload() { onUnload() {
y = 160 y = 160
}, },
methods: { methods: {
drawText() { drawText() {
let element = uni.getElementById('draw-text-view')! let element = uni.getElementById('draw-text-view')!
let ctx = element.getDrawableContext()! let ctx = element.getDrawableContext()!
let width = element.getBoundingClientRect().width let width = element.getBoundingClientRect().width
ctx.reset() ctx.reset()
ctx.font = "15px Arial" ctx.font = "15px Arial"
ctx.textAlign = "center" ctx.textAlign = "center"
for (var i = 0; i < this.texts.length; i++) { for (var i = 0; i < this.texts.length; i++) {
let value = this.texts[i] let value = this.texts[i]
if (i % 2 == 0) { if (i % 2 == 0) {
ctx.fillText(value, width / 2, (20 * (i + 1))) ctx.fillText(value, width / 2, (20 * (i + 1)))
} else { } else {
ctx.lineWidth = 0.5 ctx.lineWidth = 0.5
ctx.strokeText(value, width / 2, (20 * (i + 1))) ctx.strokeText(value, width / 2, (20 * (i + 1)))
} }
} }
ctx.update() ctx.update()
}, },
drawLines() { drawLines() {
let ctx = uni.getElementById('draw-line-view')!.getDrawableContext()! let ctx = uni.getElementById('draw-line-view')!.getDrawableContext()!
ctx.reset() ctx.reset()
ctx.lineWidth = 10; ctx.lineWidth = 10;
["round", "bevel", "miter"].forEach((join, i) => { ["round", "bevel", "miter"].forEach((join, i) => {
ctx.lineJoin = join; ctx.lineJoin = join;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(5, 10 + i * 40); ctx.moveTo(5, 10 + i * 40);
ctx.lineTo(50, 50 + i * 40); ctx.lineTo(50, 50 + i * 40);
ctx.lineTo(90, 10 + i * 40); ctx.lineTo(90, 10 + i * 40);
ctx.lineTo(130, 50 + i * 40); ctx.lineTo(130, 50 + i * 40);
ctx.lineTo(170, 10 + i * 40); ctx.lineTo(170, 10 + i * 40);
ctx.stroke(); ctx.stroke();
}); });
ctx.lineWidth = 1 ctx.lineWidth = 1
var space = 170 var space = 170
ctx.strokeStyle = '#09f'; ctx.strokeStyle = '#09f';
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(10 + space, 10); ctx.moveTo(10 + space, 10);
ctx.lineTo(140 + space, 10); ctx.lineTo(140 + space, 10);
ctx.moveTo(10 + space, 140); ctx.moveTo(10 + space, 140);
ctx.lineTo(140 + space, 140); ctx.lineTo(140 + space, 140);
ctx.stroke(); ctx.stroke();
// Draw lines // Draw lines
ctx.strokeStyle = 'black'; ctx.strokeStyle = 'black';
['butt', 'round', 'square'].forEach((lineCap, i) => { ['butt', 'round', 'square'].forEach((lineCap, i) => {
ctx.lineWidth = 15; ctx.lineWidth = 15;
ctx.lineCap = lineCap; ctx.lineCap = lineCap;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(25 + space + i * 50, 10); ctx.moveTo(25 + space + i * 50, 10);
ctx.lineTo(25 + space + i * 50, 140); ctx.lineTo(25 + space + i * 50, 140);
ctx.stroke(); ctx.stroke();
}); });
ctx.lineWidth = 1; ctx.lineWidth = 1;
this.drawDashedLine([], ctx); this.drawDashedLine([], ctx);
this.drawDashedLine([2, 2], ctx); this.drawDashedLine([2, 2], ctx);
this.drawDashedLine([10, 10], ctx); this.drawDashedLine([10, 10], ctx);
this.drawDashedLine([20, 5], ctx); this.drawDashedLine([20, 5], ctx);
this.drawDashedLine([15, 3, 3, 3], ctx); this.drawDashedLine([15, 3, 3, 3], ctx);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx); this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx);
ctx.lineDashOffset = 18; ctx.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx); this.drawDashedLine([12, 3, 3], ctx);
ctx.lineDashOffset = 0 ctx.lineDashOffset = 0
ctx.setLineDash([0]) ctx.setLineDash([0])
ctx.update() ctx.update()
}, },
drawDashedLine(pattern : Array<number>, ctx : DrawableContext) { drawDashedLine(pattern : Array<number>, ctx : DrawableContext) {
ctx.beginPath(); ctx.beginPath();
ctx.setLineDash(pattern); ctx.setLineDash(pattern);
ctx.moveTo(0, y); ctx.moveTo(0, y);
ctx.lineTo(300, y); ctx.lineTo(300, y);
ctx.stroke(); ctx.stroke();
y += 15; y += 15;
}, },
drawCircles() { drawCircles() {
let ctx = uni.getElementById('draw-circle-view')!.getDrawableContext()! let ctx = uni.getElementById('draw-circle-view')!.getDrawableContext()!
ctx.reset() ctx.reset()
// Draw shapes // Draw shapes
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) { for (var j = 0; j < 3; j++) {
ctx.beginPath(); ctx.beginPath();
var x = 25 + j * 50; // x coordinate var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius var radius = 20; // Arc radius
var startAngle = 0; // Starting point on circle var startAngle = 0; // Starting point on circle
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx.arc(x, y, radius, startAngle, endAngle, clockwise); ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
if (i > 1) { if (i > 1) {
ctx.fill(); ctx.fill();
} else { } else {
ctx.stroke(); ctx.stroke();
} }
} }
} }
ctx.update() ctx.update()
}, },
drawStar() { drawStar() {
let ctx = uni.getElementById('draw-dash-line')!.getDrawableContext()! let ctx = uni.getElementById('draw-dash-line')!.getDrawableContext()!
ctx.reset() ctx.reset()
ctx.beginPath(); ctx.beginPath();
var horn = 5; // 画5个角 var horn = 5; // 画5个角
var angle = 360 / horn; // 五个角的度数 var angle = 360 / horn; // 五个角的度数
// 两个圆的半径 // 两个圆的半径
var R = 50; var R = 50;
var r = 20; var r = 20;
// 坐标 // 坐标
var x = 100; var x = 100;
var y = 100; var y = 100;
for (var i = 0; i < horn; i++) { for (var i = 0; i < horn; i++) {
// 角度转弧度:角度/180*Math.PI // 角度转弧度:角度/180*Math.PI
// 外圆顶点坐标 // 外圆顶点坐标
ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y); ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
// 內圆顶点坐标 // 內圆顶点坐标
ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y); ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
} }
// closePath:关闭路径,将路径的终点与起点相连 // closePath:关闭路径,将路径的终点与起点相连
ctx.closePath(); ctx.closePath();
ctx.lineWidth = 3; ctx.lineWidth = 3;
ctx.fillStyle = '#E4EF00'; ctx.fillStyle = '#E4EF00';
ctx.strokeStyle = "red"; ctx.strokeStyle = "red";
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
ctx.lineWidth = 10; ctx.lineWidth = 10;
ctx.beginPath() ctx.beginPath()
ctx.moveTo(170, 100) ctx.moveTo(170, 100)
ctx.lineTo(255, 15) ctx.lineTo(255, 15)
ctx.lineTo(340, 100) ctx.lineTo(340, 100)
ctx.closePath() ctx.closePath()
ctx.fill() ctx.fill()
ctx.strokeStyle = "blue" ctx.strokeStyle = "blue"
ctx.stroke() ctx.stroke()
ctx.beginPath() ctx.beginPath()
ctx.moveTo(170, 145) ctx.moveTo(170, 145)
ctx.lineTo(255, 45) ctx.lineTo(255, 45)
ctx.lineTo(340, 145) ctx.lineTo(340, 145)
ctx.closePath() ctx.closePath()
ctx.fill() ctx.fill()
ctx.strokeStyle = "gray" ctx.strokeStyle = "gray"
ctx.stroke() ctx.stroke()
// 未设置beginPath,导致上下表现一致,与前端一致 // 未设置beginPath,导致上下表现一致,与前端一致
ctx.moveTo(170, 190) ctx.moveTo(170, 190)
ctx.lineTo(255, 90) ctx.lineTo(255, 90)
ctx.lineTo(340, 190) ctx.lineTo(340, 190)
ctx.closePath() ctx.closePath()
ctx.fillStyle = "orange" ctx.fillStyle = "orange"
ctx.fill() ctx.fill()
ctx.strokeStyle = "khaki" ctx.strokeStyle = "khaki"
ctx.stroke() ctx.stroke()
ctx.update() ctx.update()
}, },
hex(num : number) : string { hex(num : number) : string {
if (num == 0) { if (num == 0) {
return "00" return "00"
} }
let hexChars = "0123456789ABCDEF"; let hexChars = "0123456789ABCDEF";
let result = ""; let result = "";
while (num > 0) { while (num > 0) {
let remainder = Math.floor(num) % 16; let remainder = Math.floor(num) % 16;
result = hexChars[remainder] + result; result = hexChars[remainder] + result;
num = Math.floor(Math.floor(num) / 16); num = Math.floor(Math.floor(num) / 16);
} }
if (result.length == 1) { if (result.length == 1) {
return "0" + result return "0" + result
} }
return result return result
}, },
drawhouse() { drawhouse() {
let ctx = uni.getElementById('draw-house')!.getDrawableContext()! let ctx = uni.getElementById('draw-house')!.getDrawableContext()!
ctx.reset() ctx.reset()
ctx.lineWidth = 10; ctx.lineWidth = 10;
// Wall // Wall
ctx.strokeRect(75, 140, 150, 110); ctx.strokeRect(75, 140, 150, 110);
// Door // Door
ctx.fillRect(130, 190, 40, 60); ctx.fillRect(130, 190, 40, 60);
// Roof // Roof
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(50, 140); ctx.moveTo(50, 140);
ctx.lineTo(150, 60); ctx.lineTo(150, 60);
ctx.lineTo(250, 140); ctx.lineTo(250, 140);
ctx.closePath(); ctx.closePath();
ctx.stroke(); ctx.stroke();
ctx.update() ctx.update()
}, },
drawPoint() { drawPoint() {
let ctx = uni.getElementById('draw-style')!.getDrawableContext()! let ctx = uni.getElementById('draw-style')!.getDrawableContext()!
ctx.reset() ctx.reset()
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) { for (let j = 0; j < 6; j++) {
ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`; ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx.beginPath(); ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true); ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke(); ctx.stroke();
} }
} }
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) { for (let j = 0; j < 6; j++) {
ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`; ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx.fillRect(180 + j * 25, i * 25, 25, 25); ctx.fillRect(180 + j * 25, i * 25, 25, 25);
} }
} }
ctx.update() ctx.update()
}, },
drawRect() { drawRect() {
let ctx = uni.getElementById('draw-odd')!.getDrawableContext()! let ctx = uni.getElementById('draw-odd')!.getDrawableContext()!
ctx.reset() ctx.reset()
// Create path // Create path
ctx.moveTo(30, 90); ctx.moveTo(30, 90);
ctx.lineTo(110, 20); ctx.lineTo(110, 20);
ctx.lineTo(240, 130); ctx.lineTo(240, 130);
ctx.lineTo(60, 130); ctx.lineTo(60, 130);
ctx.lineTo(190, 20); ctx.lineTo(190, 20);
ctx.lineTo(270, 90); ctx.lineTo(270, 90);
ctx.closePath(); ctx.closePath();
// Fill path // Fill path
ctx.fillStyle = "green"; ctx.fillStyle = "green";
ctx.fill("evenodd"); ctx.fill("evenodd");
ctx.update() ctx.update()
}, },
drawArcTo() { drawArcTo() {
let ctx = uni.getElementById('draw-arcto')!.getDrawableContext()! let ctx = uni.getElementById('draw-arcto')!.getDrawableContext()!
ctx.reset() ctx.reset()
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(50, 20); ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100); ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke(); ctx.stroke();
ctx.fillStyle = "blue"; ctx.fillStyle = "blue";
// start point // start point
ctx.fillRect(50, 20, 10, 10); ctx.fillRect(50, 20, 10, 10);
// end point // end point
ctx.fillRect(50, 100, 10, 10); ctx.fillRect(50, 100, 10, 10);
ctx.fillStyle = "red"; ctx.fillStyle = "red";
// control point one // control point one
ctx.fillRect(230, 30, 10, 10); ctx.fillRect(230, 30, 10, 10);
// control point two // control point two
ctx.fillRect(150, 70, 10, 10); ctx.fillRect(150, 70, 10, 10);
ctx.update() ctx.update()
} }
} }
} }
</script> </script>
<style> <style>
.drawing { .drawing {
height: 275px; height: 275px;
background-color: lightgray; background-color: lightgray;
margin-bottom: 15px; margin-bottom: 15px;
} }
</style> </style>
此差异已折叠。
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
<view> <view>
<view v-for="(item, index) in log" :key="index">{{ item }}</view> <view v-for="(item, index) in log" :key="index">{{ item }}</view>
</view> </view>
<button @click="onObj">开始监听 obj 参数</button> <button @click="onObj">开始监听 obj 参数</button>
<button @click="emitWithObj">触发监听 obj 参数</button> <button @click="emitWithObj">触发监听 obj 参数</button>
<view class="box"> <view class="box">
<text>接收到的 obj 参数:</text> <text>接收到的 obj 参数:</text>
<text>{{JSON.stringify(objArg)}}</text> <text>{{JSON.stringify(objArg)}}</text>
</view> </view>
</view> </view>
</view> </view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
uni.$on('test', this.fn2) uni.$on('test', this.fn2)
}, },
onObj() { onObj() {
uni.$on('test-obj', (res: UTSJSONObject) => { uni.$on('test-obj', (res : UTSJSONObject) => {
this.objArg = res this.objArg = res
}) })
}, },
...@@ -79,4 +79,4 @@ ...@@ -79,4 +79,4 @@
.box { .box {
padding: 10px; padding: 10px;
} }
</style> </style>
<template> <template>
<view> <view>
<button @tap="exitAppClick">退出应用</button> <button @tap="exitAppClick">退出应用</button>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
methods: { methods: {
exitAppClick:function(){ exitAppClick: function () {
uni.exit({ uni.exit({
success:function(res){ success: function (res) {
console.log(res) console.log(res)
} }
}) })
} }
} }
} }
</script> </script>
<style> <style>
</style> </style>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册