app-video.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <template>
  2. <view class="app-video app-content" :style="{width: width, height: height}" @click.stop="preventD">
  3. <view class="app-video app-image" @click.stop="play" v-if="!start">
  4. <image :src="picUrl" class="app-image" style="width: 100%;height:100%"></image>
  5. <view class="app-play app-image">
  6. <icon class="app-play-icon"></icon>
  7. </view>
  8. </view>
  9. <video id="myVideo" @fullscreenchange="fullscreenChange" v-else class="app-video video" :style="{width: width, height: height}" :autoplay="start" show-center-play-btn @error="error" :src="url"></video>
  10. </view>
  11. </template>
  12. <script>
  13. import * as event from '../../../core/event.js';
  14. export default {
  15. name: "app-video",
  16. data() {
  17. return {
  18. start: false,
  19. fullScreen: false,
  20. maxTop: 0
  21. }
  22. },
  23. props: {
  24. picUrl: {
  25. type: String,
  26. default: () => {
  27. return '';
  28. }
  29. },
  30. url: {
  31. type: String,
  32. default() {
  33. return '';
  34. }
  35. },
  36. width: {
  37. type: String,
  38. default() {
  39. return `750rpx`;
  40. }
  41. },
  42. height: {
  43. type: String,
  44. default() {
  45. return `422rpx`;
  46. }
  47. },
  48. },
  49. methods: {
  50. fullscreenChange(e) {
  51. this.fullScreen = e.detail.fullScreen;
  52. },
  53. play() {
  54. this.$nextTick().then(() => {
  55. this.start = true;
  56. });
  57. event.trigger(this.$const.EVENT_VIDEO_END);
  58. this.$emit('videoStart', true);
  59. event.on(this.$const.EVENT_VIDEO_END, true).then(() => {
  60. this.start = false;
  61. this.$emit('videoStart', false);
  62. });
  63. },
  64. autoEnd() {
  65. let query = null;
  66. /* #ifndef MP-ALIPAY */
  67. query = this.createSelectorQuery();
  68. /* #endif */
  69. /* #ifdef MP-ALIPAY */
  70. query = uni.createSelectorQuery();
  71. /* #endif */
  72. query.select('.video').boundingClientRect();
  73. query.selectViewport().scrollOffset();
  74. query.exec(res => {
  75. if (res[0].top <= -200 || res[0].top >= this.maxTop - 57) {
  76. event.trigger(this.$const.EVENT_VIDEO_END);
  77. }
  78. });
  79. },
  80. preventD() {
  81. },
  82. },
  83. computed: {
  84. scrollTop() {
  85. return this.$store.state.page.scrollTop;
  86. }
  87. },
  88. created() {
  89. this.maxTop = uni.getSystemInfoSync().windowHeight;
  90. },
  91. watch: {
  92. scrollTop: {
  93. handler() {
  94. if (!this.start || this.fullScreen) return;
  95. this.$utils.throttle(this.autoEnd, 500);
  96. },
  97. immediate: true
  98. }
  99. }
  100. }
  101. </script>
  102. <style scoped lang="scss">
  103. .app-content {
  104. position: relative;
  105. }
  106. .app-image {
  107. position: absolute;
  108. top: 0;
  109. left: 0;
  110. z-index: 100;
  111. width: 100%;
  112. height:100%;
  113. }
  114. .app-play-icon {
  115. width:#{130rpx};
  116. height: #{130rpx};
  117. background-image: url("../../../static/image/icon/play.png");
  118. background-size:100% 100%;
  119. position: absolute;
  120. top: 50%;
  121. z-index: 100;
  122. left: 50%;
  123. transform: translate(-50%, -50%);
  124. }
  125. </style>