bank-item.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <view class="bank-item" :style="bankThem">
  3. <!-- #ifndef MP-WEIXIN -->
  4. <canvas v-if="showCanvas" class="bank-icon" :id="uuid" :canvas-id="uuid" />
  5. <!-- #endif -->
  6. <!-- #ifdef MP-WEIXIN -->
  7. <canvas v-if="showCanvas" class="bank-icon" id="bankIcon" canvas-id="bankIcon" />
  8. <!-- #endif -->
  9. <view class="bank-head">
  10. <image :src="image"></image>
  11. <view class="bank-info">
  12. <text class="bank-name">{{bankName}}</text>
  13. <text class="card-type">{{cardType}}</text>
  14. </view>
  15. </view>
  16. <view class="card-code">
  17. <text class="omit">****</text>
  18. <text class="omit">****</text>
  19. <text class="omit">****</text>
  20. <text>{{endNumber}}</text>
  21. </view>
  22. <view class="bank-watermark" :style="waterMark" />
  23. </view>
  24. </template>
  25. <script>
  26. export default {
  27. name: 'bankItem',
  28. props: {
  29. bankCode: { type: String, required: true},
  30. bankName: { type: String, required: true},
  31. cardType: { type: String, default: '储蓄卡' },
  32. cardCode: { type: String, required: true}
  33. },
  34. computed: {
  35. waterMark() {
  36. return `background-image: url(${this.image});`
  37. },
  38. endNumber() {
  39. let length = this.cardCode.length;
  40. return this.cardCode.substr(length - 4, length);
  41. }
  42. },
  43. data() {
  44. // #ifndef MP-WEIXIN
  45. const buildUuid = () => {
  46. return 'bank_' + parseInt(Math.random() * 100000000);
  47. };
  48. // #endif
  49. return {
  50. bankThem: '',
  51. image: '',
  52. showCanvas: true,
  53. // #ifdef MP-WEIXIN
  54. uuid: 'bankIcon',
  55. // #endif
  56. // #ifndef MP-WEIXIN
  57. uuid: buildUuid()
  58. // #endif
  59. };
  60. },
  61. methods: {
  62. async buildItem() {
  63. this.bankThem = uni.getStorageSync(`BANK_${this.bankCode}`);
  64. this.image = await this.getBankLogo();
  65. await this.getThemColor();
  66. this.showCanvas = false;
  67. },
  68. async getThemColor() {
  69. if(this.bankThem != null && this.bankThem != '') return;
  70. let bgSize = uni.upx2px(100);
  71. let iconSize = uni.upx2px(72);
  72. this.iconContext = uni.createCanvasContext(this.uuid, this);
  73. this.iconContext.width = bgSize;
  74. this.iconContext.height = bgSize;
  75. this.iconContext.fillStyle = '#FFFFFF';
  76. this.iconContext.beginPath();
  77. let bgRadio = bgSize / 2;
  78. this.iconContext.arc(bgRadio, bgRadio, bgRadio - 1 , 0, 2 * Math.PI, 0, true);
  79. this.iconContext.closePath();
  80. this.iconContext.fill();
  81. let iconRadio = bgSize / 2 - iconSize / 2;
  82. this.iconContext.drawImage(this.image, iconRadio, iconRadio, iconSize, iconSize);
  83. await this.draw(this.iconContext);
  84. let imageData = await this.getImageData(iconRadio, iconSize);
  85. this.parsingImageData(imageData);
  86. },
  87. parsingImageData(imageData) {
  88. let statistics = {};
  89. for (let i = 0, length = imageData.length; i < length; i += 4) {
  90. let r = imageData[i];
  91. let g = imageData[i + 1];
  92. let b = imageData[i + 2];
  93. if((r + g + b) < 400) {
  94. let rgb = [r, g, b];
  95. let key = rgb.join(', ');
  96. statistics[key] = statistics[key] == null ? 1 : statistics[key] + 1;
  97. }
  98. }
  99. let maxKey = '';
  100. Object.keys(statistics).forEach(key => {
  101. if (maxKey === '') {
  102. maxKey = key;
  103. } else {
  104. maxKey = statistics[maxKey] > statistics[key] ? maxKey : key;
  105. }
  106. });
  107. let beginColor = maxKey.split(', ').map((item, index) => {
  108. item = parseInt(item);
  109. if(index > 1) return item;
  110. let newColor = item + 50;
  111. return newColor > 255 ? 255 : newColor;
  112. }).join(', ');
  113. this.bankThem = `background-image: linear-gradient(45deg, rgba(${beginColor}, 1), rgba(${maxKey}, 1));`;
  114. uni.setStorageSync(`BANK_${this.bankCode}`, this.bankThem);
  115. },
  116. getImageData(radio, size) {
  117. return new Promise((resolve, reject) => {
  118. uni.canvasGetImageData({
  119. canvasId: this.uuid,
  120. x: radio,
  121. y: radio,
  122. width: size,
  123. height: size,
  124. success(res) {
  125. resolve(res.data);
  126. },
  127. fail(err) {
  128. console.log(err);
  129. reject();
  130. }
  131. },
  132. this
  133. );
  134. });
  135. },
  136. getBankLogo() {
  137. return new Promise((resolve, reject) => {
  138. uni.downloadFile({
  139. url: `https://banklogo.yfb.now.sh/resource/logo/${this.bankCode}.png`,
  140. success(res) {
  141. resolve(res.tempFilePath);
  142. },
  143. fail(err) {
  144. console.log(err);
  145. reject();
  146. }
  147. });
  148. });
  149. },
  150. draw(context, reserve = false) {
  151. return new Promise((resolve) => {
  152. context.draw(reserve, () => {
  153. resolve();
  154. });
  155. });
  156. }
  157. },
  158. created() {
  159. this.$nextTick(() => {
  160. this.buildItem();
  161. });
  162. }
  163. };
  164. </script>
  165. <style>
  166. .omit {
  167. font-size: 48rpx;
  168. margin-right: 30rpx;
  169. }
  170. .card-code {
  171. margin-top: 15rpx;
  172. display: flex;
  173. justify-content: flex-end;
  174. color: #FFFFFF;
  175. font-size: 38rpx;
  176. }
  177. .flex-1 {
  178. flex: 1;
  179. }
  180. .card-type {
  181. font-size: 24rpx;
  182. color: #F1F1F1;
  183. }
  184. .bank-name {
  185. font-size: 32rpx;
  186. color: #FFFFFF;
  187. }
  188. .bank-info {
  189. display: flex;
  190. flex-direction: column;
  191. margin-left: 30rpx;
  192. }
  193. .bank-head {
  194. display: flex;
  195. flex: 1;
  196. align-items: center;
  197. }
  198. .bank-head image {
  199. width: 100rpx;
  200. height: 100rpx;
  201. padding: 15rpx;
  202. background-color: #FFFFFF;
  203. border-radius: 50%;
  204. overflow: hidden;
  205. }
  206. .bank-icon {
  207. position: absolute;
  208. top: 20rpx;
  209. left: 20rpx;
  210. width: 100rpx;
  211. height: 100rpx;
  212. }
  213. .bank-watermark {
  214. position: absolute;
  215. right: -184rpx;
  216. bottom: 0rpx;
  217. width: 144rpx;
  218. height: 90rpx;
  219. background-repeat: no-repeat;
  220. filter: drop-shadow(-204rpx 0rpx 0rpx #fff);
  221. opacity: 0.1;
  222. }
  223. .bank-item {
  224. position: relative;
  225. flex: 1;
  226. padding: 14px 20px;
  227. margin-bottom: 12px;
  228. }
  229. .bank-item:after {
  230. content: "";
  231. display: block;
  232. background: inherit;
  233. filter: blur(10rpx);
  234. position: absolute;
  235. width: 100%;
  236. height: 100%;
  237. top: 10rpx;
  238. left: 10rpx;
  239. z-index: -1;
  240. opacity: 0.4;
  241. transform-origin: 0 0;
  242. border-radius: inherit;
  243. transform: scale(1, 1);
  244. }
  245. </style>