share.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. //隐藏等级
  146. // ctx.fillText(`${_this.userServerInfo.level_name}排行榜`, uni.upx2px(375), uni.upx2px(405));
  147. ctx.fillText(`排行榜`, uni.upx2px(375), uni.upx2px(405));
  148. ctx.setFontSize(uni.upx2px(28));
  149. ctx.fillText(
  150. `大卫博士学位争霸赛第${_this.userServerInfo.season}季 ${filters.dateFormatter(Date.now(), 'yyyy年MM月dd日 hh:mm')}`,
  151. uni.upx2px(370),
  152. uni.upx2px(1350)
  153. );
  154. ctx.draw();
  155. _this.$hideLoading();
  156. },
  157. fail: err => {
  158. uni.showModal({
  159. content: '获取背景图失败',
  160. showCancel: false,
  161. success: res => {
  162. if (res.confirm) {
  163. uni.navigateBack({});
  164. }
  165. }
  166. });
  167. }
  168. });
  169. }
  170. });
  171. }
  172. };
  173. </script>
  174. <style lang="scss">
  175. .container {
  176. .certificate {
  177. .bg {
  178. width: 100%;
  179. height: 100%;
  180. }
  181. }
  182. .share {
  183. padding: 22rpx 90rpx;
  184. background-color: #ffbf2a;
  185. display: flex;
  186. justify-content: center;
  187. flex-direction: column;
  188. align-items: center;
  189. color: #fa6b3d;
  190. font-size: 32rpx;
  191. .item {
  192. width: 100%;
  193. height: 110rpx;
  194. line-height: 110rpx;
  195. text-align: center;
  196. background-color: #f85820;
  197. border-radius: 110rpx;
  198. padding: 0;
  199. margin: 0;
  200. box-shadow: 0 0 5px rgba(233, 87, 55, 0.45);
  201. &::after,
  202. &::before {
  203. border: none;
  204. }
  205. color: #ffd252;
  206. font-size: 50rpx;
  207. margin-bottom: 16rpx;
  208. }
  209. }
  210. }
  211. .honour {
  212. @include page();
  213. height: auto;
  214. min-height: 100%;
  215. overflow: inherit;
  216. &.share {
  217. border-top-color: #493225;
  218. }
  219. .content {
  220. display: flex;
  221. flex-direction: column;
  222. .top {
  223. width: 100%;
  224. height: 680rpx;
  225. background: #493225;
  226. border-bottom-right-radius: 375rpx 123rpx;
  227. border-bottom-left-radius: 375rpx 123rpx;
  228. position: relative;
  229. &.share {
  230. height: 890rpx;
  231. }
  232. #canvas {
  233. position: absolute;
  234. top: 56rpx;
  235. left: 50%;
  236. transform: translateX(-50%);
  237. &.share {
  238. top: 0;
  239. }
  240. }
  241. .bg {
  242. position: absolute;
  243. width: 566rpx;
  244. height: 464rpx;
  245. top: 35rpx;
  246. left: 50%;
  247. z-index: 1;
  248. transform: translateX(-50%);
  249. }
  250. .all {
  251. position: absolute;
  252. right: 32rpx;
  253. bottom: -13rpx;
  254. font-size: 26rpx;
  255. color: #fa6342;
  256. }
  257. }
  258. .bot {
  259. flex: 1;
  260. box-sizing: border-box;
  261. padding: 100rpx;
  262. .title {
  263. text-align: center;
  264. height: 45rpx;
  265. display: flex;
  266. justify-content: center;
  267. align-items: center;
  268. font-size: 36rpx;
  269. color: #fa6342;
  270. text {
  271. margin: 0 40rpx;
  272. }
  273. image {
  274. width: 48rpx;
  275. height: 45rpx;
  276. }
  277. }
  278. .text {
  279. margin-top: 80rpx;
  280. font-size: 30rpx;
  281. color: #666666;
  282. }
  283. .share-save {
  284. height: 60rpx;
  285. margin-top: 80rpx;
  286. display: flex;
  287. justify-content: space-between;
  288. .button {
  289. height: 100%;
  290. width: 240rpx;
  291. box-sizing: border-box;
  292. border: 2rpx solid #fa6342;
  293. border-radius: 30rpx;
  294. line-height: 56rpx;
  295. text-align: center;
  296. color: #fa6342;
  297. background: #ffffff;
  298. padding: 0;
  299. font-size: 24rpx;
  300. text {
  301. margin: 0 6rpx;
  302. vertical-align: middle;
  303. &.cuIcon {
  304. font-size: 36rpx;
  305. }
  306. }
  307. }
  308. }
  309. }
  310. }
  311. }
  312. </style>