living-app.nvue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. <template>
  2. <view class="es">
  3. <view :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;' ">
  4. <view class="emptybox x-c" :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;' " v-if="isEmpty">
  5. <image class="emptybox-img" src="https://www.mescroll.com/img/mescroll-empty.png" mode="aspectFill"></image>
  6. <text class="emptybox-tip">~空空如也~</text>
  7. </view>
  8. <list loadmoreoffset="100" @scroll="scrolls" :show-scrollbar="false" v-if="dataList&&dataList.length > 0" :style="'height: '+ (boxStyle.height) +'px;padding-top:'+statusBarHeight+'px' " ref="listBox" :pagingEnabled="true" :scrollable="true">
  9. <refresh @pullingdown='onpullingdown' @refresh="onrefresh" :display=" refreshing ? 'show' : 'hide' " class="refresh x-c ">
  10. <loading-indicator style="width: 22px;height: 22px;color:#fff;"></loading-indicator>
  11. <text class="es-fs-32 es-ml-8 es-c-white">{{refreshText}}</text>
  12. </refresh>
  13. <cell v-for="(item,i) in dataList" :key="i">
  14. <view :style="'width: '+ windowWidth +'px;height:'+ (videoStyle.height)+'px' " :ref="'item'+i" style="position: relative;">
  15. <view v-if="(k-i)<=1" style="position: relative;" >
  16. <view class="root" >
  17. <video :id="item.id" :loop="true" :src="item.src" :poster="item.cover"
  18. @play="playIngs(i)" :enable-progress-gesture="false" :page-gesture="false"
  19. :controls="false" :show-loading="false" :initial-time="0"
  20. :show-fullscreen-btn="false" :show-center-play-btn="false" :style="videoStyle"
  21. :object-fit="object_fit" @timeupdate="timeupdate($event,i)"
  22. @fullscreenchange="onFullscreenChange" @waiting="onWaiting()" @progress="onProgress()"
  23. @ended="endedPlayNext()" @canplay="onVideoCanPlay" @canplaythrough="onVideoCanPlayThrough"
  24. @loadeddata="onLoadeddata" @loadedmetadata="onLoadedMetadata" @error="onError"
  25. >
  26. </video>
  27. </view>
  28. <view class="videoHover" @click="tapVideoHover(item.state,$event)"
  29. @touchstart="touchstartHover" :style="boxStyle">
  30. <image v-if="item.state=='pause' && item.isShowPlayIcon" class="playState" src="/static/image/course/play.png"></image>
  31. </view>
  32. <view class="right es-c-white">
  33. <view class="item1 es es-ac es-pc es-mt-33">
  34. <view class="es-icon-100 es-br">
  35. <image class="es-icon-100" style="border-radius: 50rpx;" :src="item.headImg"></image>
  36. </view>
  37. </view>
  38. <view class="item1 es es-ver es-ac es-pc es-mt-33" @tap="doLike(item,i)">
  39. <view class="es-icon-84">
  40. <image class="es-icon-84" :src="item.like==1?'/static/images/other/video/zan1_on.png':'/static/images/other/video/zan1.png'"></image>
  41. </view>
  42. <view><text class="es-c-white es-fs-22 es-fw-500">{{item.likeNum}}</text></view>
  43. </view>
  44. <view class="item1 es es-ver es-ac es-pc es-mt-33" @tap="openComment(item)">
  45. <view class="es-icon-84">
  46. <image class="es-icon-84" src="/static/images/other/video/comment1.png"></image>
  47. </view>
  48. <view><text class="es-c-white es-fs-22 es-fw-500">{{item.smsNum}}</text></view>
  49. </view>
  50. <view class="item1 es es-ver es-ac es-pc es-mt-33" @tap="doFavorite(item,i)">
  51. <view class="es-icon-84">
  52. <image class="es-icon-84" :src="item.favorite==1?'/static/images/other/video/fav1_on.png':'/static/images/other/video/fav1.png'" ></image>
  53. </view>
  54. <view><text class="es-c-white es-fs-22 es-fw-500">{{item.favoriteNum}}</text></view>
  55. </view>
  56. <view class="item1 es es-ver es-ac es-pc es-mt-33" @tap="openShare(item)">
  57. <view class="es-icon-84">
  58. <image :class="animate ? 'animate-icon':'animate-scale'" src="@/static/image/home1/weixin_icon.png" mode="aspectFill"></image>
  59. </view>
  60. <view><text class="es-c-white es-fs-22 es-fw-500">{{item.shares}}</text></view>
  61. </view>
  62. <!-- <view class="item1 es es-ac es-pc es-mt-33">
  63. <view class="es-br ">
  64. <text class="es-c-white es-fs-34">{{item.uploadType}}</text>
  65. </view>
  66. </view> -->
  67. </view>
  68. <view class="left" v-if="item.isShowGoods && item.productId!=null" >
  69. <view class="es-w-40 es-h-40" @tap.stop="closePro(item,i)" style="position: absolute;right:0rpx;top:74rpx;z-index:999">
  70. <image class="es-w-40 es-h-40" src="../../../static/images/close40.png"></image>
  71. </view>
  72. <view class="es-h-74 es es-ac">
  73. <view class="es-f1 es es-ac" id="w">
  74. <view class="bg" style="width: 320rpx;" >
  75. <image src="@/static/images/other/video/bg.png" style="height: 74rpx;width: 100%;" ></image>
  76. </view>
  77. <view class="es-w-30"></view>
  78. </view>
  79. </view>
  80. <view class="goods" @tap="goToPro(item)">
  81. <view class="icon" style="width: 290rpx;height: 290rpx;">
  82. <image :src="item.imgUrl" style="width: 290rpx;height: 290rpx;" class="es-br-10"></image>
  83. </view>
  84. <view class="es-omit es-mt-19" style="width: 290rpx;"><text class="es-fw es-fs-30">{{item.packageName}}</text></view>
  85. </view>
  86. </view>
  87. <view class="bottom">
  88. <text class="txtTitle" :class="showExpand?'ellipsis':''" :style="defTitStyle" :id="'txtTitle'+i" :ref="'txtTitle'+i">{{item.title}}</text>
  89. <text v-if="showExpand" class="expandBtn" @tap="clickExpand">{{ titIsExpand?'收起':'展开' }}</text>
  90. </view>
  91. </view>
  92. </view>
  93. </cell>
  94. </list>
  95. </view>
  96. <view v-if="isShowTab" :style="'width: '+ windowWidth +'px;background-color:'+bgColor" class="tabbar1">
  97. <n-tabs style="background: transparent;" v-model="tabIndex" :tabs="mtabs" :height="88" @change="tabChange" :tab-width="134" @search="handleShowSearch"></n-tabs>
  98. <view class="search-box view-animation" :style="'width: '+ windowWidth +'px;height:'+searchHeight+'rpx'">
  99. <uni-search-bar radius="72" v-model="keyword" placeholder="搜索内容" clearButton="auto" cancelButton="none" @confirm="search" />
  100. </view>
  101. </view>
  102. <view class="redpacked x-c es-br-ban" v-if="!iserr && !showGuide" @click.stop="tapRedpacked">
  103. <gb-progress class="es x-c es-br-ban" :radius="43" :startPosDegree="0" originalColor="#222222"
  104. processColor="#FF5C03" innerbgColor="#222222" :process="process" :barWidth="5">
  105. <image class="es-w-50 es-h-50" src="@/static/images/ad/redpacked.png" mode="widthFix" ></image>
  106. </gb-progress>
  107. </view>
  108. <!-- 新手指引 -->
  109. <view class="guide" :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;'" v-if="showGuide" @touchmove.stop.prevent>
  110. <view class="guide-box" style="width: 100%; height:100%; left: 0px; top: 0px;box-shadow: rgb(33 33 33 / 80%) 0px 0px 0px 0px, rgb(33 33 33 / 50%) 0px 0px 0px 5000px;" >
  111. <view class="tips" id="guidetips" :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;' " style="top: 0px; left: 0px;" @click="nextGuide">
  112. <view class="liveguide" >
  113. <image class="phone_icon" src="@/static/images/guide/phone_icon.png" mode="aspectFill"></image>
  114. <image class="hand_icon" :class="{origin: !goSwipe, target: goSwipe}" src="@/static/images/guide/hand_icon.png" mode="aspectFill"></image>
  115. <text class="liveguide-tip">上滑查看更多视频</text>
  116. </view>
  117. </view>
  118. </view>
  119. <!-- 遮罩层,防止点击 -->
  120. <view class="v-model" @click="nextGuide"></view>
  121. </view>
  122. <!-- 分享弹窗 -->
  123. <u-popup :show="showShare" @close="showShare = false" >
  124. <share-box :shareItem="shareItem" @closeShare='showShare = false' ></share-box>
  125. </u-popup>
  126. </view>
  127. </template>
  128. <script>
  129. import { getVideoList,doFavorite,doLike } from '@/api/shortvideo'
  130. import { addIntegral } from '@/api/integral'
  131. import { isLogin,updateMsgDot } from '@/utils/common'
  132. import { showLoginPage } from '@/utils/login'
  133. import shareBox from "@/components/share-box/share-boxN.vue"
  134. // #ifdef APP-PLUS
  135. const dom = weex.requireModule('dom');
  136. // #endif
  137. export default {
  138. components: {
  139. shareBox
  140. },
  141. data() {
  142. return {
  143. animate: true,
  144. animateInterval: null,
  145. bgColor: '',
  146. searchFlag: false,
  147. searchHeight: 0,
  148. showSearch: false,
  149. isEmpty: false,
  150. step: {
  151. name: 'liveguide',
  152. guideList: [{
  153. el: '',
  154. tips: '上滑查看更多视频',
  155. next: '',
  156. }]
  157. },
  158. dataList: [], //用于数据循环的列表🌟💗
  159. wHeight: 0, //获取的屏幕高度🌟💗
  160. boxStyle: { //视频父视图样式🌟💗
  161. 'height': 0,
  162. 'width': 0,
  163. },
  164. videoStyle: { //视频,图片封面样式🌟💗
  165. 'height': 0,
  166. 'width': 0,
  167. 'marginTop':0
  168. },
  169. Heights: 0,
  170. k: 0, //默认为0🌟💗
  171. playIngIds: [], //正在播放的视频id列队,列队用于处理滑动过快导致的跳频问题🌟💗
  172. ready: false, //可忽略
  173. isDragging: false, //false代表停止滑动🌟💗
  174. refreshing: false, //用于下拉刷新🌟💗
  175. windowWidth: 0, //获取屏幕宽度🌟💗
  176. windowHeight: 0,
  177. dex: [0, 0], //用于判断是上滑还是下滑,第一个存旧值,第二个存新值【目前在1.0.7已经废弃】
  178. currents: 0, //用于左右滑动,0代表视频界面,1代表右滑界面🌟💗
  179. platform: '', //用于获取操作系统:ios、android🌟💗
  180. playIng: false, //用于视频初始化时是否播放,默认不播放🌟💗
  181. videoTime: '', //视频总时长,这个主要用来截取时间数值💗
  182. videoTimes: '', //视频时长,用这个来获取时间值,例如:00:30这个时间值💗
  183. changeTime: '', //显示滑动进度条时变化的时间💗
  184. isShowimage: false, //是否显示封面【1.0.4已废弃,但是意思需要记住】
  185. currenttimes: 0, //当前时间💗
  186. isShowProgressBarTime: false, //是否拖动进度条,如果拖动(true)则显示进度条时间,否则不显示(false)【1.0.4已废弃,但是意思需要记住】
  187. ProgressBarOpacity: 0.7, //进度条不拖动时的默认值,就是透明的💗
  188. dotWidth: 0, //播放的小圆点,默认没有💗
  189. deleteHeight: 0, //测试高度🌟💗
  190. statusBarHeight:0,
  191. percent: 0, //百分小数💗
  192. currentPosition: 0, //滑块当前位置💗//2.0已弃用,现已用于后端参数
  193. currentPositions: 0, //滑块当前位置的副本💗//2.0已弃用,现已用于后端参数
  194. newTime: 0, //跟手滑动后的最新时间💗
  195. timeNumber: 0, //🌟💗
  196. ProgressBarBottom: 20, //进度条离底部的距离💗
  197. object_fit: 'contain', //视频样式默认包含🌟💗 contain :包含 fill:填充 cover:覆盖
  198. mode: 'aspectFit', //图片封面样式🌟💗
  199. timeout: "", //🌟用来阻止 setTimeout()方法
  200. voice: "", //🌟用来阻止 setTimeout()方法
  201. oldVideo: "",
  202. isAutoplay: false, //是否开启自动播放(默认不开启)
  203. autoplayText: "开启自动播放",
  204. timers: "",
  205. leftTimers:"",
  206. // 引入评论 - 参数
  207. heightNum: 1.18,
  208. // 双击点赞参数
  209. touchNum: 0,
  210. aixinLeft: 0,
  211. aixinTop: 0,
  212. isShowAixin: false,
  213. Rotate: 0,
  214. isShowTab:true,
  215. isShow1: false, //控制渲染变量1
  216. isShow2: false, //控制渲染变量2 : 专门控制 uni-popup
  217. showPlay: false, //转轮显示控制
  218. rotates: 0, //转轮旋转角度
  219. rotateTime: "", //转轮递归事件控制
  220. xrotats: "",
  221. player: "",
  222. top:0,
  223. w:0,
  224. showLeft:true,
  225. keyword:"",
  226. pageNum:1,
  227. pageSize:10,
  228. isLastPage:false,
  229. refreshText: '↓ 下拉刷新',
  230. tabIndex: 0, // tab下标
  231. current: 0,
  232. mtabs: [
  233. {id: "tab00",name: ''},
  234. {id: "tab01",name: ''}
  235. // {id: "tab00",name: '推荐'},
  236. // {id: "tab01",name: '热点'}
  237. // {id: "tab02",name: '直播'},
  238. // {id: "tab03",name: '健康'}
  239. ],
  240. specVisible: false,
  241. esComment:null,
  242. showExpand:false,
  243. titIsExpand:false,
  244. lines:2,
  245. lineCount:0,
  246. titOpacity:0,
  247. defTitStyle:{'opacity':0},
  248. showShare:false,
  249. shareItem:{ imageUrl:"",title:"",path:""},
  250. viewVideoNum:0,
  251. //圆环倒计时
  252. iserr:false,
  253. interval:null,
  254. process:0,
  255. processDatas:[],
  256. isCounting:true,
  257. isPostBack:true,
  258. countItem:{"process":0,"isLoad":false},
  259. doLikeDisabled:false,
  260. doFavDisabled:false,
  261. showGuide:true,
  262. goSwipe: false,
  263. countNum:false,
  264. guideTimer:null
  265. }
  266. },
  267. created: function() {
  268. // setTimeout(e => {
  269. // uni.createSelectorQuery().select('#w').boundingClientRect(r2 => {
  270. // this.w = r2.width;
  271. // }).exec();
  272. // }, 50)
  273. },
  274. onLoad(options) {
  275. const systemInfo = uni.getSystemInfoSync();
  276. this.statusBarHeight=systemInfo.statusBarHeight;
  277. this.windowWidth = systemInfo.screenWidth //获取屏幕宽度
  278. this.boxStyle.width = this.windowWidth + 'px' //给宽度加px
  279. let tabBarHeight = systemInfo.screenHeight - systemInfo.safeArea.bottom;
  280. this.wHeight=systemInfo.windowHeight; //获取屏幕高度
  281. this.boxStyle.height = this.wHeight - this.deleteHeight; //改变视频高度
  282. this.videoStyle.width=this.boxStyle.width;
  283. this.videoStyle.height=this.boxStyle.height - this.statusBarHeight;
  284. this.getData();
  285. uni.getSystemInfo({success: (res) => {
  286. this.top = res.safeArea.top;
  287. }
  288. });
  289. let that=this;
  290. uni.$on('refreshVideoComment', (data) => {
  291. let item=that.dataList[that.k];
  292. item.smsNum=data.smsNum;
  293. that.dataList[that.k]=item;
  294. that.$forceUpdate(); // 如果你需要强制刷新,可以调用 $forceUpdate()
  295. });
  296. const guide = uni.getStorageSync(this.step.name);
  297. console.log("qxj guide:"+guide);
  298. if (!guide) {
  299. this.showGuide = true;
  300. } else {
  301. this.showGuide = false;
  302. }
  303. this.guideTimer=setInterval(() => {
  304. if(this.countNum%2==0){
  305. this.goSwipe=true;
  306. }
  307. else{
  308. this.goSwipe=false;
  309. }
  310. this.countNum++;
  311. }, 900)
  312. },
  313. onShow(){
  314. if(!isLogin()){
  315. uni.navigateTo({
  316. url: '/pages/auth/loginIndex'
  317. })
  318. return;
  319. }
  320. updateMsgDot()
  321. this.animate = true
  322. this.changeAnimate()
  323. const systemInfo = uni.getSystemInfoSync();
  324. if(this.dataList.length !== 0){
  325. this.dataList[this.k].state = 'play';
  326. uni.createVideoContext(this.dataList[this.k].id,this).play();
  327. }
  328. },
  329. onHide(){
  330. clearInterval(this.animateInterval)
  331. this.animateInterval = null
  332. this.dataList[this.k].state = 'pause';//界面隐藏也要停止播放视频
  333. uni.createVideoContext(this.dataList[this.k].id,this).pause();//暂停以后继续播放
  334. //this.showToast('回到后台');
  335. },
  336. destroyed() {
  337. uni.$off("refreshVideoComment");
  338. },
  339. watch:{
  340. k(k,old_k){
  341. //监听 k 值的变化,可以控制视频的播放与暂停
  342. //console.log(k)
  343. // 清理定时器
  344. //this.dataList[old_k].state = 'stop'//如果是被滑走的视频,就停止播放
  345. this.dataList[old_k].playIng = false//如果视频暂停,就加载封面
  346. this.dataList[old_k].isplay = true
  347. console.log("qxj 旧视频暂停");
  348. uni.createVideoContext(this.dataList[old_k].id,this).seek(0);
  349. uni.createVideoContext(this.dataList[old_k].id,this).play();
  350. clearTimeout(this.oldVideo)
  351. this.oldVideo = setTimeout(()=>{
  352. //uni.createVideoContext(this.dataList[old_k].id,this).seek(0)
  353. uni.createVideoContext(this.dataList[old_k].id,this).pause()
  354. console.log('预留第' + (old_k + 1) + '个视频:' + this.dataList[old_k].id)
  355. },10);
  356. // clearTimeout(this.timeout)
  357. // this.timeout = setTimeout(()=>{
  358. // uni.createVideoContext(this.dataList[k+1].id,this).seek(0);
  359. // uni.createVideoContext(this.dataList[k+1].id,this).pause();
  360. // console.log('预加载第' + (k+1) + '个视频:' + this.dataList[k+1].id)
  361. // },50);
  362. // 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行
  363. // uni.createVideoContext(this.dataList[old_k].id + '' + old_k,this).stop()//如果视频暂停,那么旧视频停止,这里的this.dataList[old_k].id + '' + old_k,后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题
  364. this.dataList[k].state = 'play'
  365. console.log('已经暂停 --> 第' + (old_k + 1) + '个视频~')//提示
  366. clearTimeout(this.player);
  367. this.player = setTimeout(()=>{
  368. uni.createVideoContext(this.dataList[k].id,this).play();
  369. },0);
  370. if(k == (this.dataList.length-1)) {
  371. (async ()=>{
  372. console.log("qxj wath isLastPage:"+this.isLastPage);
  373. var p = k;
  374. if(this.isLastPage){
  375. this.pageNum=1;
  376. await this.getData();
  377. //var p = k;
  378. }else{
  379. this.pageNum++;
  380. await this.getData();
  381. }
  382. console.log("qxj after getData listCount:"+this.dataList.length);
  383. this.dataList[p].isplay = true
  384. setTimeout(()=>{
  385. uni.createVideoContext(this.dataList[p].id,this).play()
  386. clearTimeout(this.timeout)
  387. this.timeout = setTimeout(()=>{
  388. uni.createVideoContext(this.dataList[p].id,this).seek(0)
  389. uni.createVideoContext(this.dataList[p].id,this).pause()
  390. console.log('预加载第' + (p + 1) + '个视频:' + this.dataList[p].id)
  391. },1000)
  392. },20)
  393. })();
  394. }
  395. //【此处处理进度条卡住的问题】
  396. if(uni.getSystemInfoSync().platform !== 'ios'){
  397. setTimeout(()=>{
  398. uni.createVideoContext(this.dataList[k].id,this).pause()
  399. uni.createVideoContext(this.dataList[k].id,this).play()
  400. },100)
  401. }
  402. this.xrotats = setTimeout(()=>{
  403. this.showPlay = true;
  404. },200)
  405. }
  406. },
  407. methods: {
  408. changeAnimate() {
  409. this.animateInterval = setInterval(()=>{
  410. this.animate = !this.animate
  411. },500)
  412. },
  413. handleShowSearch() {
  414. uni.navigateTo({
  415. url: "/pages/index/searchInfo?type=2"
  416. })
  417. // this.showSearch = !this.showSearch
  418. // this.searchHeight = this.showSearch ? '116' : 0
  419. // this.bgColor = this.showSearch ? 'rgba(0,0,0,0.2)' : 'rgba(0,0,0,0)'
  420. // this.keyword = ""
  421. // if(!this.showSearch && this.searchFlag) {
  422. // this.searchFlag = false
  423. // this.pageNum=1;
  424. // this.getData('showLoading');
  425. // }
  426. },
  427. search() {
  428. this.searchFlag = true
  429. this.pageNum=1;
  430. this.getData('showLoading');
  431. },
  432. onpullingdown(e) {
  433. if (this.refreshing) return;
  434. if (Math.abs(e.pullingDistance) > Math.abs(e.viewHeight)) {
  435. this.refreshText = '释放更新'
  436. this.isShowTab=false;
  437. } else {
  438. this.refreshText = '下拉更新'
  439. this.isShowTab=true;
  440. }
  441. },
  442. onrefresh(e) {
  443. console.log('onRefreshing...');
  444. this.refreshing = true;
  445. this.isShowTab=false;
  446. this.pageNum=1;
  447. this.getData();
  448. if (this.refreshing) return;
  449. },
  450. getData:function(flag){
  451. // userList.forEach(e=>{
  452. // e.id = 'A'+e.id+''+parseInt(Math.random()*1000);
  453. // this.dataList.push(e);
  454. // });
  455. // if(this.isLastPage){
  456. // return;
  457. // }
  458. let that=this;
  459. const params={"keyword":this.keyword};
  460. if(flag == 'showLoading') {
  461. uni.showLoading({
  462. title: '加载中...',
  463. })
  464. }
  465. this.isEmpty = false
  466. getVideoList(params,this.pageNum,this.pageSize).then(res => {
  467. this.refreshing = false;
  468. this.isShowTab=true;
  469. if(res.code==200&& res.data &&res.data.list&&res.data.list.length > 0){
  470. const datas=res.data.list;
  471. this.isLastPage=res.data.isLastPage;
  472. datas.forEach(e=>{
  473. e.videoId=e.id;
  474. e.id = 'A'+e.id+''+parseInt(Math.random()*1000);
  475. //e.src=e.src.replace("obs.shouzhujue.com","obs.jy.cc");
  476. //e.src=e.src.replace("cdn.ylrzcloud.com","tcpv.ylrzcloud.com");
  477. this.dataList.push(e);
  478. });
  479. if(this.pageNum==1){
  480. setTimeout(e=>{
  481. this.tapVideoHover("reset");
  482. this.checkTextLines(0);
  483. },100)
  484. this.leftTimers=setTimeout(e=>{
  485. this.dataList[0].isShowGoods=true;
  486. },3000);
  487. }
  488. if(this.isPostBack){
  489. this.isPostBack=false;
  490. this.getBrowse();
  491. }
  492. }else{
  493. this.isEmpty = true
  494. this.dataList = []
  495. this.refreshing = false;
  496. this.isShowTab=true;
  497. }
  498. },
  499. rej => {
  500. uni.hideLoading()
  501. }
  502. ).catch(()=>{
  503. uni.hideLoading()
  504. //联网失败, 结束加载
  505. this.refreshing = false;
  506. this.isShowTab=true;
  507. });
  508. },
  509. touchstart(event) {
  510. this.dataList[this.k].isShowimage = true //刚触摸的时候就要显示预览视频图片了
  511. this.dataList[this.k].isShowProgressBarTime = true //显示时间线
  512. this.ProgressBarOpacity = 1 //让滑块显示起来更明显一点
  513. this.dotWidth = 10 //让点显示起来更明显一点
  514. },
  515. touchend() { //当手松开后,跳到最新时间
  516. console.log('touchEnd');
  517. uni.createVideoContext(this.dataList[this.k].id, this).seek(this.newTime)
  518. if (this.dataList[this.k].state == 'pause') {
  519. this.dataList[this.k].state = 'play'
  520. uni.createVideoContext(this.dataList[this.k].id, this).play();
  521. console.log('touchEnd 播放数据',this.k,this.dataList[this.k].id);
  522. }
  523. this.dataList[this.k].isShowProgressBarTime = false //触摸结束后,隐藏时间线
  524. this.dataList[this.k].isShowimage = false //触摸结束后,隐藏时间预览
  525. this.ProgressBarOpacity = 0.5 //隐藏起来进度条,不那么明显了
  526. this.dotWidth = 0 //隐藏起来进度条,不那么明显了
  527. },
  528. touchmove(event) { //当手移动滑块时,计算位置、百分小数、新的时间
  529. var msg = []
  530. if (this.videoTime !== '') {
  531. msg = this.videoTime.split(':')
  532. }
  533. var timeNumber = Number(msg[0]) * 60 + Number(msg[1])
  534. this.currentPositions = event.changedTouches[0].screenX
  535. this.percent = this.currentPositions / this.windowWidth
  536. this.newTime = this.percent * timeNumber
  537. this.currenttimes = parseInt(this.newTime)
  538. let theTime = this.newTime
  539. let middle = 0; // 分
  540. if (theTime > 60) {
  541. middle = parseInt(theTime / 60);
  542. theTime = parseInt(theTime % 60);
  543. }
  544. this.changeTime = `${Math.round(middle)>9?Math.round(middle):'0'+Math.round(middle)}:${Math.round(theTime)>9?Math.round(theTime):'0'+Math.round(theTime)}`
  545. },
  546. tapVideoHover(state,event){
  547. this.dataList[this.k].isShowimage = false
  548. this.dataList[this.k].isShowProgressBarTime = false
  549. this.ProgressBarOpacity = 0.5
  550. this.dotWidth = 0
  551. // 1.启用双击点赞 --- start
  552. if(state=='play'||state=='continue'){
  553. this.dataList[this.k].state = 'pause';
  554. }
  555. else if(state=='reset'){
  556. this.dataList[this.k].state = 'reset';
  557. }
  558. else{
  559. this.dataList[this.k].state = 'continue';
  560. }
  561. this.dataList[this.k].isShowPlayIcon = true;
  562. //console.log('xxx',this.dataList[this.k].state);
  563. if(this.dataList[this.k].state == 'continue'){
  564. //console.log('播放数据',this.dataList[this.k].id);
  565. uni.createVideoContext(this.dataList[this.k].id,this).play();//暂停以后继续播放
  566. }
  567. if(this.dataList[this.k].state == 'pause'){
  568. uni.createVideoContext(this.dataList[this.k].id,this).pause();//暂停以后继续播放
  569. }
  570. if(this.dataList[this.k].state == 'reset'){
  571. uni.createVideoContext(this.dataList[this.k].id,this).seek(0);
  572. uni.createVideoContext(this.dataList[this.k].id,this).play();//暂停以后继续播放
  573. this.dataList[this.k].state = 'continue';
  574. }
  575. },
  576. scrolls (event) {
  577. this.isDragging = event.isDragging;
  578. if (!event.isDragging) {//isDragging:判断用户是不是在滑动,滑动:true,停止滑动:false。我们要用户停止滑动时才给 k 赋值,这样就可以避免很多麻烦
  579. var i = Math.round(Math.abs(event.contentOffset.y) / (this.wHeight - this.deleteHeight - this.statusBarHeight + 1))//先用绝对值取出滑动的距离,然后除以屏幕高度,取一个整,就知道你现在滑动到哪一个视频了
  580. //console.log("qxj k:"+this.k+" i:"+i);
  581. if(i !== this.k){
  582. //这里加判断是因为这个方法会执行很多次,会造成重复请求,所以这里写一个限制
  583. let num = 0;
  584. clearTimeout(this.timers);
  585. this.timers = setTimeout(()=>{
  586. this.k = i;//判断了用户没有滑动,确认了用户的确是在看这个视频,然后就赋值啦
  587. this.dataList[this.k].state = 'play';
  588. //console.log('正在播放 --> 第' + (this.k + 1) + '个视频~');
  589. this.checkTextLines(i);
  590. this.getBrowse();
  591. },num);
  592. if(!isLogin()){
  593. if(this.viewVideoNum%2==0){
  594. showLoginPage();
  595. }
  596. this.viewVideoNum++;
  597. }
  598. clearTimeout(this.leftTimers);
  599. this.leftTimers=setTimeout(e=>{
  600. this.dataList[this.k].isShowGoods=true;
  601. },3000);
  602. }
  603. }
  604. },
  605. handleDoLike(item,index){
  606. if (this.doLikeDisabled) return;
  607. this.doLikeDisabled = true;
  608. this.doLike(item, i);
  609. setTimeout(() => {
  610. this.doLikeDisabled = false;
  611. }, 1000); // 1秒后重新启用方法
  612. },
  613. doLike(item,index){
  614. if(!isLogin()){
  615. showLoginPage();
  616. return;
  617. }
  618. doLike(item.videoId).then(res => {
  619. if(res.code==200){
  620. if(item.like==0){
  621. item.like=1;
  622. item.likeNum+=1;
  623. }else{
  624. item.like=0;
  625. item.likeNum-=1;
  626. }
  627. this.dataList[index]=item;
  628. this.$forceUpdate(); // 如果你需要强制刷新,可以调用 $forceUpdate()
  629. }else{
  630. this.showToast(res.msg);
  631. }
  632. },
  633. rej => {}
  634. );
  635. },
  636. doFavorite(item,index){
  637. if(!isLogin()){
  638. showLoginPage();
  639. return;
  640. }
  641. doFavorite(item.videoId).then(res => {
  642. if(res.code==200){
  643. if(item.favorite==0){
  644. item.favorite=1;
  645. item.favoriteNum+=1;
  646. }else{
  647. item.favorite=0;
  648. item.favoriteNum-=1;
  649. }
  650. this.dataList[index]=item;
  651. this.$forceUpdate(); // 如果你需要强制刷新,可以调用 $forceUpdate()
  652. }
  653. else{
  654. this.showToast(res.msg);
  655. }
  656. },
  657. rej => {}
  658. );
  659. },
  660. addIntegral(){
  661. if(!isLogin()){
  662. return;
  663. }
  664. addIntegral(2).then(res => {
  665. if(res.code==200){
  666. uni.showToast({icon:'none',title:res.msg,duration:3000,position:'bottom'});
  667. }
  668. },
  669. rej => {}
  670. );
  671. },
  672. tabChange (index) {
  673. this.tabIndex=index;
  674. },
  675. playIngs:function(){
  676. },
  677. openComment(item){
  678. const subNVue = uni.getSubNVueById('videoComment');
  679. subNVue.show('slide-in-bottom', 250);
  680. uni.$emit('videoComment', {
  681. videoId: item.videoId,
  682. smsNum:item.smsNum,
  683. subNVueName: 'videoComment'
  684. });
  685. },
  686. closePro(item,index){
  687. item.isShowGoods=false;
  688. this.dataList[index]=item;
  689. this.$forceUpdate();
  690. },
  691. goToPro(item){ //跳转疗法页面
  692. uni.navigateTo({
  693. url: "/pages/store/packageDetails?packageId="+item.productId
  694. });
  695. },
  696. click:function(){
  697. },
  698. onClickItem(e) {
  699. if (this.tabIndex !== e.currentIndex) {
  700. this.tabIndex = e.currentIndex
  701. }
  702. },
  703. getRichText(content) {
  704. content = new HTMLParser(content.trim())
  705. return content
  706. },
  707. checkTextLines(index) {
  708. var system = uni.getSystemInfoSync();
  709. let textWidth=system.screenWidth-uni.upx2px(150+20);
  710. let fontSize=uni.upx2px(30);
  711. let screenWidth=system.screenWidth;
  712. let that=this;
  713. let txtTitle=this.$refs["txtTitle"+index];
  714. this.defTitStyle={'opacity':0}
  715. this.showExpand=false;
  716. uni.createSelectorQuery().select("#txtTitle"+index).boundingClientRect(rect => {
  717. setTimeout(e=>{
  718. this.defTitStyle={'opacity':1};
  719. this.showExpand=rect.height>40;
  720. },50);
  721. }).exec();
  722. },
  723. linechange(event){
  724. console.log(event)
  725. const lineCount = event.detail.lineCount //行数
  726. this.lineCount = lineCount
  727. if(lineCount>3){ //如果大于3行,显示展开阅读
  728. this.showExpand = true
  729. }
  730. },
  731. clickExpand(){
  732. this.titIsExpand=!this.titIsExpand;
  733. this.defTitStyle={'opacity':1,'lines':this.titIsExpand?1000:2};
  734. },
  735. openShare(item){
  736. this.shareItem.videoId = item.videoId;
  737. this.shareItem.title=item.title;
  738. this.shareItem.imageUrl=item.cover;
  739. this.shareItem.compressImage = 1
  740. this.shareItem.summary="";
  741. let cdn=uni.getStorageSync('h5Path');
  742. this.shareItem.url=cdn+"/pages/course/video/living-applet?videoId="+item.videoId;
  743. this.showShare=true;
  744. },
  745. getBrowse() { // 倒计时
  746. this.countItem=this.processDatas[this.k];
  747. if(this.countItem==null){
  748. this.countItem={"process":0,"isLoad":false};
  749. this.process=0;
  750. }
  751. this.process=this.countItem.isLoad?100:0;
  752. if(this.interval==null){
  753. this.interval = setInterval(() => {
  754. if(this.showGuide){
  755. return;
  756. }
  757. if (this.process < 100) {
  758. if (this.isCounting) {
  759. this.process = this.process + 1;
  760. this.countItem.process=this.process;
  761. if(this.processDatas[this.k]!=undefined){
  762. this.processDatas.splice(this.k,1,this.countItem);
  763. }else{
  764. this.processDatas.push(this.countItem);
  765. }
  766. }
  767. }
  768. else {
  769. if(!this.countItem.isLoad){
  770. this.addIntegral();
  771. }
  772. clearInterval(this.interval);
  773. this.interval=null;
  774. this.countItem.isLoad=true;
  775. if(this.processDatas[this.k]!=undefined){
  776. this.processDatas.splice(this.k,1,this.countItem);
  777. }else{
  778. this.processDatas.push(this.countItem);
  779. }
  780. }
  781. }, 100);
  782. }
  783. },
  784. onProgress() {
  785. //console.log("------qxj onProgress");
  786. },
  787. timeupdate(){
  788. //console.log("------qxj onTimeupdate");
  789. },
  790. onLoadeddata() {
  791. console.log('------qxj 视频缓冲完成');
  792. },
  793. onVideoCanPlay() {
  794. console.log('------qxj 视频可以开始播放,但可能需要缓冲');
  795. },
  796. onVideoCanPlayThrough() {
  797. console.log('------qxj 视频可以无暂停地播放');
  798. },
  799. onLoadedMetadata(e) {
  800. //console.log("------qxj onLoadedMetadata");
  801. },
  802. endedPlayNext(){
  803. //console.log("------qxj endedPlayNext");
  804. },
  805. onWaiting(){
  806. ////console.log("------qxj onWaiting");
  807. //this.tapVideoHover("");
  808. },
  809. onError(){
  810. console.log("------qxj onError 当前视频播放出错");
  811. uni.showToast({title: "当前视频播放出错",icon: 'none',position:'bottom'});
  812. },
  813. showToast(title){
  814. uni.showToast({icon:'none',title: title ,duration:3000});
  815. },
  816. tapRedpacked(){
  817. },
  818. nextGuide(){
  819. console.log("qxj nextGuide");
  820. clearInterval(this.guideTimer);
  821. this.guideTimer=null;
  822. this.showGuide = false;
  823. uni.setStorageSync(this.step.name, 'true');
  824. uni.createVideoContext(this.dataList[this.k].id,this).pause();//暂停以后继续播放
  825. setTimeout(e=>{
  826. uni.switchTab({url: '/pages/index/index' });
  827. },500);
  828. }
  829. }
  830. }
  831. </script>
  832. <style scoped lang="scss">
  833. .animate-icon {
  834. width:70rpx;
  835. height:70rpx;
  836. transition-duration: 0.5s;
  837. transform:scale(1);
  838. transition-timing-function: linear;
  839. }
  840. .animate-scale{
  841. width:70rpx;
  842. height:70rpx;
  843. transition-duration: 0.5s;
  844. transform:scale(0.88);
  845. transition-timing-function: linear;
  846. }
  847. .emptybox {
  848. align-items: center;
  849. &-img {
  850. width: 320rpx;
  851. height: 240rpx;
  852. }
  853. &-tip {
  854. margin-top: 80rpx;
  855. font-size: 30rpx;
  856. color: gray;
  857. }
  858. }
  859. .view-animation{
  860. transition-duration: 0.2s;
  861. transition-property: height;
  862. }
  863. .search-box {
  864. box-sizing: border-box;
  865. border-radius: 10rpx;
  866. position: relative;
  867. overflow: hidden;
  868. }
  869. .container {
  870. background-color: #000000;
  871. }
  872. .item {
  873. /* width : 750rpx; */
  874. background-color: #000000;
  875. position: relative;
  876. }
  877. .videoHover {
  878. position: absolute;
  879. top: 0;
  880. left: 0;
  881. flex: 1;
  882. background-color: rgba(0, 0, 0, 0.1);
  883. justify-content: center;
  884. align-items: center;
  885. /* border-style: dashed;
  886. border-color: #DD524D;
  887. border-width: 1px; */
  888. }
  889. .playState {
  890. width: 80rpx;
  891. height: 80rpx;
  892. opacity: 0.9;
  893. }
  894. .userInfo {
  895. position: absolute;
  896. bottom: 80px;
  897. right: 10px;
  898. flex-direction: column;
  899. }
  900. .userAvatar {
  901. border-radius: 500%;
  902. margin-bottom: 15px;
  903. border-style: solid;
  904. border-width: 2px;
  905. border-color: #ffffff;
  906. }
  907. .userAvatar {
  908. width: 100rpx;
  909. height: 100rpx;
  910. }
  911. .likeIco,
  912. .shareIco,
  913. .commentIco {
  914. width: 60rpx;
  915. height: 60rpx;
  916. margin-top: 15px;
  917. }
  918. .likeNum,
  919. .commentNum,
  920. .shareTex {
  921. color: #ffffff;
  922. font-size: 30rpx;
  923. text-align: center;
  924. margin: 5px;
  925. }
  926. .likeNumActive {
  927. color: red;
  928. }
  929. .content {
  930. width: 610rpx;
  931. z-index: 99;
  932. position: absolute;
  933. bottom: 30px;
  934. /* background-color: #007AFF; */
  935. /* justify-content: center; */
  936. padding: 15rpx;
  937. flex-direction: column;
  938. justify-content: flex-start;
  939. color: #ffffff;
  940. }
  941. .userName {
  942. font-size: 30rpx;
  943. color: #ffffff;
  944. margin-top: 80upx;
  945. }
  946. .words {
  947. margin-top: 10rpx;
  948. font-size: 30rpx;
  949. color: #ffffff;
  950. }
  951. .root {
  952. background-color: #000000;
  953. /* background-color: #00ffff; */
  954. }
  955. .person {
  956. position: absolute;
  957. right: 0;
  958. height: 88rpx;
  959. }
  960. .person .num {
  961. background-color: rgba(255, 100, 3, 1);
  962. height: 58rpx;
  963. border-radius: 100rpx 0 0 100rpx;
  964. padding: 0 20rpx;
  965. }
  966. .right,.left {
  967. position: absolute;
  968. bottom: 180rpx;
  969. padding-bottom: env(safe-area-inset-bottom);
  970. }
  971. .right {
  972. right: 30rpx;
  973. bottom: 100rpx;
  974. }
  975. .right .item1 {
  976. width: 100rpx;
  977. }
  978. .right image {
  979. width: 100%;
  980. height: 100%;
  981. }
  982. .left {left: 20rpx;}
  983. .goods .icon,.goods .icon image {
  984. width: 290rpx;
  985. height: 290rpx;
  986. }
  987. .bg {
  988. /* background-image: url(/static/images/other/video/bg.png); */
  989. position: absolute;
  990. left: 0;
  991. top: 0;
  992. width: 100%;
  993. height: 74rpx;
  994. }
  995. .goods {
  996. width: 330rpx;
  997. background-color: rgba(255, 255, 255, 0.4);
  998. padding: 20rpx;
  999. border-radius: 20rpx;
  1000. margin-top: 20rpx;
  1001. }
  1002. .tabbar1{
  1003. position: absolute;
  1004. top: 0;
  1005. padding-top: 44px;
  1006. z-index: 999;
  1007. // height:44px;
  1008. /* background-color:rgba(0,0,0,0.2) ; */
  1009. }
  1010. .border1{
  1011. border-width: 1px;border-color: green;border-style: solid;
  1012. }
  1013. .border2{
  1014. border-width: 1px;border-color: yellow;border-style: solid;
  1015. }
  1016. .refresh {
  1017. display: flex;
  1018. flex-direction: row;
  1019. justify-content: center;
  1020. height: 50px;
  1021. }
  1022. .bottom {
  1023. position: absolute;
  1024. left: 0;
  1025. bottom: 60rpx;
  1026. right: 150rpx;
  1027. padding-bottom: env(safe-area-inset-bottom);
  1028. }
  1029. .txtTitle{
  1030. line-height: 20px;
  1031. /* 超出两行显示省略号,如果是text标签需要设置为1 */
  1032. color: #fff;
  1033. font-weight: 500;
  1034. font-size: 30rpx;
  1035. margin-left:20rpx;
  1036. }
  1037. .ellipsis{
  1038. lines:2;
  1039. /* 确保文本不会自动换行 */
  1040. /* white-space: nowrap; */
  1041. /* 设置文本溢出时显示省略号 */
  1042. text-overflow: ellipsis;
  1043. /* 限制显示的行数为2 */
  1044. overflow: hidden;
  1045. white-space: nowrap; /* 不换行 */
  1046. padding-right: 20px; /* 设置右边距为20px,实现末尾缩进 */
  1047. box-sizing: border-box; /* 包含padding在内的总宽度 */
  1048. }
  1049. .expandBtn{
  1050. position: absolute;
  1051. right: 0rpx;
  1052. bottom: 0rpx;
  1053. font-weight: 600;
  1054. color: #fff;
  1055. font-size: 30rpx;
  1056. /* background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 50%); */
  1057. }
  1058. .redpacked{
  1059. position: fixed;
  1060. width: 86rpx;
  1061. height: 86rpx;
  1062. top: 300rpx;
  1063. z-index: 999;
  1064. left: 30rpx;
  1065. background-color: rgba(0, 0, 0, 0.4);
  1066. }
  1067. .guide {
  1068. left: 0;
  1069. top: 0;
  1070. position: absolute;
  1071. z-index: 10001;
  1072. .guide-box {
  1073. position: absolute;
  1074. z-index: 10001;
  1075. background-color: rgba(0, 0, 0, 0.6);
  1076. // transition: all 0.2s;
  1077. .arrow {
  1078. width: 28rpx;
  1079. height: 28rpx;
  1080. background: #fff;
  1081. position: absolute;
  1082. top: 0;
  1083. left: 48rpx;
  1084. z-index: 10000;
  1085. transform: rotate(45deg);
  1086. }
  1087. .guide-step-tips {
  1088. width: 424rpx;
  1089. padding: 0 24rpx 24rpx 24rpx;
  1090. box-sizing: border-box;
  1091. border-radius: 12rpx;
  1092. background-color: #fff;
  1093. font-family: PingFang SC, PingFang SC;
  1094. font-weight: 400;
  1095. font-size: 26rpx;
  1096. color: #757575;
  1097. position: relative;
  1098. }
  1099. .tips {
  1100. position: absolute;
  1101. top: 0;
  1102. left: 0;
  1103. z-index: 10001;
  1104. .text {}
  1105. .tool-btn {
  1106. margin-top: 20rpx;
  1107. display: flex;
  1108. flex-direction: row;
  1109. align-items: center;
  1110. justify-content:space-between;
  1111. font-weight: 400;
  1112. font-size: 26rpx;
  1113. color: #757575;
  1114. .next {
  1115. width: 128rpx;
  1116. height: 68rpx;
  1117. line-height: 68rpx;
  1118. text-align: center;
  1119. background: #FF5C03;
  1120. border-radius: 8rpx 8rpx 8rpx 8rpx;
  1121. font-family: PingFang SC, PingFang SC;
  1122. font-weight: 400;
  1123. font-size: 26rpx;
  1124. color: #FFFFFF;
  1125. }
  1126. }
  1127. }
  1128. }
  1129. }
  1130. .liveguide {
  1131. display: flex;
  1132. flex-direction: column;
  1133. align-items: center;
  1134. justify-content: center;
  1135. flex: 1;
  1136. .phone_icon {
  1137. width: 144rpx;
  1138. height: 262rpx;
  1139. }
  1140. }
  1141. .hand_icon {
  1142. height: 177rpx;
  1143. width: 177rpx;
  1144. margin-top: -100rpx;
  1145. margin-left: 118rpx;
  1146. margin-bottom: 20rpx;
  1147. // animation: moveUpDown 1.8s ease-in-out infinite; /* 使用简写属性 */
  1148. // animation-name: moveUpDown;
  1149. // animation-duration: 1.8s;
  1150. // animation-timing-function: ease-in-out;
  1151. // animation-iteration-count: infinite;
  1152. // /* 以下是其他可选属性,默认值已设置 */
  1153. // animation-delay: 0s; /* 默认值 */
  1154. // animation-direction: normal; /* 默认值 */
  1155. // animation-fill-mode: none; /* 默认值 */
  1156. // animation-play-state: running; /* 默认值 */
  1157. }
  1158. .target {
  1159. transform: translateY(20px);
  1160. transition:transform .9s ;
  1161. }
  1162. .origin {
  1163. transform: translateY(0px);
  1164. transition-property:transform;
  1165. transition-duration: .9s;
  1166. }
  1167. .liveguide-tip {
  1168. font-family: PingFang SC, PingFang SC;
  1169. font-weight: 600;
  1170. font-size: 36rpx;
  1171. color: #ffffff !important;
  1172. }
  1173. </style>