electAnimation.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <template>
  2. <view>
  3. <view class="elect-parent">
  4. <view class="elect-container" :class="[elect._start?' playMove ':'',elect._running?'movePaused':' movePlay ']"
  5. :style="{'animation-duration': elect.allSecond+'s'}">
  6. <view class="elect" :id="elect._id" :style="{
  7. borderColor: borderColor,
  8. color: color,
  9. '--time':elect._remainingTime,
  10. backgroundImage:`url(${imageSrc})`}"
  11. :class=" elect._running?' play ':''">
  12. </view>
  13. </view>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. // 创建对象
  19. function createElectObj(props) {
  20. return new ElectObj(props || {})
  21. }
  22. function ElectObj(props) {
  23. this.animationData = props.animationData || null;
  24. this.allDuration = props.allDuration || 1000;
  25. this.allSecond = props.allDuration / 1000;
  26. console.log("this.allSecond=", this.allSecond);
  27. // 页面对象
  28. this._id = props.id || 0;
  29. // return;
  30. //是否运行心电图
  31. this._running = false;
  32. this._left = 0;
  33. this._startLeft = 0;
  34. this._start = false;
  35. this._play = false;
  36. // 是否在进行播放
  37. this._bPlaying = false;
  38. // 移动的距离
  39. this._Distance = 350;
  40. //心电图走的时间
  41. this._remainingTime = 0;
  42. this.moveTime = 0;
  43. //计算器
  44. this._interval = null;
  45. // 心电图走的速度,
  46. this._speed = this._Distance / props.allDuration;
  47. //实列对象的参数
  48. this.animation = uni.createAnimation();
  49. //实列音频对象
  50. this.hitUrl = "../../../static/elect/hit.mp3";
  51. this.hitTenUrl = "../../../static/elect/hit-ten.mp3";
  52. this.createUrl = "../../../static/elect/create.mp3";
  53. this.missUrl = "../../../static/elect/miss.mp3";
  54. this.playAudioContext = uni.createInnerAudioContext();
  55. this.playAudioContext.autoplay = false;
  56. this.playAudioContext.src = this.hitUrl;
  57. this.playAudioContext.volume = 1;
  58. // this.missAudioContext = uni.createInnerAudioContext();
  59. // this.missAudioContext.autoplay = false;
  60. // this.missAudioContext.src = "../../../static/elect/miss.mp3";
  61. // this.missAudioContext.volume = 1;
  62. this.playCount = 0;
  63. }
  64. ElectObj.prototype = {
  65. setVolume: function(volume) {
  66. // this.missAudioContext.volume = volume;
  67. this.playAudioContext.volume = volume;
  68. },
  69. setDuration: function(_allduration) {
  70. this.allDuration = _allduration;
  71. this.allSecond = _allduration / 1000;
  72. this._speed = this._Distance / _allduration;
  73. },
  74. //结束时候重置对应状态
  75. electEnd: function() {
  76. console.log("心电图结束");
  77. this.playCount = 0;
  78. this.playAudioContext.stop();
  79. // this.missAudioContext.stop();
  80. this.setVolume(0);
  81. },
  82. //播放序列帧动画
  83. play: function(_self, _parentLeft) {
  84. // console.log('play');
  85. if (this._play) return;
  86. // 用执行时间来判断
  87. if (this.moveTime < this.allDuration * 0.1) return;
  88. this._play = true;
  89. _self.$emit('onElectPlay');
  90. if (this.playCount < 5) {
  91. this.playAudioContext.src = this.hitUrl;
  92. this.playAudioContext.stop();
  93. this.playAudioContext.play();
  94. this.playCount++;
  95. } else {
  96. this.playAudioContext.src = this.hitTenUrl;
  97. this.playAudioContext.stop();
  98. this.playAudioContext.play();
  99. this.playCount = 0;
  100. // console.log("播放特殊音效");
  101. }
  102. // 计算点击后剩余的时间
  103. this._remainingTime = (this.allDuration - this.moveTime) / 1000;
  104. this._running = true;
  105. },
  106. // 移动动画
  107. move: function(callback) {
  108. if (this._bPlaying) return;
  109. this._bPlaying = true;
  110. this.playAudioContext.src = this.createUrl;
  111. this.playAudioContext.stop();
  112. this.playAudioContext.play();
  113. // 移动前初始化一部分默认参数
  114. this._play = false;
  115. this._start = true;
  116. // console.log("this.allDuration==", this.allDuration);
  117. let timeUnit = 300;
  118. this._interval = setInterval(() => {
  119. this.moveTime += timeUnit;
  120. if (this.moveTime >= this.allDuration) {
  121. this._running = false;
  122. this._start = false;
  123. // 完成后,初始化到位置最初状态
  124. clearInterval(this._interval);
  125. this._interval = null;
  126. this.moveTime = 0;
  127. setTimeout(() => {
  128. if (callback)
  129. callback();
  130. }, 100)
  131. }
  132. }, timeUnit);
  133. }
  134. }
  135. import imageSrc from "@/static/elect/elect.png"
  136. export default {
  137. props: {
  138. parentLeft: {
  139. type: Number,
  140. default: 0
  141. },
  142. electLeft: {
  143. type: Number,
  144. default: 150
  145. },
  146. backgroundColor: {
  147. type: String,
  148. default: '#007AFF'
  149. },
  150. borderColor: {
  151. type: String,
  152. default: '#000000'
  153. },
  154. color: {
  155. type: String,
  156. default: '#000000'
  157. },
  158. duration: {
  159. type: Number,
  160. default: 3000
  161. }
  162. },
  163. data() {
  164. return {
  165. // 心电图实列数组
  166. elects: [],
  167. elect: null,
  168. bRun: false,
  169. bInitMissAudio: false,
  170. bPlayMissAudio: false,
  171. imageSrc: imageSrc
  172. };
  173. },
  174. created() {
  175. // 动画要最开始实例化
  176. this.animation = uni.createAnimation();
  177. // let initElects = [];
  178. // for (var i = 0; i < 1; i++) {
  179. // var temp = createElectObj({
  180. // id: 'elect' + i,
  181. // allDuration: this.duration,
  182. // });
  183. // initElects.push(temp);
  184. // }
  185. // this.elects = initElects; //Object.assign({},this.elects,initElects);
  186. this.elect = createElectObj({
  187. id: 'elect0',
  188. allDuration: this.duration,
  189. });
  190. // setTimeout(() => {
  191. // this.playElect();
  192. // }, 100)
  193. },
  194. methods: {
  195. /**
  196. * 调用移动心电图整体的动画
  197. */
  198. moveElect() {
  199. // 从数组一个数据做操作,开始循环
  200. if (!this.bRun) return;
  201. console.log(this.bRun);
  202. this.elect.move(() => {
  203. if (!this.elect._play) {
  204. // this.elect.missAudioContext.play();
  205. this.elect.playAudioContext.src = this.elect.missUrl;
  206. this.elect.playAudioContext.stop();
  207. this.elect.playAudioContext.play();
  208. // console.log(11);
  209. // if (!this.bInitMissAudio) {
  210. // this.elect.playAudioContext.onEnded(() => {
  211. // //最后一个音效播放完后,在继续下一个线段出来
  212. // this.elect._bPlaying = false;
  213. // this.moveElect();
  214. // });
  215. // this.bInitMissAudio = true;
  216. // }
  217. setTimeout(() => {
  218. //最后一个音效播放完后,在继续下一个线段出来
  219. this.elect._bPlaying = false;
  220. this.moveElect();
  221. }, 500);
  222. this.$emit('onElectMiss')
  223. } else {
  224. this.elect._bPlaying = false;
  225. // this.elect.playAudioContext.offEnded();
  226. this.moveElect();
  227. }
  228. });
  229. },
  230. /**
  231. * 播放心电图序列帧动画
  232. */
  233. jumpElect() {
  234. // console.log(11);
  235. this.elect.play(this, this.parentLeft);
  236. },
  237. /**
  238. * 暂停播放心电图
  239. */
  240. pausedElect(bEnd) {
  241. this.bRun = false;
  242. //声音要暂停
  243. if (bEnd) {
  244. this.elect.electEnd();
  245. }
  246. },
  247. /**
  248. * 开始播放
  249. */
  250. playElect() {
  251. this.bRun = true;
  252. this.moveElect();
  253. },
  254. /**
  255. * 修改时间
  256. * @param {Object} changeDuration
  257. */
  258. changeDuration(changeDuration) {
  259. this.elect.setDuration(changeDuration);
  260. },
  261. /**
  262. * 禁音
  263. */
  264. setVolume(volume) {
  265. this.elect.setVolume(volume);
  266. }
  267. }
  268. }
  269. </script>
  270. <style lang="scss">
  271. .elect-parent {
  272. // border: 1rpx solid #ffaa7f;
  273. position: relative;
  274. display: flex;
  275. justify-content: center;
  276. overflow: hidden;
  277. }
  278. .elect-container {
  279. width: 100%;
  280. height: 68px;
  281. // border: 1rpx solid #000000;
  282. position: relative;
  283. }
  284. .elect {
  285. // background-color: #007AFF;
  286. background-size: cover;
  287. height: 68px;
  288. width: 337px;
  289. position: relative;
  290. top: 0;
  291. left: -156px;
  292. }
  293. .playMove {
  294. // animation: move linear calc(var(--mTime) / 1000 * 1s) both;
  295. animation-name: move;
  296. animation-timing-function: linear;
  297. animation-fill-mode: both;
  298. }
  299. .movePlay {
  300. animation-play-state: running;
  301. }
  302. .movePaused {
  303. animation-play-state: paused;
  304. }
  305. .play {
  306. animation: run calc(var(--time) * 1s) steps(1, start) both;
  307. animation-play-state: running;
  308. }
  309. @keyframes move {
  310. 0% {
  311. transform: translateX(0);
  312. }
  313. 100% {
  314. transform: translateX(350px);
  315. }
  316. }
  317. @keyframes run {
  318. @for $i from 0 through 49 {
  319. #{$i*2}% {
  320. background-position: -0px -68px*$i;
  321. }
  322. }
  323. 100% {
  324. background-position: -0px -3400px;
  325. }
  326. }
  327. </style>