share.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <template>
  2. <view class="honour" v-if="isAjaxed">
  3. <custom-nav title="排行版"></custom-nav>
  4. <custom-toast ref="toast"></custom-toast>
  5. <view class="container">
  6. <view class="certificate"><canvas id="canvas" canvas-id="canvas" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas></view>
  7. <view class="share">
  8. <view class="item" @tap="saveImg"><view>保存图片</view></view>
  9. <text>保存图片去朋友圈晒晒吧~</text>
  10. </view>
  11. </view>
  12. </view>
  13. </template>
  14. <script>
  15. import { api_getHonourInfo } from '../../api.js';
  16. import * as filters from '../../common/js/filters.js';
  17. export default {
  18. data() {
  19. return {
  20. pageTitle: '荣耀殿堂', //页面名
  21. canvasWidth: 0, //canvas 宽
  22. canvasHeight: 0, //canvas 高
  23. name: '', //名字
  24. season: '',
  25. grade: '', //学位
  26. year: '', //年
  27. month: '', //月
  28. day: '', //日
  29. fromIndex: true, //是否非分享页面,
  30. header: '',
  31. headerImg: '',
  32. deg: '',
  33. isAjaxed: false
  34. };
  35. },
  36. computed: {
  37. userServerInfo() {
  38. return this.$store.state.userServerInfo;
  39. },
  40. userWeixinInfo() {
  41. return this.$store.state.userWeixinInfo;
  42. }
  43. },
  44. methods: {
  45. saveImg() {
  46. //保存证书到本地
  47. uni.canvasToTempFilePath({
  48. //首先将 canvas 转化为一个图片
  49. canvasId: 'canvas'
  50. })
  51. .then(([, res]) => {
  52. //获得图片的临时路径
  53. return uni.saveImageToPhotosAlbum({
  54. //将图片保存到系统相册
  55. filePath: res.tempFilePath
  56. });
  57. })
  58. .then(([err, res]) => {
  59. if (err && (err.errMsg === 'saveImageToPhotosAlbum:fail:auth denied' || err.errMsg === 'saveImageToPhotosAlbum:fail auth deny')) {
  60. //如果用户拒绝授权保存图片到相册
  61. const that = this;
  62. uni.showModal({
  63. title: '"大卫博士学位争霸赛"需要保存图片或视频到你的相册',
  64. content: '',
  65. success(res) {
  66. if (res.confirm) {
  67. wx.openSetting({
  68. success(res) {
  69. that.saveImg();
  70. return;
  71. }
  72. });
  73. }
  74. }
  75. });
  76. } else if (err && err.errMsg === 'saveImageToPhotosAlbum:fail authorize no response') {
  77. uni.showModal({
  78. content: '保存图片失败,请手动截图保存',
  79. showCancel: false
  80. });
  81. }
  82. if (res && res.errMsg === 'saveImageToPhotosAlbum:ok') {
  83. uni.showModal({
  84. content: '图片已经保存成功',
  85. showCancel: false
  86. });
  87. }
  88. });
  89. }
  90. },
  91. async onLoad(opt) {
  92. //当进入页面之后判断是否带带有参数
  93. uni.hideShareMenu();
  94. this.header = this.userServerInfo.avatar
  95. uni.showLoading({
  96. title: '加载中',
  97. mask: true
  98. });
  99. let _this = this;
  100. uni.downloadFile({
  101. url: this.header,
  102. success: ({ statusCode, tempFilePath }) => {
  103. if (statusCode === 200) {
  104. this.headerImg = tempFilePath;
  105. }
  106. },
  107. fail: e => {
  108. console.log(e);
  109. uni.showToast({
  110. icon: 'none',
  111. title: '获取用户头像失败',
  112. duration: 3000
  113. });
  114. },
  115. complete: () => {
  116. uni.getImageInfo({
  117. src: 'https://api.jiuweiyun.cn/public/uploads/weapp/icon/phb_bg.png',
  118. success: res => {
  119. this.isAjaxed = true;
  120. uni.hideLoading(); //停止 loading
  121. _this.canvasWidth = uni.upx2px(750);
  122. _this.canvasHeight = uni.upx2px(1385);
  123. _this.name = '刘德华' || _this.userServerInfo.name; //姓名
  124. _this.name = _this.name.slice(0, 6);
  125. _this.season = 23 || _this.userServerInfo.season; // 赛季季数
  126. const ctx = uni.createCanvasContext('canvas');
  127. ctx.drawImage(res.path, 0, 0, _this.canvasWidth, _this.canvasHeight);
  128. ctx.save();
  129. ctx.beginPath();
  130. ctx.arc(uni.upx2px(375), uni.upx2px(844), uni.upx2px(64), 0, 2 * Math.PI, false);
  131. ctx.clip();
  132. ctx.drawImage(_this.headerImg, uni.upx2px(311), uni.upx2px(780), uni.upx2px(128), uni.upx2px(128));
  133. ctx.restore();
  134. ctx.setTextAlign('center');
  135. ctx.setFontSize(uni.upx2px(30));
  136. ctx.setFillStyle('#F85820');
  137. ctx.fillText(`${_this.userServerInfo.score}分`, uni.upx2px(470), uni.upx2px(1080));
  138. ctx.fillText(
  139. `${_this.userServerInfo.rank}名(超过${_this.userServerInfo.score === 0 ? 0 : _this.userServerInfo.count - _this.userServerInfo.rank}人)`,
  140. uni.upx2px(480),
  141. uni.upx2px(1204)
  142. );
  143. ctx.fillText(_this.userServerInfo.name, uni.upx2px(380), uni.upx2px(960));
  144. ctx.setFillStyle('#FFFFFF');
  145. ctx.fillText(`${_this.userServerInfo.level_name}排行榜`, uni.upx2px(375), uni.upx2px(405));
  146. ctx.setFontSize(uni.upx2px(28));
  147. ctx.fillText(
  148. `大卫博士学位争霸赛第${_this.userServerInfo.season}季 ${filters.dateFormatter(Date.now(), 'yyyy年MM月dd日 hh:mm')}`,
  149. uni.upx2px(370),
  150. uni.upx2px(1350)
  151. );
  152. ctx.draw();
  153. _this.$hideLoading();
  154. },
  155. fail: err => {
  156. uni.showModal({
  157. content: '获取背景图失败',
  158. showCancel: false,
  159. success: res => {
  160. if (res.confirm) {
  161. uni.navigateBack({});
  162. }
  163. }
  164. });
  165. }
  166. });
  167. }
  168. });
  169. }
  170. };
  171. </script>
  172. <style lang="scss">
  173. .container {
  174. .certificate {
  175. .bg {
  176. width: 100%;
  177. height: 100%;
  178. }
  179. }
  180. .share {
  181. padding: 22rpx 90rpx;
  182. background-color: #ffbf2a;
  183. display: flex;
  184. justify-content: center;
  185. flex-direction: column;
  186. align-items: center;
  187. color: #fa6b3d;
  188. font-size: 32rpx;
  189. .item {
  190. width: 100%;
  191. height: 110rpx;
  192. line-height: 110rpx;
  193. text-align: center;
  194. background-color: #f85820;
  195. border-radius: 110rpx;
  196. padding: 0;
  197. margin: 0;
  198. box-shadow: 0 0 5px rgba(233, 87, 55, 0.45);
  199. &::after,
  200. &::before {
  201. border: none;
  202. }
  203. color: #ffd252;
  204. font-size: 50rpx;
  205. margin-bottom: 16rpx;
  206. }
  207. }
  208. }
  209. .honour {
  210. @include page();
  211. height: auto;
  212. min-height: 100%;
  213. overflow: inherit;
  214. &.share {
  215. border-top-color: #493225;
  216. }
  217. .content {
  218. display: flex;
  219. flex-direction: column;
  220. .top {
  221. width: 100%;
  222. height: 680rpx;
  223. background: #493225;
  224. border-bottom-right-radius: 375rpx 123rpx;
  225. border-bottom-left-radius: 375rpx 123rpx;
  226. position: relative;
  227. &.share {
  228. height: 890rpx;
  229. }
  230. #canvas {
  231. position: absolute;
  232. top: 56rpx;
  233. left: 50%;
  234. transform: translateX(-50%);
  235. &.share {
  236. top: 0;
  237. }
  238. }
  239. .bg {
  240. position: absolute;
  241. width: 566rpx;
  242. height: 464rpx;
  243. top: 35rpx;
  244. left: 50%;
  245. z-index: 1;
  246. transform: translateX(-50%);
  247. }
  248. .all {
  249. position: absolute;
  250. right: 32rpx;
  251. bottom: -13rpx;
  252. font-size: 26rpx;
  253. color: #fa6342;
  254. }
  255. }
  256. .bot {
  257. flex: 1;
  258. box-sizing: border-box;
  259. padding: 100rpx;
  260. .title {
  261. text-align: center;
  262. height: 45rpx;
  263. display: flex;
  264. justify-content: center;
  265. align-items: center;
  266. font-size: 36rpx;
  267. color: #fa6342;
  268. text {
  269. margin: 0 40rpx;
  270. }
  271. image {
  272. width: 48rpx;
  273. height: 45rpx;
  274. }
  275. }
  276. .text {
  277. margin-top: 80rpx;
  278. font-size: 30rpx;
  279. color: #666666;
  280. }
  281. .share-save {
  282. height: 60rpx;
  283. margin-top: 80rpx;
  284. display: flex;
  285. justify-content: space-between;
  286. .button {
  287. height: 100%;
  288. width: 240rpx;
  289. box-sizing: border-box;
  290. border: 2rpx solid #fa6342;
  291. border-radius: 30rpx;
  292. line-height: 56rpx;
  293. text-align: center;
  294. color: #fa6342;
  295. background: #ffffff;
  296. padding: 0;
  297. font-size: 24rpx;
  298. text {
  299. margin: 0 6rpx;
  300. vertical-align: middle;
  301. &.cuIcon {
  302. font-size: 36rpx;
  303. }
  304. }
  305. }
  306. }
  307. }
  308. }
  309. }
  310. </style>