diff --git a/index.html b/index.html index 2899d5b..4004f22 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ <head> <meta charset="UTF-8"/> <link rel="icon" href="/favicon.ico"/> - <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=no" id="viewport" /> <title>Vite App</title> <style> ::-webkit-scrollbar { diff --git a/src/App.vue b/src/App.vue index d143eb7..0901a8d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -6,107 +6,31 @@ </keep-alive> </transition> </router-view> - - <div class="call-float" - v-if="isSmall" - :style="callFloatStyle" - @touchmove="touchmove" - @touchend="touchend" - @click="isSmall = false"> - <img src="@/assets/img/icon/message/chat/call-float.png" alt=""> - <span>呼叫中</span> - </div> - - <transition name="scale"> - <div class="audio-call" - :style="isSmall ? callFloatStyle : {zIndex:10}" - :class="isSmall?'small':''" - v-if="isShowAudioCall"> - <div class="float"> - <div class="header"> - <img @click="isSmall = true" src="@/assets/img/icon/message/chat/narrow.png" alt="" - class="left"> - <div class="center"> - <img src="@/assets/img/icon/avatar/2.png" alt="" class="avatar"> - <span>等待对方接听...</span> - </div> - <div class="right"> - <div class="option"> - <img src="@/assets/img/icon/message/chat/disabled-camera.png" alt=""> - <span>摄像头</span> - </div> - <div class="option"> - <img src="@/assets/img/icon/message/chat/able-volume.png" alt=""> - <span>免提</span> - </div> - <div class="option"> - <back mode="light" img="back" class="shrink"/> - <!-- <img src="@/assets/img/icon/message/chat/narrow.png" alt="">--> - </div> - </div> - </div> - <img src="@/assets/img/icon/avatar/2.png" alt="" class="big-avatar"> - <div class="footer"> - <img @click="isShowAudioCall = false" src="@/assets/img/icon/message/chat/call-end.png"> - <span>挂断</span> - </div> - </div> - </div> - </transition> + <Call/> </template> <script> /* * try {navigator.control.gesture(false);} catch (e) {} //UC浏览器关闭默认手势事件 try {navigator.control.longpressMenu(false);} catch (e) {} //关闭长按弹出菜单 * */ -import Mask from "./components/Mask"; import {mapState} from "vuex"; import routes from "./router/routes"; -import {inject} from "_vue@3.2.20@vue"; +import Call from "./components/Call"; export default { name: 'App', components: { - Mask + Call }, data() { return { - isSmall: false, - isShowAudioCall: false, transitionName: 'go', - callFloatTransitionTime: 0, - callFloatLeft: 15, - callFloatTop: 100, - height: 0, - width: 0, - mitt: inject('mitt'), } }, computed: { ...mapState(['excludeRoutes']), - callFloatStyle() { - return { - 'transition-duration': this.callFloatTransitionTime + 'ms', - left: this.callFloatLeft + 'px', - top: this.callFloatTop + 'px', - } - } - }, - methods: { - touchmove(e) { - this.callFloatTransitionTime = 0 - this.callFloatLeft = e.touches[0].pageX - 35 - this.callFloatTop = e.touches[0].pageY - 40 - }, - touchend(e) { - this.callFloatTransitionTime = 300 - if (this.callFloatLeft < this.width / 2) { - this.callFloatLeft = 15 - } else { - this.callFloatLeft = this.width - 15 - 70 - } - }, }, + methods: {}, // watch $route 决定使用哪种过渡 watch: { '$route'(to, from) { @@ -124,15 +48,6 @@ export default { }, }, mounted() { - this.mitt.on('showAudioCall', () => { - if (this.isShowAudioCall) { - this.isSmall = false - } else { - this.isShowAudioCall = true - } - }) - this.height = document.body.clientHeight - this.width = document.body.clientWidth // this.$store.dispatch('getFriends') try { navigator.control.gesture(false); @@ -147,165 +62,9 @@ export default { } </script> -<style> -.scale-enter-active, -.scale-leave-active { - transition: transform .2s ease; -} - -.scale-enter-from, -.scale-leave-to { - transform: scale(0); -} -</style> - <style lang="less"> @import "./assets/less/index"; -.call-float { - transition-property: all; - z-index: 9; - width: 7rem; - height: 8rem; - position: fixed; - top: 20vh; - left: @padding-page; - background: white; - display: flex; - align-items: center; - border-radius: .6rem; - justify-content: center; - flex-direction: column; - color: #14BF5F; - font-size: 1.2rem; - - img { - width: 3rem; - margin-bottom: .2rem; - } -} - -.audio-call { - color: white; - font-size: 1.2rem; - position: fixed; - z-index: 8; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - //background: black; - background: linear-gradient(to bottom, #262626, black); - transition: all .3s; - - .float { - transition: all .3s; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-between; - - > .header { - width: 100vw; - padding: @padding-page; - box-sizing: border-box; - display: flex; - align-items: flex-start; - justify-content: space-between; - - img { - width: 2.4rem; - height: 2.4rem; - } - - .center { - display: flex; - align-items: center; - - img { - width: 2rem; - height: 2rem; - background: white; - padding: .2rem; - border-radius: 50%; - } - - span { - margin-left: .5rem; - } - } - - .right { - display: flex; - flex-direction: column; - font-size: 1rem; - - .option { - margin-bottom: 2.4rem; - display: flex; - align-items: center; - flex-direction: column; - - span { - margin-top: 1rem; - } - } - - .shrink { - transform: rotate(90deg) scale(.6) !important; - } - } - } - - .big-avatar { - position: absolute; - left: 50%; - top: 50%; - transform: translate3d(-50%, -50%, 0); - width: 10rem; - border-radius: 50%; - } - - .footer { - display: flex; - flex-direction: column; - align-items: center; - font-size: 1.2rem; - margin-bottom: 4rem; - - img { - width: 5rem; - margin-bottom: .5rem; - } - - } - } - - &.small { - //opacity: 0; - width: 7rem; - height: 8rem; - position: fixed; - top: 20vh; - left: @padding-page; - border-radius: .6rem; - - .float { - width: 7rem; - height: 8rem; - transform: scale(0); - overflow: hidden; - } - } - -} - - #app { height: 100%; width: 100%; diff --git a/src/components/Call.vue b/src/components/Call.vue new file mode 100644 index 0000000..5db170a --- /dev/null +++ b/src/components/Call.vue @@ -0,0 +1,283 @@ +<template> + <div class="call-float" + v-if="call.isSmall" + :style="callFloatStyle" + @touchmove="touchmove" + @touchend="touchend" + @click="call.isSmall = false"> + <img src="@/assets/img/icon/message/chat/call-float.png" alt=""> + <span>呼叫中</span> + </div> + + <transition name="scale"> + <div class="audio-call" + :style="call.isSmall ? callFloatStyle : {zIndex:10}" + :class="call.isSmall?'small':''" + v-if="call.isShowAudioCall"> + <div class="float"> + <div class="header"> + <div class="left"> + <img @click="call.isSmall = true" src="@/assets/img/icon/message/chat/narrow.png" alt=""> + </div> + <span class="center">等待对方接听...</span> + <div class="right"> + <div class="option"> + <img src="@/assets/img/icon/message/chat/disabled-camera.png" alt=""> + <span>摄像头</span> + </div> + <div class="option"> + <img src="@/assets/img/icon/message/chat/able-volume.png" alt=""> + <span>免提</span> + </div> + <div class="option"> + <back mode="light" img="back" class="shrink"/> + <!-- <img src="@/assets/img/icon/message/chat/narrow.png" alt="">--> + </div> + </div> + </div> + <img src="@/assets/img/icon/avatar/2.png" alt="" class="big-avatar"> + <div class="footer"> + <img @click="call.isShowAudioCall = false" src="@/assets/img/icon/message/chat/call-end.png"> + <span>挂断</span> + </div> + </div> + </div> + </transition> +</template> +<script> +import {inject} from "vue"; + +export default { + name: "Call", + components: {}, + props: { + modelValue: false + }, + data() { + return { + mitt: inject('mitt'), + call: { + callFloatTransitionTime: 300, + callFloatLeft: 15, + callFloatTop: 100, + isSmall: false, + isShowAudioCall: false, + }, + height: 0, + width: 0, + } + }, + computed: { + callFloatStyle() { + return { + 'transition-duration': this.call.callFloatTransitionTime + 'ms', + left: this.call.callFloatLeft + 'px', + top: this.call.callFloatTop + 'px', + } + } + }, + watch: {}, + created() { + }, + methods: { + touchmove(e) { + this.call.callFloatTransitionTime = 0 + this.call.callFloatLeft = e.touches[0].pageX - 35 + this.call.callFloatTop = e.touches[0].pageY - 40 + }, + touchend(e) { + this.call.callFloatTransitionTime = 300 + if (this.call.callFloatLeft < this.width / 2) { + this.call.callFloatLeft = 15 + } else { + this.call.callFloatLeft = this.width - 15 - 70 + } + }, + }, + mounted() { + this.mitt.on('showAudioCall', () => { + if (this.call.isShowAudioCall) { + this.call.isSmall = false + } else { + this.call.isShowAudioCall = true + } + }) + this.height = document.body.clientHeight + this.width = document.body.clientWidth + } +} +</script> + +<style> +.scale-enter-active, +.scale-leave-active { + transition: transform .2s ease; +} + +.scale-enter-from, +.scale-leave-to { + transform: scale(0); +} +</style> + +<style scoped lang="less"> +@import "@/assets/less/index"; + +.call-float { + transition-property: all; + z-index: 9; + width: 7rem; + height: 9rem; + position: fixed; + top: 20vh; + left: @padding-page; + background: white; + display: flex; + align-items: center; + border-radius: .6rem; + justify-content: center; + flex-direction: column; + color: #14BF5F; + font-size: 1.2rem; + + img { + width: 3rem; + margin-bottom: .2rem; + } +} + +.audio-call { + color: white; + position: fixed; + z-index: 8; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: linear-gradient(to bottom, #262626, black); + transition: all .3s; + font-size: 1.2rem; + + .float { + transition: all .3s; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + + span { + transition: all .3s; + } + + > .header { + transition: all .3s; + width: 100%; + padding: @padding-page; + box-sizing: border-box; + display: flex; + align-items: flex-start; + justify-content: space-between; + + .left { + width: 12%; + + img { + width: 50%; + max-width: 2.4rem; + max-height: 2.4rem; + } + } + + .center { + width: 50%; + overflow: hidden; + text-align: center; + word-break: keep-all; + font-size: 1.4rem; + } + + .right { + width: 12%; + max-width: 4rem; + display: flex; + flex-direction: column; + + img { + width: 50%; + max-width: 2.4rem; + max-height: 2.4rem; + } + + .option { + margin-bottom: 55%; + display: flex; + align-items: center; + flex-direction: column; + overflow: hidden; + + span { + word-break: keep-all; + margin-top: 20%; + font-size: 1.2rem; + } + } + + .shrink { + transform: rotate(90deg) scale(.6) !important; + } + } + } + + .big-avatar { + position: absolute; + left: 50%; + top: 50%; + transform: translate3d(-50%, -50%, 0); + width: 25%; + max-width: 10rem; + border-radius: 50%; + } + + .footer { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + font-size: 1.2rem; + margin-bottom: 10%; + + img { + width: 15%; + max-width: 5rem; + margin-bottom: 1%; + } + + } + } + + &.small { + width: 7rem; + height: 9rem; + position: fixed; + top: 20vh; + left: @padding-page; + border-radius: .6rem; + + .float { + > .header { + padding: 0; + } + + span { + transform: scale(.2); + } + } + } +} + +</style>