index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <!-- 海报弹窗 -->
  2. <template>
  3. <su-popup :show="show" round="10" @close="onClosePoster" type="center" class="popup-box">
  4. <view class="ss-flex-col ss-col-center ss-row-center">
  5. <view
  6. v-if="poster.src === ''"
  7. class="poster-title ss-flex ss-row-center"
  8. :style="{
  9. height: poster.height + 'px',
  10. width: poster.width + 'px',
  11. }"
  12. >
  13. 海报加载中...
  14. </view>
  15. <image
  16. v-else
  17. class="poster-img"
  18. :src="poster.src"
  19. :style="{
  20. height: poster.height + 'px',
  21. width: poster.width + 'px',
  22. }"
  23. :show-menu-by-longpress="true"
  24. />
  25. <canvas
  26. class="hideCanvas"
  27. :canvas-id="poster.canvasId"
  28. :id="poster.canvasId"
  29. :style="{
  30. height: poster.height + 'px',
  31. width: poster.width + 'px',
  32. }"
  33. />
  34. <view
  35. class="poster-btn-box ss-m-t-20 ss-flex ss-row-between ss-col-center"
  36. v-if="poster.src !== ''"
  37. >
  38. <button class="cancel-btn ss-reset-button" @tap="onClosePoster">取消</button>
  39. <button class="save-btn ss-reset-button ui-BG-Main" @tap="onSavePoster">
  40. {{
  41. ['wechatOfficialAccount', 'H5'].includes(sheep.$platform.name)
  42. ? '长按图片保存'
  43. : '保存图片'
  44. }}
  45. </button>
  46. </view>
  47. </view>
  48. </su-popup>
  49. </template>
  50. <script setup>
  51. import { reactive, getCurrentInstance } from 'vue';
  52. import sheep from '@/sheep';
  53. import useCanvas from './useCanvas';
  54. const props = defineProps({
  55. show: {
  56. type: Boolean,
  57. default: false,
  58. },
  59. shareInfo: {
  60. type: Object,
  61. default() {},
  62. },
  63. });
  64. const poster = reactive({
  65. canvasId: 'canvasId',
  66. width: sheep.$platform.device.windowWidth * 0.9,
  67. height: 600,
  68. src: '',
  69. });
  70. const emits = defineEmits(['success', 'close']);
  71. const vm = getCurrentInstance();
  72. const onClosePoster = () => {
  73. emits('close');
  74. };
  75. // 保存海报图片
  76. const onSavePoster = () => {
  77. if (['WechatOfficialAccount', 'H5'].includes(sheep.$platform.name)) {
  78. sheep.$helper.toast('请长按图片保存');
  79. return;
  80. }
  81. uni.saveImageToPhotosAlbum({
  82. filePath: poster.src,
  83. success: (res) => {
  84. onClosePoster();
  85. sheep.$helper.toast('保存成功');
  86. },
  87. fail: (err) => {
  88. sheep.$helper.toast('保存失败');
  89. console.log('图片保存失败:', err);
  90. },
  91. });
  92. };
  93. // 使用 canvas 生成海报
  94. async function getPoster(params) {
  95. poster.src = '';
  96. poster.shareInfo = props.shareInfo;
  97. // #ifdef APP-PLUS
  98. poster.canvasId = 'canvasId-' + new Date().getTime();
  99. // #endif
  100. const canvas = await useCanvas(poster, vm);
  101. return canvas;
  102. }
  103. defineExpose({
  104. getPoster,
  105. });
  106. </script>
  107. <style lang="scss" scoped>
  108. .popup-box {
  109. position: relative;
  110. }
  111. .poster-title {
  112. color: #999;
  113. }
  114. // 分享海报
  115. .poster-btn-box {
  116. width: 600rpx;
  117. position: absolute;
  118. left: 50%;
  119. transform: translateX(-50%);
  120. bottom: -80rpx;
  121. .cancel-btn {
  122. width: 240rpx;
  123. height: 70rpx;
  124. line-height: 70rpx;
  125. background: $white;
  126. border-radius: 35rpx;
  127. font-size: 28rpx;
  128. font-weight: 500;
  129. color: $dark-9;
  130. }
  131. .save-btn {
  132. width: 240rpx;
  133. height: 70rpx;
  134. line-height: 70rpx;
  135. border-radius: 35rpx;
  136. font-size: 28rpx;
  137. font-weight: 500;
  138. }
  139. }
  140. .poster-img {
  141. border-radius: 20rpx;
  142. }
  143. .hideCanvas {
  144. position: fixed;
  145. top: -99999rpx;
  146. left: -99999rpx;
  147. z-index: -99999;
  148. }
  149. </style>