我的订单+我的

This commit is contained in:
2024-06-19 16:12:23 +08:00
parent 5d8aace5cc
commit 132e363be0
473 changed files with 65060 additions and 2742 deletions

View File

@@ -0,0 +1,50 @@
<template>
<view class="volume">
<text class="text">亮度</text>
<view class="process-bar">
<view
class="active-process"
:style="{flex: precent}"
></view>
</view>
</view>
</template>
<script>
export default {
name: 'Brightness',
props: {
currentValue: {
type: Number | String
},
totalValue: {
type: Number | String
}
},
computed: {
precent () {
return this.currentValue / this.totalValue;
}
}
}
</script>
<style lang="stylus" scoped>
.volume
flex-direction row
align-items center
justify-content center
padding 10rpx
background rgba(20, 20, 20, 0.8)
border-radius 2rpx
.text
color #FFFFFF
.process-bar
margin-left 20rpx
width 260rpx
height: 8rpx
flex-direction row
background-color rgba(153, 153, 153, 0.4)
.active-process
background-color #FF920A
</style>

View File

@@ -0,0 +1,307 @@
<template>
<view class="custom-slider">
<image
v-if="minIcon"
class="icon"
:src="minIcon"></image>
<view
ref="slider"
class="slider"
@touchstart.stop="onTouchStart"
@touchmove.stop="onTouchMove"
@touchend.stop="onTouchEnd">
<view class="bar">
<slot></slot>
</view>
<view
class="active-bar-wrapper">
<view
class="active-bar"
:style="{flex: presentShow}"></view>
</view>
<view v-if="step !== 1" class="steps-wrapper">
<template v-for="(step, index) in steps">
<view v-if="index" class="step"></view>
<view class="holder-bar"></view>
</template>
</view>
<view
class="dot-wrapper">
<view
class="holder-bar"
:style="{flex: presentShow}"></view>
<view class="dot"></view>
</view>
<view class="know-area">
<slot name="know"></slot>
</view>
</view>
<image
v-if="maxIcon"
class="icon"
:src="maxIcon"></image>
</view>
</template>
<script>
// 注意平台差异
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
// #endif
import { range, addNumber } from '@/utils/formate.js';
export default {
data() {
return {
dragStatus: '',
size: {
width: 0,
height: 0,
top: 0,
bottom: 0,
left: 0,
right: 0
},
currentValue: 0
}
},
props: {
disabled: Boolean,
vertical: {
type: Boolean,
default: false
},
barHeight: [Number, String],
buttonSize: [Number, String],
activeColor: String,
inactiveColor: String,
min: {
type: Number,
default: 0,
},
minIcon: {
type: String,
default: ''
},
max: {
type: Number,
default: 100,
},
maxIcon: {
type: String,
default: ''
},
step: {
type: Number,
default: 1,
},
value: {
type: Number,
default: 0,
},
isDOMShow: {
type: Boolean,
default: false
}
},
computed: {
scope() {
return this.max - this.min;
},
presentShow () {
return (this.currentValue - this.min) / this.scope;
},
steps () {
return this.scope / this.step
}
},
watch: {
isDOMShow (value) {
this.getSliderSize();
},
value (val) {
this.currentValue = val;
}
},
created() {
// 同步初始值
this.currentValue = this.value;
},
mounted () {
this.getSliderSize();
},
methods: {
touchStart(event) {
this.resetTouchStatus();
this.startX = event.touches[0].screenX;
this.startY = event.touches[0].screenY;
},
touchMove(event) {
const touch = event.touches[0];
// safari back will set clientX to negative number
this.deltaX = touch.screenX < 0 ? 0 : touch.screenX - this.startX;
this.deltaY = touch.screenY - this.startY;
this.offsetX = Math.abs(this.deltaX);
this.offsetY = Math.abs(this.deltaY);
// lock direction when distance is greater than a certain value
const LOCK_DIRECTION_DISTANCE = 10;
if (
!this.direction ||
(this.offsetX < LOCK_DIRECTION_DISTANCE &&
this.offsetY < LOCK_DIRECTION_DISTANCE)
) {
this.direction = this.getDirection(this.offsetX, this.offsetY);
}
},
resetTouchStatus() {
this.direction = '';
this.deltaX = 0;
this.deltaY = 0;
this.offsetX = 0;
this.offsetY = 0;
},
getDirection (x, y) {
if (x > y) {
return 'horizontal';
}
if (y > x) {
return 'vertical';
}
return '';
},
onTouchStart(event) {
console.log('start')
this.touchStart(event);
this.startValue = this.format(this.currentValue);
this.dragStatus = 'start';
this.$emit('dragStart');
},
onTouchMove(event) {
this.touchMove(event);
const rect = this.size;
const delta = this.vertical ? this.deltaY : this.deltaX;
const total = this.vertical ? rect.height : rect.width;
const diff = (delta / total) * this.scope;
// console.log('move', delta);
if (delta === 0) return;
this.dragStatus = 'draging';
this.currentValue = this.startValue + diff;
this.updateValue(this.currentValue, true);
},
onTouchEnd(event) {
console.log('end')
if(this.dragStatus === 'draging') {
this.updateValue(this.currentValue, true);
return;
}
if (this.dragStatus === 'start') {
this.onClick(event);
};
},
onClick(event) {
if (this.disabled) return;
const rect = this.size;
const delta = this.vertical
? event.changedTouches[0].screenY - rect.top
: event.changedTouches[0].screenX - rect.left;
const total = this.vertical ? rect.height : rect.width;
let value = +this.min + (delta / total) * this.scope;
// this.startValue = this.value;
this.updateValue(value, true);
},
updateValue(value, end) {
value = this.format(value);
this.currentValue = value;
this.$emit('changing', value);
if (end) {
this.$emit('change', value);
}
},
format(value) {
const min = +this.min;
const max = +this.max;
const step = +this.step;
value = range(value, min, max);
const diff = parseInt((value - min) / step) * step;
return addNumber(min, diff);
},
isSameValue(newValue, oldValue) {
return JSON.stringify(newValue) === JSON.stringify(oldValue);
},
getSliderSize () {
setTimeout(()=> {
const result = dom.getComponentRect(this.$refs.slider, option => {
this.size = option.size;
})
}, 1000);
}
}
}
</script>
<style lang="stylus" scoped>
.custom-slider
flex-direction row
align-items center
justify-content center
.icon
width 40rpx
height 40rpx
.slider
position relative
margin 0 15rpx
height 78rpx
flex-direction row
align-items center
flex 1
.bar
flex 1
flex-direction row
height 6rpx
background-color rgba(153, 153, 153, 0.4)
.active-bar-wrapper
position absolute
top 0
right 0
bottom 0
left 0
flex-direction row
align-items center
.active-bar
height 6rpx
background-color #FF920A
.steps-wrapper
position absolute
top 0
right 0
bottom 0
left 0
flex-direction row
align-items center
.step
width 6rpx
height 6rpx
background-color #FFFFFF
.holder-bar
flex 1
height: 6rpx
.dot-wrapper
position absolute
top 0
right 0
bottom 0
left 0
flex-direction row
align-items center
.holder-bar
height 6rpx
.dot
width 28rpx
height 28rpx
background-color #FFFFFF
border-radius 100%
.know-area
position absolute
top 0
right 0
bottom 0
left 0
</style>

View File

@@ -0,0 +1,215 @@
<template>
<view
@touchstart.stop="touchstart"
@touchmove.stop="touchmove"
@touchend.stop="touchend">
<slot></slot>
</view>
</template>
<script>
export default {
props: {
holeWidth: Number, // 屏幕宽度(物理像素)
duration: Number, // 视频总时长
currentTime: Number // 视频当前播放时间
},
computed: {
halfWidth() {
return parseInt(this.holeWidth / 2);
}
},
data() {
return {
downLeft: false, // 是否在左区域按下手势
swipeDir: null // 滑动方向
}
},
mounted() {
this.addHandler();
},
methods:{
addHandler() {
// 增加父容器左右滑动监听
let finalTime = -1;
// 计算左右滑动seek进度
const countTime = (position) => {
const { holeWidth, duration, currentTime } = this;
const precent = Math.abs(position) / holeWidth;
const nowTime = currentTime || 0;
let plusTime = parseInt(Math.abs(precent * duration));
if (position < 0) plusTime = plusTime * -1;
finalTime = nowTime + plusTime;
finalTime = this.limit(finalTime, 0, duration);
return finalTime;
};
this.addGesture((type, position) => {
switch (type) {
// 下滑
case -1:
this.$emit('onGestureEvent', {
type: this.downLeft ? 'LEFT_DOWN' : 'RIGHT_DOWN',
position
});
break;
// 上滑
case -2:
this.$emit('onGestureEvent', {
type: this.downLeft ? 'LEFT_UP' : 'RIGHT_UP',
position
});
break;
// 左滑
case 0:
this.swipeDir = type;
countTime(position);
this.$emit('onGestureEvent', {
type: 'SEEK_TIME_UPDATE',
finalTime
});
break;
// 右滑
case 1:
this.swipeDir = type;
countTime(position);
this.$emit('onGestureEvent', {
type: 'SEEK_TIME_UPDATE',
finalTime
});
break;
// touchend for swipe
case 3:
if (this.swipeDir > -1) {
this.$emit('onGestureEvent', {
type: this.swipeDir ? 'SWIPE_RIGHT' : 'SWIPE_LEFT'
});
this.swipeDir = -1;
}
if (finalTime > -1) {
this.$emit('onGestureSeekTo', finalTime);
finalTime = -1;
}
this.$emit('onGestureEvent', {
type: 'TOUCH_END'
});
break;
// doubleTap
case 4:
break;
// tap
case 5:
this.handleClick();
break;
// longTap
case 6:
break;
}
});
},
addGesture(callback) {
const { options } = this;
let startX, startY, moveEndX, moveEndY, X, Y, position, hasType;
let T, lastTap, isJustTouch = true;
const excuteCb = (type) => {
// type 手势类型 -2 上滑 -1 下滑 0 左滑 1 右滑 2 just touch 3 touchend 4 doubleTap 5 tap 6 longTap
if (callback && typeof callback === 'function')
callback(type, position);
};
const isXchange = () => {
if (Math.abs(X) > Math.abs(Y)) {
position = X;
hasType = 'X';
isJustTouch = false;
}
if (X >= 0) excuteCb(1);
// 左滑
else excuteCb(0);
};
const isYchange = () => {
if (Math.abs(Y) > Math.abs(X)) {
position = Y;
hasType = 'Y';
isJustTouch = false;
}
if (Y >= 0) excuteCb(-1);
// 上滑
else excuteCb(-2);
};
const countDirect = () => {
if (hasType) {
hasType === 'X' ? isXchange() : isYchange();
return;
}
if (Math.abs(X) > 5) {
isXchange();
return;
}
if (Math.abs(Y) > 5) {
isYchange();
}
};
this.handleTouch = (type, e) => {
switch(type) {
case 'start':
startX = e.touches[0].screenX;
startY = e.touches[0].screenY;
T = Date.now();
hasType = '';
isJustTouch = true;
this.downLeft = startX < this.halfWidth ? true : false;
break;
case 'move':
moveEndX = e.touches[0].screenX;
moveEndY = e.touches[0].screenY;
X = moveEndX - startX;
Y = moveEndY - startY;
// console.log('Y', Y);
countDirect();
break;
case 'end':
if (isJustTouch)
if (lastTap && Date.now() - lastTap <= 300)
excuteCb(4);
else if (Date.now() - T < 1000)
excuteCb(5);
else
excuteCb(6);
else
excuteCb(3);
lastTap = Date.now();
isJustTouch = true;
break;
}
};
},
handleClick() {
this.$emit('onGestureClick');
},
touchstart(e) {
this.handleTouch('start', e);
},
touchmove(e) {
this.handleTouch('move', e);
},
touchend(e) {
this.handleTouch('end', e);
},
limit(num, min, max) {
if (num < min) return min;
if (num > max) return max;
return num;
}
}
}
</script>
<style></style>

View File

@@ -0,0 +1,44 @@
<template>
<view class="volume">
<text class="text">{{ currentValue }}/{{ totalValue }}</text>
</view>
</template>
<script>
export default {
name: 'Process',
props: {
currentValue: {
type: Number | String
},
totalValue: {
type: Number | String
}
},
computed: {
precent () {
return this.currentValue / this.totalValue;
},
restPrecent () {
return 1 - this.precent;
}
}
}
</script>
<style lang="stylus" scoped>
.volume
flex-direction row
align-items center
justify-content center
padding 10rpx
background rgba(20, 20, 20, 0.8)
border-radius 2rpx
.text
color #FFFFFF
</style>
<style>
</style>

View File

@@ -0,0 +1,41 @@
<template>
<view
class="status-bar">
<component
:is="name"
:current-value="currentValue"
:total-value="totalValue"></component>
</view>
</template>
<script>
import Volume from './Volume.nvue'
import Brightness from'./Brightness.nvue'
import Process from './Process.nvue'
export default {
components: {
Volume,
Brightness,
Process
},
props: {
name: {
type: String,
default: ''
},
currentValue: {
type: Number | String
},
totalValue: {
type: Number | String
}
}
}
</script>
<style lang="stylus" scoped>
.status-bar
flex-direction: row;
align-items: center;
justify-content: center;
</style>

View File

@@ -0,0 +1,50 @@
<template>
<view class="volume">
<text class="text">音量</text>
<view class="process-bar">
<view
class="active-process"
:style="{flex: precent}"
></view>
</view>
</view>
</template>
<script>
export default {
name: 'Volume',
props: {
currentValue: {
type: Number | String
},
totalValue: {
type: Number | String
}
},
computed: {
precent () {
return this.currentValue / this.totalValue;
}
}
}
</script>
<style lang="stylus" scoped>
.volume
flex-direction row
align-items center
justify-content center
padding 10rpx
background rgba(20, 20, 20, 0.8)
border-radius 2rpx
.text
color #FFFFFF
.process-bar
margin-left 20rpx
width 260rpx
height: 8rpx
flex-direction row
background-color rgba(153, 153, 153, 0.4)
.active-process
background-color #FF920A
</style>

View File

@@ -0,0 +1,73 @@
<template>
<view class="container">
<div id="url-player-test"></div>
</view>
</template>
<script>
export default {
mounted() {
// 在适合的生命周期通过script和link标签引入播放器sdk、css
this.loadWebPlayerSDK().then(() => {
// 如果需要使用自定义组件,打开以下注释
// this.loadComponent().then(() => {
let player = new Aliplayer({
id: "url-player-test",
source: "//player.alicdn.com/video/aliyunmedia.mp4",
width: "100%",
height: "100%",
}, function (player) {
});
player.one('canplay', function () {
console.log('canplay', player.tag);
player.tag.play();
});
// }).catch((e) => { console.log("加载组件失败", e) })
}).catch((e) => {
console.log("加载播放器SDK失败", e);
});
},
data() {
return {}
},
methods: {
loadWebPlayerSDK() {
return new Promise((resolve, reject) => {
const s_tag = document.createElement('script'); // 引入播放器js
s_tag.type = 'text/javascript';
s_tag.src = 'https://g.alicdn.com/apsara-media-box/imp-web-player/2.20.3/aliplayer-min.js';
s_tag.charset = 'utf-8';
s_tag.onload = () => {
resolve();
}
document.body.appendChild(s_tag);
const l_tag = document.createElement('link'); // 引入播放器css
l_tag.rel = 'stylesheet';
l_tag.href = 'https://g.alicdn.com/apsara-media-box/imp-web-player/2.20.3/skins/default/aliplayer-min.css';
document.body.appendChild(l_tag);
});
},
loadComponent() {
return new Promise((resolve, reject) => {
const s_tag = document.createElement('script');
s_tag.type = 'text/javascript';
// 需要先下载组件 js 文件,放到项目 /static/ 目录下
// 下载地址https://github.com/aliyunvideo/AliyunPlayer_Web/blob/master/customComponents/dist/aliplayer-components/aliplayercomponents-1.0.9.min.js
s_tag.src = './static/aliplayercomponents-1.0.9.min.js';
s_tag.charset = 'utf-8';
s_tag.onload = () => {
resolve();
}
document.body.appendChild(s_tag);
});
}
}
}
</script>
<style>
.container {
padding: 20px;
font-size: 14px;
height: 800px;
}
</style>