six.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <template>
  2. <div>
  3. <van-swipe
  4. ref="swipe"
  5. :touchable="false"
  6. :show-indicators="false"
  7. vertical
  8. indicator-color="white"
  9. >
  10. <van-swipe-item>
  11. <div style="width: 100%; overflow: hidden; position: relative">
  12. <transition name="fade">
  13. <div class="next" v-if="step === 5">
  14. <img
  15. @click="nextPage"
  16. src="../../../assets/img/next.png"
  17. style="width: 2em; display: block; margin: 0 auto"
  18. />
  19. <p style="font-size: 12px; text-align: center">
  20. 获取你的新年好物
  21. </p>
  22. </div>
  23. </transition>
  24. <div class="six" :style="'background-image: url(' + bgimg + ')'">
  25. <img
  26. :src="kuangimg"
  27. :style="
  28. step === 2
  29. ? 'opacity: 1'
  30. : step >= 3
  31. ? 'width: 25%;transform: translate(0, 0);opacity: 1; top: 1em; left: 1em'
  32. : 'opacity: 0'
  33. "
  34. class="firstImg"
  35. />
  36. <transition name="fade">
  37. <div
  38. class="sImg img"
  39. v-if="step === 1"
  40. :style="'width:' + width + 'px;'"
  41. >
  42. <template v-for="(item, i) in text.texts" :key="i">
  43. <p
  44. v-text="item"
  45. :style="
  46. stepBody >= i
  47. ? 'opacity: 1;color: ' + text.color
  48. : 'color: ' + text.color
  49. "
  50. ></p>
  51. <br />
  52. </template>
  53. </div>
  54. </transition>
  55. <transition name="fade">
  56. <div class="body" @click="changeNextStep" v-if="nextStep === 1">
  57. <div class="loading">
  58. <div class="loading1">
  59. <div class="loading2"></div>
  60. </div>
  61. </div>
  62. </div>
  63. </transition>
  64. <img
  65. :src="text2img"
  66. :style="step >= 4 ? 'opacity: 1' : ''"
  67. class="tImg"
  68. />
  69. <transition name="fade">
  70. <div class="btns" v-if="step === 5">
  71. <div
  72. class="btn"
  73. @click="() => showDown(1)"
  74. style="margin-left: 0"
  75. :stype="'border-color:' + text.color + ';color:' + text.color"
  76. >
  77. 下载壁纸
  78. </div>
  79. <div
  80. class="btn"
  81. @click="() => showDown(2)"
  82. :stype="'border-color:' + text.color + ';color:' + text.color"
  83. >
  84. 生成海报
  85. </div>
  86. </div>
  87. </transition>
  88. </div>
  89. </div>
  90. </van-swipe-item>
  91. <!-- <van-swipe-item style="overflow: auto">
  92. <div
  93. v-if="showSheet == 1"
  94. style="
  95. width: 100%;
  96. height: 100%;
  97. overflow: hidden;
  98. position: relative;
  99. "
  100. >
  101. <img
  102. @click="nextPage"
  103. src="../../../assets/img/next.png"
  104. class="next"
  105. />
  106. <seven />
  107. </div>
  108. </van-swipe-item> -->
  109. <van-swipe-item style="overflow: auto; height: 100vh">
  110. <eight
  111. ref="eightRef"
  112. @showTitleFunc="showTitleFunc"
  113. @showVideo="showVideo"
  114. />
  115. </van-swipe-item>
  116. </van-swipe>
  117. <transition name="fade">
  118. <div class="model" v-if="showImg !== undefined">
  119. <div class="gs">
  120. <img :src="bgimg" style="width: 100%; height: 100%" alt="" />
  121. </div>
  122. <van-icon
  123. color="#fff"
  124. size="26"
  125. name="close"
  126. class="close"
  127. @click="close"
  128. />
  129. <div class="modelImg">
  130. <p>请长按保存图片</p>
  131. <img :src="showImg" style="width: 100%; height: 100%" />
  132. </div>
  133. </div>
  134. </transition>
  135. <transition name="fade">
  136. <div v-if="showOverlay" class="model">
  137. <van-icon
  138. color="#fff"
  139. size="26"
  140. name="close"
  141. class="close"
  142. @click="closeSeven"
  143. />
  144. <video class="sevenvideo" src=""></video>
  145. </div>
  146. </transition>
  147. <van-dialog
  148. v-model:show="showTitle"
  149. title="登录后即可参与抽奖~"
  150. show-cancel-button
  151. :before-close="closeTitle"
  152. >
  153. <van-field
  154. required
  155. v-model="from.phone"
  156. label="联系方式"
  157. type="tel"
  158. placeholder="请输入手机号"
  159. >
  160. <template #button>
  161. <van-button
  162. v-if="isCode === 0"
  163. @click="getCode"
  164. size="small"
  165. type="primary"
  166. >获取验证码</van-button
  167. >
  168. <van-count-down
  169. v-if="isCode !== 0"
  170. @finish="isCode = 0"
  171. :time="isCode"
  172. format="ss 秒"
  173. />
  174. </template>
  175. </van-field>
  176. <van-field
  177. required
  178. v-model="from.code"
  179. label="验证码"
  180. type="tel"
  181. placeholder="请输入验证码"
  182. />
  183. </van-dialog>
  184. </div>
  185. </template>
  186. <script setup>
  187. import { ref, reactive, nextTick, defineEmits } from "vue";
  188. import {
  189. getStore,
  190. getSendVerifyCode,
  191. getInfo,
  192. getDrawPlus,
  193. } from "@/api/SilkRoadSpringGala.js";
  194. import data from "../data/data.json";
  195. import { showToast } from "vant";
  196. // import seven from "./seven.vue";
  197. import eight from "./eight.vue";
  198. const from = reactive({
  199. name: "",
  200. phone: localStorage.getItem("silkRoadPhone"),
  201. code: "",
  202. });
  203. // import { onMounted, reactive } from "vue";
  204. // import { isIpad, isIpod, isIphone } from "../../utils/isTerminal";
  205. /**
  206. * window.$originData.orginParames.title 页面标题
  207. * window.$originData.orginParames.parameters 固定参数值
  208. * window.$originData.urlParames url参数
  209. */
  210. const showImg = ref(undefined);
  211. const swipe = ref(null);
  212. let width = window.$originData.orginParames.availWidth * 0.7;
  213. const type = Math.floor(Math.random() * 12 + 1);
  214. let ori = data[type - 1] || {
  215. texts: [],
  216. };
  217. let max = 0;
  218. const showTitle = ref(false);
  219. for (let i = 0; i < ori.texts.length; i++) {
  220. max < ori.texts[i].length && (max = ori.texts[i].length);
  221. }
  222. width = 14 * max;
  223. const url = {
  224. bg: require("@/assets/img/12/" + type + "-1.png"),
  225. bg2: require("@/assets/img/12/" + type + "-2.png"),
  226. kuang: require("@/assets/img/12/" + type + ".kuang.png"),
  227. text2: require("@/assets/img/12/" + type + ".text2.png"),
  228. };
  229. const text = reactive({
  230. ...data[type - 1],
  231. width,
  232. });
  233. const emits = defineEmits(["autoAudio"]);
  234. const isCode = ref(0); // 验证码
  235. const bgimg = ref(url.bg);
  236. const kuangimg = ref(url.kuang);
  237. const text2img = ref(url.text2);
  238. const step = ref(0); // 动画步骤 默认0
  239. const stepBody = ref(0); // 首页文字显示动画 默认0
  240. const nextStep = ref(0);
  241. const eightRef = ref(null);
  242. // 如果有手机号获取用户信息
  243. if (from.phone) {
  244. getInfo({
  245. phone: from.phone,
  246. }).then(r => {
  247. r.addr && localStorage.setItem("silkRoadAddress", r.addr);
  248. r.userName && localStorage.setItem("silkRoadName", r.userName);
  249. });
  250. }
  251. let t = setTimeout(() => {
  252. clearTimeout(t);
  253. step.value += 1;
  254. t = setInterval(() => {
  255. stepBody.value += 1;
  256. if (stepBody.value === text.texts.length) {
  257. nextStep.value = 1;
  258. clearInterval(t);
  259. t = setInterval(() => {
  260. nextStep.value === 2 && (step.value += 1);
  261. if (step.value === 5) clearInterval(t);
  262. }, 1000);
  263. }
  264. }, 1000);
  265. }, 200);
  266. function nextPage() {
  267. if (step.value !== 5) return;
  268. swipe.value.next();
  269. }
  270. function changeNextStep() {
  271. nextStep.value += 1;
  272. }
  273. function showTitleFunc() {
  274. showTitle.value = true;
  275. from.name = "";
  276. from.phone = "";
  277. from.code = "";
  278. }
  279. function getCode() {
  280. // 获取验证码
  281. if (!/1[0-9]{10}/.test(from.phone)) {
  282. showToast("请输入正确的手机号");
  283. return;
  284. }
  285. getSendVerifyCode({
  286. phone: from.phone,
  287. }).then(() => {
  288. isCode.value = 60000;
  289. });
  290. }
  291. function closeTitle(type) {
  292. if (type !== "confirm") return true;
  293. const v = !from.code || !from.phone;
  294. if (v) {
  295. showToast("请输入完整信息。");
  296. return false;
  297. }
  298. getStore({
  299. phone: from.phone,
  300. verifyCode: from.code,
  301. }).then(r => {
  302. localStorage.setItem("silkRoadPhone", from.phone);
  303. localStorage.setItem("silkRoadCode", from.code);
  304. localStorage.setItem("silkRoadName", from.name);
  305. localStorage.setItem("silkRoadToken", r.token);
  306. isCode.value = 0;
  307. showTitle.value = false;
  308. console.log(showTitle.value);
  309. // 调用子组件抽奖
  310. eightRef.value.draw();
  311. });
  312. return true;
  313. }
  314. function showDown(type) {
  315. switch (type) {
  316. case 1:
  317. showImg.value = url.bg;
  318. break;
  319. case 2:
  320. showImg.value = url.bg2;
  321. break;
  322. }
  323. }
  324. function close() {
  325. showImg.value = undefined;
  326. }
  327. // 视频播放
  328. const showOverlay = ref(false);
  329. let time = -1;
  330. let autoTime = 0;
  331. let current = 0;
  332. function showVideo(url) {
  333. showOverlay.value = true;
  334. emits("autoAudio");
  335. nextTick(() => {
  336. let ele = document.querySelector(".sevenvideo");
  337. ele.src = url;
  338. ele.currentTime = 0;
  339. current = 0;
  340. time = -1;
  341. // 已经开始
  342. ele.addEventListener("playing", function () {
  343. time = Date.now();
  344. current = ele.duration * 1000;
  345. });
  346. // 当媒介能够开始播放但可能因缓冲而需要停止时运行脚本
  347. ele.addEventListener("canplay", endVideo, false);
  348. //播放结束
  349. ele.addEventListener(
  350. "ended",
  351. function () {
  352. console.log("ended");
  353. endVideo();
  354. closeSeven();
  355. },
  356. false
  357. );
  358. //暂停
  359. ele.addEventListener("pause", endVideo, false);
  360. ele.play();
  361. });
  362. }
  363. function closeSeven() {
  364. autoTime = Date.now() - time;
  365. if (autoTime / current <= 0.95)
  366. showToast({
  367. message: "温馨提醒:中途退出无法获取抽奖机会哦~",
  368. duration: 3000,
  369. });
  370. let ele = document.querySelector(".sevenvideo");
  371. ele.pause();
  372. emits("autoAudio");
  373. showOverlay.value = false;
  374. }
  375. function endVideo() {
  376. if (time == -1) return;
  377. const phone = localStorage.getItem("silkRoadPhone");
  378. autoTime = Date.now() - time;
  379. if (autoTime / current <= 0.95 || !phone) return;
  380. getDrawPlus({
  381. phone,
  382. }).then(() => {
  383. showToast("已增加一次抽奖机会!");
  384. });
  385. }
  386. </script>
  387. <style lang="scss" scoped>
  388. .six {
  389. width: 100%;
  390. height: 100vh;
  391. background-size: 100% 100%;
  392. position: relative;
  393. .body {
  394. position: absolute;
  395. bottom: 10vh;
  396. width: 100vw;
  397. }
  398. img,
  399. .img {
  400. width: 50%;
  401. transition-property: all;
  402. transition-duration: 2s;
  403. opacity: 0;
  404. position: absolute;
  405. top: 50%;
  406. left: 50%;
  407. transform: translate(-50%, -50%);
  408. }
  409. .firstImg {
  410. transition-delay: 1s;
  411. -moz-transition-delay: 1s;
  412. /* Firefox 4 */
  413. -webkit-transition-delay: 1s;
  414. /* Safari 和 Chrome */
  415. -o-transition-delay: 1s;
  416. /* Opera */
  417. }
  418. .sImg {
  419. width: 70%;
  420. color: #ffffff;
  421. font-family: OPPOSans;
  422. font-size: 14px;
  423. line-height: 3em;
  424. opacity: 1;
  425. p {
  426. display: inline-block;
  427. white-space: nowrap;
  428. transition-property: all;
  429. transition-duration: 0.5s;
  430. opacity: 0;
  431. }
  432. }
  433. .tImg {
  434. width: 80%;
  435. transition-delay: 1s;
  436. -moz-transition-delay: 1s;
  437. /* Firefox 4 */
  438. -webkit-transition-delay: 1s;
  439. /* Safari 和 Chrome */
  440. -o-transition-delay: 1s;
  441. /* Opera */
  442. }
  443. .btns {
  444. position: absolute;
  445. text-align: center;
  446. bottom: 10vh;
  447. width: 100%;
  448. > div {
  449. display: inline-block;
  450. border: 1px solid #fff;
  451. border-radius: 2em;
  452. font-weight: 600;
  453. color: #fff;
  454. padding: 5px 15px;
  455. margin-left: 2em;
  456. }
  457. }
  458. .fade-enter-from,
  459. .fade-leave-to {
  460. opacity: 0;
  461. }
  462. .fade-enter-active,
  463. .fade-leave-active {
  464. transition: opacity 1s ease;
  465. }
  466. .fade-enter-to,
  467. .fade-leave-from {
  468. opacity: 1;
  469. }
  470. }
  471. .next {
  472. bottom: 40px;
  473. left: 50%;
  474. transform: translateX(-50%);
  475. top: inherit;
  476. width: 8em;
  477. color: #fff;
  478. z-index: 1;
  479. position: absolute;
  480. animation-name: an;
  481. animation-duration: 1s;
  482. animation-timing-function: linear;
  483. animation-iteration-count: infinite;
  484. animation-direction: alternate;
  485. }
  486. @keyframes an {
  487. from {
  488. bottom: 10px;
  489. }
  490. to {
  491. bottom: 15px;
  492. }
  493. }
  494. .model {
  495. position: fixed;
  496. top: 0;
  497. left: 0;
  498. bottom: 0;
  499. right: 0;
  500. z-index: 10;
  501. background-color: #000000;
  502. .gs {
  503. width: 100vw;
  504. height: 100vh;
  505. filter: blur(10px);
  506. -webkit-filter: blur(10px);
  507. }
  508. .modelImg {
  509. position: absolute;
  510. top: 50%;
  511. left: 50%;
  512. transform: translate(-50%, -50%);
  513. width: 80%;
  514. text-align: center;
  515. color: #ffffff;
  516. }
  517. .close {
  518. position: absolute;
  519. top: 1em;
  520. right: 1em;
  521. }
  522. .sevenvideo {
  523. top: 50%;
  524. transform: translateY(-50%);
  525. width: 100%;
  526. position: absolute;
  527. }
  528. }
  529. </style>