CommonDrawList.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. <template>
  2. <div class="common-draw-list-view">
  3. <!-- <div
  4. v-if="route.query.idx === '5'"
  5. class="no-content"
  6. >
  7. <img
  8. class="no-content"
  9. src="@/assets/images/please-wait.png"
  10. alt=""
  11. draggable="false"
  12. >
  13. </div> -->
  14. <ul
  15. ref="drawUlEl"
  16. class="common-draw-list"
  17. @wheel="onDrawUlWheel"
  18. >
  19. <li
  20. v-for="(drawName, idx) in drawList"
  21. :key="idx"
  22. >
  23. <img
  24. class=""
  25. :data-original="`${imgPrefixHigh}/${drawName}`"
  26. :src="`${imgPrefix}/${drawName}`"
  27. alt=""
  28. draggable="false"
  29. @click="onClickImg"
  30. >
  31. </li>
  32. </ul>
  33. <ul
  34. ref="groupUlEl"
  35. class="group-list"
  36. @wheel="onGroupUlWheel"
  37. >
  38. <li
  39. v-for="(groupName, idx) in Object.keys(groupList)"
  40. :key="idx"
  41. :class="{
  42. active: activeGroupIdx === idx
  43. }"
  44. @click="activeGroupIdx = idx"
  45. >
  46. {{ groupName }}
  47. </li>
  48. </ul>
  49. <!-- <button
  50. v-if="route.query.idx === '3'"
  51. class="game-entry"
  52. @click="router.push({
  53. name: 'StartView',
  54. })"
  55. /> -->
  56. <button
  57. class="like"
  58. :class="{
  59. liked: hasLiked,
  60. }"
  61. @click="onClickLike"
  62. >
  63. <img
  64. v-show="!hasLiked"
  65. class=""
  66. src="@/assets/images/like.png"
  67. alt=""
  68. draggable="false"
  69. >
  70. <img
  71. v-show="hasLiked"
  72. class=""
  73. src="@/assets/images/liked.png"
  74. alt=""
  75. draggable="false"
  76. >
  77. <span class="txt">{{ likeCount }}</span>
  78. </button>
  79. <button
  80. class="return"
  81. @click="router.push({
  82. name: 'EntryList',
  83. })"
  84. />
  85. <div
  86. v-show="isViewingBigImage"
  87. class="show-on-mask"
  88. >
  89. <button
  90. class="return"
  91. @click="closeViewer"
  92. />
  93. </div>
  94. </div>
  95. </template>
  96. <script setup>
  97. import { ref, computed, onMounted, } from "vue"
  98. import { useRoute, useRouter } from "vue-router"
  99. import { likeRecord } from "@/store/index.js"
  100. import { drawTree } from "@/assets/draw-tree.js"
  101. import Viewer from 'viewerjs'
  102. const {
  103. windowSizeInCssForRef,
  104. windowSizeWhenDesignForRef,
  105. } = useSizeAdapt(724, 375)
  106. const route = useRoute()
  107. const router = useRouter()
  108. const activeGroupIdx = ref(0)
  109. const groupL1Name = Object.keys(drawTree)[Number(route.query.idx) - 1]
  110. const groupList = Object.values(drawTree)[Number(route.query.idx) - 1]
  111. console.log(groupL1Name, groupList, 'groupList')
  112. const groupName = computed(() => {
  113. return Object.keys(groupList)[activeGroupIdx.value]
  114. })
  115. const drawList = computed(() => {
  116. return Object.keys(groupList[Object.keys(groupList)[activeGroupIdx.value]])
  117. })
  118. const imgPrefix = computed(() => {
  119. return `${process.env.VUE_APP_OUTER_ASSETS_PREFIX}draws/${encodeURIComponent(groupL1Name)}/${encodeURIComponent(groupName.value)}`
  120. })
  121. const imgPrefixHigh = computed(() => {
  122. return `${process.env.VUE_APP_OUTER_ASSETS_PREFIX}drawsHigh/${encodeURIComponent(groupL1Name)}/${encodeURIComponent(groupName.value)}`
  123. })
  124. const isViewingBigImage = ref(false)
  125. let viewer = null
  126. function onClickImg(e) {
  127. // console.log(e.target)
  128. viewer = new Viewer(e.target, {
  129. url: 'data-original',
  130. backdrop: 'static', // 点击空白区域不会关闭
  131. button: true,
  132. fullscreen: true,
  133. inline: false,
  134. keyboard: true,
  135. movable: true,
  136. navbar: false,
  137. rotatable: false,
  138. title: false,
  139. toolbar: false,
  140. tooltip: false,
  141. transition: true,
  142. zoomable: true,
  143. shown() {
  144. isViewingBigImage.value = true
  145. },
  146. hide() {
  147. isViewingBigImage.value = false
  148. },
  149. hidden() {
  150. viewer.destroy()
  151. viewer = null
  152. }
  153. })
  154. viewer.show()
  155. }
  156. function closeViewer() {
  157. viewer.hide()
  158. }
  159. api.reportVisit(Number(route.query.idx)).then((res) => {
  160. console.log('sdfsdf', res)
  161. })
  162. // // 显示单元点赞
  163. // const likeCount = ref(null)
  164. // api.getLikeCount(route.query.idx).then((res) => {
  165. // likeCount.value = res
  166. // })
  167. const likeCount = ref()
  168. onMounted(() => {
  169. getLikeCount()
  170. })
  171. const getLikeCount = () => {
  172. // 总点赞量
  173. likeCount.value = 0
  174. api.getAllLikeCount().then((res) => {
  175. likeCount.value += res
  176. })
  177. }
  178. const hasLiked = computed(() => {
  179. return likeRecord.value[route.query.idx - 1]
  180. })
  181. function onClickLike(e) {
  182. if (hasLiked.value) {
  183. return
  184. }
  185. likeRecord.value[route.query.idx - 1] = true
  186. api.like(route.query.idx)
  187. likeCount.value++ // 从接口拿到的数据不会立刻变化
  188. setTimeout(() => {
  189. utils.animateCSS(e.target, 'heartBeat')
  190. }, 100)
  191. }
  192. const drawUlEl = ref(null)
  193. function onDrawUlWheel(e) {
  194. drawUlEl.value.scrollLeft -= e.wheelDelta
  195. }
  196. const groupUlEl = ref(null)
  197. function onGroupUlWheel(e) {
  198. groupUlEl.value.scrollLeft -= e.wheelDelta
  199. }
  200. </script>
  201. <style>
  202. .viewer-button{
  203. width: 0 !important;
  204. height: 0 !important;
  205. }
  206. </style>
  207. <style lang="less" scoped>
  208. .common-draw-list-view{
  209. position: relative;
  210. height: 100%;
  211. padding-top: calc(28 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  212. padding-bottom: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  213. display: flex;
  214. flex-direction: column;
  215. justify-content: space-between;
  216. align-items: center;
  217. background-image: url(@/assets/images/foreword-bg.jpg);
  218. background-size: cover;
  219. background-repeat: no-repeat;
  220. background-position: center center;
  221. >div.no-content{
  222. position: absolute;
  223. left: 0;
  224. top: 0;
  225. width: 100%;
  226. height: 100%;
  227. display: flex;
  228. justify-content: center;
  229. align-items: center;
  230. >img.no-content{
  231. height: calc(242 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  232. }
  233. }
  234. >ul.common-draw-list{
  235. width: 100%;
  236. padding-left: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  237. padding-right: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  238. padding-bottom: calc(5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  239. display: flex;
  240. align-items: center;
  241. overflow: auto;
  242. &::-webkit-scrollbar { height: 0; };
  243. >li{
  244. flex: 0 0 auto;
  245. width: calc(272 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  246. height: calc(272 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  247. margin-right: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  248. background-size: cover;
  249. background-repeat: no-repeat;
  250. background-position: center center;
  251. border-radius: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  252. border: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) solid #FFFFFF;
  253. box-shadow: 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0px rgba(0,0,0,0.1);
  254. >img{
  255. width: 100%;
  256. height: 100%;
  257. object-fit: cover;
  258. }
  259. }
  260. }
  261. >button.game-entry{
  262. position: absolute;
  263. bottom: 0;
  264. right: calc(160 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  265. width: calc(194 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  266. height: calc(86 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  267. background-image: url(@/assets/images/game-entry.png);
  268. background-size: cover;
  269. background-repeat: no-repeat;
  270. background-position: center center;
  271. }
  272. >button.like{
  273. position: absolute;
  274. bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  275. right: calc(70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  276. background: #FFD73C;
  277. box-shadow: 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0px rgba(0,0,0,0.25);
  278. border-radius: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  279. opacity: 1;
  280. border: calc(2 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) solid #FFFFFF;
  281. width: calc(88 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  282. height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  283. padding-left: calc(5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  284. padding-right: calc(5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  285. display: flex;
  286. justify-content: space-evenly;
  287. align-items: center;
  288. box-shadow: 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0px rgba(0,0,0,0.25);
  289. >img{
  290. width: calc(26 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  291. height: calc(26 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  292. }
  293. >.txt{
  294. font-size: calc(14 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  295. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  296. font-weight: 400;
  297. color: #FFFFFF;
  298. line-height: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  299. }
  300. }
  301. >button.like.liked{
  302. background: #fbf0d8;
  303. >.txt{
  304. color: rgba(215, 173, 13, 1);
  305. }
  306. }
  307. >button.return{
  308. position: absolute;
  309. bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  310. right: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  311. width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  312. height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  313. background-image: url(@/assets/images/icon_back@2x.png);
  314. background-size: contain;
  315. background-repeat: no-repeat;
  316. background-position: center center;
  317. box-shadow: 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0px rgba(0,0,0,0.25);
  318. border-radius: 50%;
  319. }
  320. >ul.group-list{
  321. padding-left: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  322. margin-right: calc(170 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  323. padding-bottom: calc(5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  324. display: flex;
  325. align-items: center;
  326. overflow: auto;
  327. &::-webkit-scrollbar { background: #fbf0d8; width: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')); height: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')); } /*宽度是对垂直滚动条而言,高度是对水平滚动条而言*/
  328. &::-webkit-scrollbar-thumb { background: rgba(215, 173, 13, 1); border-radius: calc(2 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')); }
  329. >li{
  330. flex: 0 0 auto;
  331. display: flex;
  332. height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  333. justify-content: center;
  334. align-items: center;
  335. margin-right: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  336. font-size: 16px;
  337. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  338. font-weight: 400;
  339. color: #484238;
  340. line-height: 19px;
  341. padding-right: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  342. padding-left: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  343. background-color: #fff;
  344. border-radius: calc(5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  345. cursor: pointer;
  346. }
  347. >li.active{
  348. background-color: rgba(239, 196, 27, 1);
  349. font-weight: bold;
  350. color: #FFFFFF;
  351. border: calc(3 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) solid #FFFFFF;
  352. box-shadow: 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0px rgba(0,0,0,0.25);
  353. }
  354. }
  355. >.show-on-mask{
  356. position: absolute;
  357. z-index: 2106;
  358. right: 0;
  359. bottom: 0;
  360. width: calc(90 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  361. display: flex;
  362. flex-direction: column;
  363. align-items: center;
  364. >button.return {
  365. width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  366. height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  367. background-image: url(@/assets/images/icon_back@2x.png);
  368. background-size: contain;
  369. background-repeat: no-repeat;
  370. background-position: center center;
  371. margin-bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  372. }
  373. }
  374. }
  375. </style>