certificateDetailCanvas.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <!-- 分享招聘会 -->
  2. <template>
  3. <view style="position: relative;">
  4. <view v-if="shareUrl" class="d-flex align-center flex-column justify-center" style="height: 100vh;">
  5. <image v-if="!!shareUrl" :style="imgStyle" @click="handlePreviewSharePoster" :src="shareUrl" :show-menu-by-longpress="true"></image>
  6. <view class="color-999 ss-m-t-20 font-size-14 ss-m-b-50">点击图片预览,长按图片保存</view>
  7. </view>
  8. <canvas canvas-id="posterCanvas" class="shareCanvas" :style="`width: ${canvasWidth}px; height: ${canvasHeight}px;`"></canvas>
  9. </view>
  10. </template>
  11. <script setup>
  12. import { ref, computed } from 'vue'
  13. import { onLoad } from '@dcloudio/uni-app'
  14. import { timesTampChange } from '@/utils/date'
  15. import { formatName } from '@/utils/getText'
  16. const canvasWidth = 500
  17. const canvasHeight = 700
  18. const shareUrl = ref('')
  19. const windowWidth = ref(0)
  20. const itemData = ref(null)
  21. onLoad(async (options) => {
  22. if (options.itemData) {
  23. itemData.value = JSON.parse(options.itemData)
  24. createPoster()
  25. }
  26. const windowInfo = wx.getWindowInfo()
  27. windowWidth.value = windowInfo.windowWidth
  28. })
  29. const imgStyle = computed(() => {
  30. if (windowWidth.value <= 320) return `width: 259px; height: ${Math.round((canvasHeight*259)/canvasWidth)}px;`
  31. if (windowWidth.value > 320 && windowWidth.value <= 375) return `width: 313px; height: ${Math.round((canvasHeight*313)/canvasWidth)}px;`
  32. if (windowWidth.value > 375) return `width: 328px; height: ${Math.round((canvasHeight*328)/canvasWidth)}px;`
  33. })
  34. // 图片预览
  35. const handlePreviewSharePoster = () => {
  36. uni.previewImage({
  37. current: 0,
  38. longPressActions: {
  39. itemList: ['发送给朋友', '保存图片', '收藏']
  40. },
  41. urls: [shareUrl.value]
  42. })
  43. }
  44. const getImageTempRatio = (url) => {
  45. return new Promise((req, rej)=>{
  46. wx.getImageInfo({
  47. src:url,
  48. success:(res) =>{
  49. req(res)
  50. }
  51. })
  52. })
  53. }
  54. const createPoster = async () => {
  55. uni.showLoading({ title: '生成中...', mask: true })
  56. var ctx = uni.createCanvasContext('posterCanvas')
  57. //清空画布
  58. ctx.clearRect(0, 0, canvasWidth, canvasHeight)
  59. //背景图片
  60. const { path: bgUrl } = await getImageTempRatio('https://minio.citupro.com/dev/static/bgc.jpg')
  61. ctx.drawImage(bgUrl, 0, 0, canvasWidth, canvasHeight) // 路径、x、y、宽、高
  62. const info = { ...itemData.value }
  63. // 绘制文字内容
  64. ctx.setFontSize(16)
  65. if (info?.student?.schoolName) ctx.fillText(info.student.schoolName, 50, 130)
  66. if (info?.student?.majorName) ctx.fillText(info.student.majorName, 50, 160)
  67. if (info?.person?.name) ctx.fillText(info.person.name, 50, 190)
  68. if (info?.startTime) ctx.fillText(timesTampChange(info.startTime, 'Y-M-D'), 50, 250)
  69. if (info?.endTime) ctx.fillText(timesTampChange(info?.endTime, 'Y-M-D'), 50, 310)
  70. if (info?.enterprise?.anotherName || info?.enterprise?.name) ctx.fillText(formatName(info.enterprise?.anotherName || info.enterprise.name), 50, 400)
  71. if (info?.evaluate) ctx.fillText(info.evaluate, 20, 460)
  72. if (info?.createTime) ctx.fillText(timesTampChange(info?.createTime, 'Y-M-D'), 200, 520)
  73. ctx.font = 'bold';
  74. ctx.fillText('兹有', 20, 100)
  75. ctx.fillText('同学于', 20, 220)
  76. ctx.fillText('至', 20, 280)
  77. ctx.fillText('在', 20, 340)
  78. ctx.fillText('实习。', 20, 430)
  79. ctx.fillText('特此证明。', 20, 490)
  80. ctx.draw(false, () =>{
  81. wx.canvasToTempFilePath({
  82. canvasId: 'posterCanvas',
  83. success:(res)=>{
  84. shareUrl.value = res.tempFilePath
  85. console.log('canvas-success', shareUrl.value)
  86. uni.hideLoading({})
  87. },
  88. fail:(err)=>{
  89. uni.hideLoading({})
  90. console.log('canvas-fail', err)
  91. }
  92. })
  93. })
  94. }
  95. </script>
  96. <style scoped lang="scss">
  97. .shareCanvas {
  98. position: fixed;
  99. top: -99999upx;
  100. left: -99999upx;
  101. z-index: -99999;
  102. }
  103. </style>