123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- <template>
- <view class="tm-poups " @click.stop="">
- <block v-if="position_sv != 'center'">
- <view v-show="value==true&&position_sv != 'center'" class="tm-poup " :class="[
- isFilter?'blur':'',
- position_sv == 'center' ? 'tm-poup-center' : '',
- position_sv !='center'?position_sv:'',
- isClickbled?'isClickbled':''
- ]" @click.stop.prevent="overClick" @touchmove.stop.prevent="stopMove" :style="{
- backgroundColor: overColor,
- width:'100%',height:'100%'
- }">
- <!-- 内容 -->
- <!-- <view class="tm-poup-wk bottom">{{ show ? 'on' : 'off'}}</view> -->
- <scroll-view :animation="aniData" @click.stop.prevent="" class="tm-poup-wk dhshiKa" scroll-y="true" :class="[
- position_sv == 'top'?'round-b-' + round:'',
- position_sv == 'bottom'?'round-t-' + round:'',
- position_sv, aniOn ? 'on ' : 'off',
- black_tmeme ? 'grey-darken-5 bk' : bgColor
- ]" :style="{
- width: (position_sv == 'top' || position_sv == 'bottom') ? '100%' : width_w,
- height: position_sv == 'right' || position_sv == 'left' ?'100%' : height_h,
-
- }">
- <view :class="[clssStyle]" >
- <slot></slot>
- </view>
- </scroll-view>
- </view>
- </block>
- <view v-if="value===true&&position_sv == 'center'" class="tm-poup " :class="[
- isFilter?'blur':'',
- position_sv == 'center' ? 'tm-poup-center' : ''
- ]" @click="overClick" @touchmove.stop.prevent="stopMove" :style="{
- backgroundColor: overColor,
- width:sysInfo.screenWidth+'px',height:'100%'
- }">
- <!-- 内容 -->
- <scroll-view :animation="aniData" @click.stop.prevent="" class="tm-poup-wk " scroll-y="true" :class="[
- `round-${round}`,aniOn ? 'on' : 'off', position_sv,
- black_tmeme ? 'grey-darken-5 bk' : bgColor
- ]" :style="{
- width: width_w,
- height: height_h
- }">
- <view :class="[clssStyle]">
- <slot></slot>
- </view>
- </scroll-view>
- </view>
- </view>
- </template>
- <script>
- /**
- * poup弹出层
- * @description poup弹出层,上下,左右方向。
- * @property {Boolean} value = [true|false] 使用时value.sync可同步,也可不同步。等同于v-model
- * @property {Boolea} v-model 显示和关闭。
- * @property {String} position = [bottom|top|left|right|center] 方向可选bottom,left,right,top,center
- * @property {Function} change 改变时会调用此函数,参数e等同于v-model和value
- * @property {String|Number} width 宽,位置为left,right是起作用。可以是30%或者数字(单位upx)
- * @property {String|Number} height 宽,位置为top,bottom是起作用。可以是30%或者数字(单位upx)
- * @property {String|Number} round 圆角0-25
- * @property {String|Boolean} black = [true|false] 暗黑模式
- * @property {Boolean} over-close = [true|false] 是否点击遮罩关闭。
- * @property {Boolean} is-filter = [true|false] 是否背景模糊
- * @property {String} clss-style = [] 自定内容的类
- * @property {String} bg-color = [white|blue] 默认:white,白色背景;请填写背景的主题色名称。
- * @property {String} over-color = [] 默认:rgba(0,0,0,0.3), 遮罩层颜色值不是主题。
- * @example <tm-poup height="85%" v-model="show"></tm-poup>
- */
- export default {
- name: 'tm-poup',
- props: {
- bgColor: {
- type: String,
- default: 'white'
- },
- // 遮罩层颜色。
- overColor: {
- type: String,
- default: 'rgba(0,0,0,0.3)'
- },
- black: {
- type: Boolean | String,
- default: null
- },
- clssStyle: {
- type: String,
- default: ''
- },
- value: {
- type: Boolean,
- default: false
- },
- // bottom,left,right,top
- position: {
- type: String,
- default: 'bottom'
- },
- round: {
- type: String | Number,
- default: '10'
- },
- width: {
- type: String | Number,
- default: '30%'
- },
- height: {
- type: String | Number,
- default: 220
- },
- overClose: {
- type: Boolean,
- default: true
- },
- isFilter: {
- type: Boolean,
- default: true,
- },
- //允许穿透背景遮罩。
- isClickbled: {
- type: Boolean,
- default: false
- }
- },
- model: {
- prop: 'value',
- event: 'input',
- sysInfo: {},
- },
- watch: {
- value:function(val){
- this.$emit('change', val);
- if(val){
- this.open()
- }else{this.close()}
- },
- position: function() {
- this.position_sv = this.position
- }
- },
- created() {
- this.sysInfo = uni.getSystemInfoSync();
- },
- computed: {
- black_tmeme: function() {
- if (this.black !== null) return this.black;
- return this.$tm.vx.state().tmVuetify.black;
- },
- width_w: function() {
- let w = this.$TestUnit(this.width);
- let i = w.value;
- if (w.type == 'number') {
- i = w.value + 'px';
- }
- return i;
- },
- height_h: function() {
- let w = this.$TestUnit(this.height);
- let i = w.value;
- if (w.type == 'number') {
- i = w.value + 'px';
- }
- return i;
- },
- },
- data() {
- return {
- aniOn: false,
- closeTimid: null,
- position_sv: this.position,
- dhshiKa:true,//是否结束动画
- aniData:null,
- timdiiid:6369784254,
-
- };
- },
- deactivated() {
- clearTimeout(this.closeTimid)
- },
- destroyed() {
- clearTimeout(this.closeTimid)
- },
- mounted() {
- if(this.value){
- this.open()
- }
- },
- methods: {
- overClick() {
- if (!this.overClose) return;
- this.close();
- },
- close() {
- let t = this;
- clearTimeout(this.timdiiid)
- this.dhshiKa=false;
- t.aniOn=false;
- this.createBtT(this.position_sv,'off').then(()=>{
- t.$emit('input', false);
- t.closeTimid = null;
- t.dhshiKa = true;
- // t.$emit('change', false);
- // console.log('off');
- })
- },
- open() {
- let t = this;
- clearTimeout(this.timdiiid)
-
-
- this.dhshiKa=false
- this.aniOn=true;
-
- this.createBtT(this.position_sv,'on').then(()=>{
- t.dhshiKa=true
-
- t.isclick=false
- // console.log('on');
- })
-
- },
- //下至上。
- createBtT(pos,type){
- let t = this;
- this.aniData = '';
- let aniData = uni.createAnimation({
- duration:240,
- timingFunction: 'linear',
- })
- this.aniData = aniData;
- if(pos=='bottom'){
- if(type=='on'){
- aniData.translateY('0%').step();
- this.aniData = aniData.export()
-
- }
- if(type=='off'){
- aniData.translateY('100%').step();
- this.aniData = aniData.export()
-
- }
- }else if(pos=='top'){
- if(type=='on'){
- aniData.translateY('0%').step();
- this.aniData = aniData.export()
-
- }
- if(type=='off'){
- aniData.translateY('-100%').step();
- this.aniData = aniData.export()
-
- }
- }else if(pos=='left'){
- if(type=='on'){
- aniData.translateX('0%').step();
- this.aniData = aniData.export()
-
- }
- if(type=='off'){
- aniData.translateX('-100%').step();
- this.aniData = aniData.export()
-
- }
- }else if(pos=='right'){
- if(type=='on'){
- aniData.translateX('0%').step();
- this.aniData = aniData.export()
-
- }
- if(type=='off'){
- aniData.translateX('100%').step();
- this.aniData = aniData.export()
-
- }
- }else if(pos=='center'){
-
- if(type=='on'){
- aniData.opacity(1).scale(1).step();
- this.aniData = aniData.export()
-
- }
- if(type=='off'){
- aniData.opacity(0).scale(0.6).step();
- this.aniData = aniData.export()
-
- }
- }
-
- return new Promise(res=>{
- t.timdiiid = setTimeout(()=>{
- t.aniData = null;
- res();
- },240)
- })
- },
- stopMove(e) {}
- }
- };
- </script>
- <style lang="scss" scoped>
- .tm-poup {
- position: fixed;
- z-index: 452;
- width: 100%;
- height: 100%;
- min-height: 100%;
- min-width: 100%;
- overflow: hidden;
- top: 0;
- left: 0;
-
- &.isClickbled {
- pointer-events: none;
- }
- &.okkk{
- pointer-events: none;
- }
- &.blur {
- backdrop-filter: blur(10px);
- }
- &.on {
- animation: opta 1s linear;
- }
- &.off {
- animation: opta_off 0.35s linear;
- }
- .tm-poup-wk {
- position: absolute;
- overflow: hidden;
- pointer-events: auto;
- // transition: all 0.3s;
- &.bottom {
- transform: translateY(100%);
- width: 100%;
- bottom: 0;
-
- }
- &.top {
- top: 0;
- left: 0;
- width: 100%;
- transform: translateY(-100%);
- }
- &.left {
- top: 0;
- transform: translateX(-100%);
- border-radius: 0 !important;
- left: 0;
- }
- &.right {
- top: 0;
- right: 0;
- transform: translateX(100%);
- border-radius: 0 !important;
- }
- &.center {
- opacity:0;
- transform: scale(0.6);
- }
- }
- &.tm-poup-center {
- display: flex;
- justify-content: center;
- align-items: center;
- align-content: center;
-
- .tm-poup-wk {
- position: static;
- }
- }
- }
- @keyframes opta {
- from {
- opacity: 0.6;
- }
- to {
- opacity: 1;
- }
- }
- @keyframes opta_off {
- from {
- opacity: 1;
- }
- to {
- opacity: 0;
- }
- }
- @keyframes bottomTtop {
- from {
- transform: translateY(100%);
- }
- to {
- transform: translateY(0%);
- }
- }
- @keyframes bottomTtop_off {
- from {
- transform: translateY(0%);
- }
- to {
- transform: translateY(100%);
- }
- }
- @keyframes topTbottom {
- from {
- transform: translateY(-100%);
- }
- to {
- transform: translateY(0);
- }
- }
- @keyframes topTbottom_off {
- from {
- transform: translateY(0);
- }
- to {
- transform: translateY(-100%);
- }
- }
- @keyframes leftTright {
- from {
- transform: translateX(-100%);
- }
- to {
- transform: translateX(0);
- }
- }
- @keyframes leftTright_off {
- from {
- transform: translateX(0);
- }
- to {
- transform: translateX(-100%);
- }
- }
- @keyframes rightTleft {
- from {
- transform: translateX(100%);
- }
- to {
- transform: translateX(0%);
- }
- }
- @keyframes rightTleft_off {
- from {
- transform: translateX(0%);
- }
- to {
- transform: translateX(100%);
- }
- }
- @keyframes Centerleft {
- from {
- transform: scale(0.65);
- opacity: 0.65;
- }
- to {
- transform: scale(1);
- opacity: 1;
- }
- }
- @keyframes Centerleft_off {
- from {
- transform: scale(1);
- opacity: 1;
- }
- to {
- transform: scale(0.65);
- opacity: 0.65;
- }
- }
- </style>
|