index.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534
  1. <template>
  2. <div class="map-box">
  3. <div class="jiluBigBox" id='poster'>
  4. <div class="m-map">
  5. <!-- <div class="zhezhaoMap"></div> -->
  6. <div id="js-container" class="map"></div>
  7. </div>
  8. <div class="jiluBox1">
  9. <div class="userPhoto">
  10. <img crossorigin='anonymous' class="allImage" mode='aspectFill' :src="userInfo.user_avatar"></img>
  11. </div>
  12. <div class="uesrName">{{userInfo.username}}</div>
  13. <div class="distance">
  14. {{sportInfo && sportInfo.distance ? Math.round(sportInfo.distance/10)/100:0}}
  15. <span class="km">公里</span>
  16. </div>
  17. <div class="title">荔枝悦动:户外跑</div>
  18. <div class="creatTime">{{sportInfo.date_time}}</div>
  19. <div class="lineColor">
  20. <div class='lowSpeed'>慢</div>
  21. <div class='fastSpeed'>快</div>
  22. </div>
  23. <div class="sportData">
  24. <div class='dataBox'>
  25. <div class='dataNum'>{{sportInfo &&sportInfo.speed?sportInfo.speed:0}}</div>
  26. <div class='dataName'>平均配速</div>
  27. </div>
  28. <div class='dateLine'></div>
  29. <div class='dataBox'>
  30. <div class='dataNum'>{{sportInfo &&sportInfo.duration?Math.round(sportInfo.duration/60):0}}
  31. </div>
  32. <div class='dataName'>总时长(分钟)</div>
  33. </div>
  34. <div class='dateLine'></div>
  35. <div class='dataBox'>
  36. <div class='dataNum'>{{sportInfo &&sportInfo.kcal?sportInfo.kcal:0}}</div>
  37. <div class='dataName'>消耗千卡</div>
  38. </div>
  39. </div>
  40. <div class="boxLine"></div>
  41. <div class="sportData" style='top: 430rpx;'>
  42. <div class='dataBox'>
  43. <div class='dataNum'>{{sportInfo &&sportInfo.steps?sportInfo.steps:0}}</div>
  44. <div class='dataName'>总步数</div>
  45. </div>
  46. <div class='dateLine'></div>
  47. <div class='dataBox'>
  48. <div class='dataNum'>{{sportInfo &&sportInfo.cadence?sportInfo.cadence:0}}</div>
  49. <div class='dataName'>步频(步/分钟)</div>
  50. </div>
  51. <div class='dateLine'></div>
  52. <div class='dataBox'>
  53. <div class='dataNum'>{{sportInfo &&sportInfo.stride?sportInfo.stride:0}}</div>
  54. <div class='dataName'>步幅(厘米)</div>
  55. </div>
  56. </div>
  57. </div>
  58. <div class="jiluBox2">
  59. <div class='title'>配速</div>
  60. <div class='kmspeed'>公里 <span style='margin-left: 40rpx;'>配速</span></div>
  61. <div class='allSpeedBox'>
  62. <div class='speedLineBox' v-for="(item,index) in useTimeList" :key="index">
  63. <div class="lineNum">{{index+1}}</div>
  64. <div class="speedColor">
  65. <div class='speedLine' :class="item==minSpeed ? 'speedFast':'speedLow'"
  66. :style="{width:(item/maxSpeed*100)+'%'}"></div>
  67. </div>
  68. <!-- <div class="lineSpeed">{{item>60 ? Math.floor(item/60)+'’'+item%60+'”': item%60+'”' }}</div> -->
  69. <div class="lineSpeed">{{ Math.floor(item)+'’'+Math.floor((item - Math.floor(item))*60.0)+'”'}}</div>
  70. </div>
  71. </div>
  72. </div>
  73. <div class="jiluBox3">
  74. <div class='title'>步频</div>
  75. <div class='bupinDataBox'>
  76. <div class='bupinData'>
  77. <div class='bupinDataNum'>
  78. {{maxCadence}}
  79. </div>
  80. <div class='bupinDataName'>
  81. 最快步频
  82. </div>
  83. </div>
  84. <div class='bupinData'>
  85. <div class='bupinDataNum'>
  86. {{sportInfo &&sportInfo.cadence?sportInfo.cadence:0}}
  87. </div>
  88. <div class='bupinDataName'>
  89. 平均步频
  90. </div>
  91. </div>
  92. </div>
  93. <div class='danwei1'>
  94. (步/分钟)
  95. </div>
  96. <div class='danwei2'>
  97. (分钟)
  98. </div>
  99. <view class="line-chart">
  100. <view>
  101. <view class="mar-bot20">
  102. <canvas class="chart" id="line" canvas-id="line"></canvas>
  103. </view>
  104. </view>
  105. </view>
  106. </div>
  107. </div>
  108. // <div class='savePhoto' @click="toImg">
  109. 保存长图
  110. </div>
  111. <div class='sharePhoto' @click="toShare">
  112. 分享好友
  113. </div>
  114. <div class='shareBox'>
  115. </div>
  116. <div class='fenxiangImageBox' @touchmove.prevent v-if='showPhoto'>
  117. <div class='fenxiangImage'>
  118. <image class="allImage" style="height: 130%;" :src="base64" mode=""></image>
  119. </div>
  120. <div class='closePhoto' @click="closeImg">
  121. 关闭图片
  122. </div>
  123. </div>
  124. </div>
  125. </template>
  126. <script>
  127. import {
  128. pathToBase64,
  129. base64ToPath
  130. } from 'image-tools'
  131. import html2canvas from 'html2canvas';
  132. import {GetUserInfo,GetSportInfo,GetSportSummary,GetMapsInfo,uploadBase64} from '../../api/apis.js';
  133. const MapKey = '43fcce2baefbd309a4afe81279946689';
  134. const MapCityName = '北京';
  135. export default {
  136. props: ['lat', 'lng', 'defaultV'],
  137. data() {
  138. return {
  139. list: [],
  140. address: undefined,
  141. index: 0,
  142. placeSearch: null,
  143. dragStatus: false,
  144. AMapUI: null,
  145. AMap: null,
  146. lineList: [],
  147. centerLog: [118.786545, 32.057882],
  148. zoomNum: 17,
  149. speedList: [],
  150. base64: '',
  151. wdwidth: '',
  152. wdheight: '',
  153. showPhoto: false,
  154. userInfo: '',
  155. sportInfo: '',
  156. useTimeList: '',
  157. cadenceInfo: '',
  158. maxCadence: 0,
  159. averageCadence: 0,
  160. maxSpeed: 0,
  161. mapBase:'',
  162. minSpeed: 9999,
  163. };
  164. },
  165. watch: {
  166. defaultV() {
  167. console.log(this.defaultV);
  168. if (this.defaultV !== undefined) {
  169. console.log(this.defaultV);
  170. }
  171. }
  172. },
  173. beforeDestroy() {
  174. // #ifdef H5
  175. cancelAnimationFrame(this.timeR);
  176. cancelAnimationFrame(this.timR);
  177. cancelAnimationFrame(this.bollTimeR);
  178. // #endif
  179. },
  180. onReady() {
  181. },
  182. async created() {
  183. function remoteLoad(url, hasCallback) {
  184. return createScript(url);
  185. function createScript(url) {
  186. let scriptElement = document.createElement('script');
  187. document.body.appendChild(scriptElement);
  188. let promise = new Promise((resolve, reject) => {
  189. scriptElement.addEventListener(
  190. 'load',
  191. e => {
  192. removeScript(scriptElement);
  193. if (!hasCallback) {
  194. resolve(e);
  195. }
  196. },
  197. false
  198. );
  199. scriptElement.addEventListener(
  200. 'error',
  201. e => {
  202. removeScript(scriptElement);
  203. reject(e);
  204. },
  205. false
  206. );
  207. if (hasCallback) {
  208. window.____callback____ = function() {
  209. resolve();
  210. window.____callback____ = null;
  211. };
  212. }
  213. });
  214. if (hasCallback) {
  215. url += '&callback=____callback____';
  216. }
  217. scriptElement.src = url;
  218. return promise;
  219. }
  220. /**
  221. * 移除script标签
  222. * @param scriptElement script dom
  223. */
  224. function removeScript(scriptElement) {
  225. document.body.removeChild(scriptElement);
  226. }
  227. }
  228. let data1 = {
  229. user_id:this.$route.query.user_id
  230. }
  231. this.GetUserInfo(data1)
  232. let data2 = {
  233. task_id:this.$route.query.task_id
  234. }
  235. this.GetSportInfo(data2)
  236. // uni.request({
  237. // // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/correction/trackPointDbSearch?task_id='+this.$route.query.task_id,
  238. // url: 'https://lzyd-front-user-api.lizhiyuedong.com/customer/getInfo?user_id=' + this.$route
  239. // .query.user_id,
  240. // // url: 'http://192.168.0.111:4002/api/task/redis?task_id='+ this.$route.query.task_id,
  241. // method: 'GET',
  242. // success: res => {
  243. // this.userInfo = res.data.data
  244. // // console.log(res)
  245. // // let coverImg = res.data.data.user_avatar
  246. // // this.urlTobase64(coverImg);
  247. // }
  248. // });
  249. // uni.request({
  250. // // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/correction/trackPointDbSearch?task_id='+this.$route.query.task_id,
  251. // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/runData/speed?task_id=' + this.$route.query.task_id,
  252. // // url: 'http://192.168.0.101:4002/api/runData/speed?task_id='+ this.$route.query.task_id,
  253. // method: 'GET',
  254. // success: res => {
  255. // console.log(res)
  256. // this.useTimeList = res.data.data.speed
  257. // for (let k = 0; k < this.useTimeList.length; k++) {
  258. // if (this.useTimeList[k] > this.maxSpeed) {
  259. // this.maxSpeed = this.useTimeList[k]
  260. // }
  261. // if (this.useTimeList[k] < this.minSpeed) {
  262. // this.minSpeed = this.useTimeList[k]
  263. // }
  264. // }
  265. // this.cadenceInfo = res.data.data.cadence.cadence
  266. // let arrIndex = []
  267. // let maxCadence = 0
  268. // let averageCadence = 0
  269. // for (let i = 0; i < this.cadenceInfo.length; i++) {
  270. // arrIndex.push(i+1)
  271. // if (this.cadenceInfo[i] > maxCadence) {
  272. // maxCadence = this.cadenceInfo[i]
  273. // }
  274. // averageCadence = this.cadenceInfo[i] + averageCadence
  275. // if (i == this.cadenceInfo.length - 1) {
  276. // Math.ceil(averageCadence / this.cadenceInfo.length)
  277. // }
  278. // // console.log(arrIndex)
  279. // }
  280. // this.maxCadence = maxCadence
  281. // this.averageCadence = averageCadence
  282. // // console.log(arrIndex)
  283. // // console.log(this.cadenceInfo.length)
  284. // let that = this
  285. // let cadenceInfo = that.cadenceInfo
  286. // const query = uni.createSelectorQuery().in(this);
  287. // query.select('.chart').boundingClientRect((data, cadenceInfo) => {
  288. // this.lineDraw("line", data, that.cadenceInfo, arrIndex);
  289. // }).exec();
  290. // // this.timeListOther = res.data.data.speed
  291. // }
  292. // });
  293. let data = {
  294. "steps": this.$route.query.steps * 1,
  295. "task_id": this.$route.query.task_id,
  296. "user_id": this.$route.query.user_id
  297. }
  298. // this.GetSportSummary(data3)
  299. uni.request({
  300. // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/correction/trackPointDbSearch?task_id='+this.$route.query.task_id,
  301. url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/runData/summary',
  302. // url: 'http://192.168.0.111:4002/api/task/redis?task_id='+ this.$route.query.task_id,
  303. header: {
  304. 'content-type': 'application/x-www-form-urlencoded',
  305. },
  306. method: 'POST',
  307. data: JSON.stringify(data),
  308. // dataType:'json',
  309. success: res => {
  310. // console.log(res.data.message)
  311. if (res.data.message == '运动距离过短') {
  312. // uniapp.showToast('')
  313. alert('运动距离过短,暂无数据哦')
  314. } else if (res.data.message == '不存在的task_id') {
  315. alert('不存在的task_id')
  316. } else {
  317. this.sportInfo = res.data.data
  318. // console.log(this.sportInfo)
  319. }
  320. // this.list = res.data.data
  321. }
  322. });
  323. // 已载入高德地图API,则直接初始化地图
  324. if (window.AMap && window.AMapUI) {
  325. // this.initMap();
  326. // uni.request({
  327. // // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/correction/trackPointDbSearch?task_id='+this.$route.query.task_id,
  328. // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/correction/trackPointAmpSearch?task_id=' +
  329. // this.$route.query.task_id,
  330. // // url: 'http://192.168.0.111:4002/api/correction/trackPointAmpSearch?task_id='+ this.$route.query.task_id,
  331. // method: 'GET',
  332. // success: res => {
  333. // this.list = res.data.data
  334. // this.list.map((item => {
  335. // this.lineList.push(item.split(','))
  336. // }))
  337. // this.initMap();
  338. // }
  339. // });
  340. this.GetMapsInfo({task_id:this.$route.query.task_id})
  341. } else {
  342. await remoteLoad(
  343. `https://webapi.amap.com/maps?v=1.4.4&key=${MapKey}&plugin=AMap.Geocoder,AMap.PlaceSearch,AMap.ToolBar`
  344. );
  345. await remoteLoad('https://webapi.amap.com/ui/1.0/main.js');
  346. this.GetMapsInfo({task_id:this.$route.query.task_id})
  347. // uni.request({
  348. // url: 'http://lzyd-front-sport-api.lizhiyuedong.com/api/correction/trackPointAmpSearch?task_id=' +
  349. // this.$route.query.task_id,
  350. // // url: 'http://192.168.0.111:4002/api/correction/trackPointAmpSearch?task_id='+ this.$route.query.task_id,
  351. // method: 'GET',
  352. // success: res => {
  353. // this.list = res.data.data
  354. // this.list.map((item => {
  355. // this.lineList.push(item.split(','))
  356. // }))
  357. // this.initMap();
  358. // }
  359. // });
  360. }
  361. },
  362. methods: {
  363. dataURLtoFile(dataurl, filename) {
  364. var arr = dataurl.split(','),
  365. mime = arr[0].match(/:(.*?);/)[1],
  366. bstr = atob(arr[1]),
  367. n = bstr.length,
  368. u8arr = new Uint8Array(n);
  369. while (n--) {
  370. u8arr[n] = bstr.charCodeAt(n);
  371. }
  372. return new File([u8arr], filename, { type: mime });
  373. },
  374. closeImg() {
  375. this.showPhoto = false
  376. },
  377. GetUserInfo(data) {
  378. GetUserInfo(data).then(res => {
  379. // console.log(res)
  380. this.userInfo = res.data
  381. // console.log(res.data.user_avatar.crossOrigin)
  382. })
  383. },
  384. GetMapsInfo(data) {
  385. GetMapsInfo(data).then(res => {
  386. this.list = res.data
  387. this.list.map((item => {
  388. this.lineList.push(item.split(','))
  389. }))
  390. this.initMap();
  391. })
  392. },
  393. GetSportSummary(data) {
  394. GetSportSummary(data).then(res => {
  395. console.log(res)
  396. // this.userInfo = res.data.data
  397. if (res.data.message == '运动距离过短') {
  398. // uniapp.showToast('')
  399. alert('运动距离过短,暂无数据哦')
  400. } else if (res.data.message == '不存在的task_id') {
  401. alert('不存在的task_id')
  402. } else {
  403. this.sportInfo = res.data
  404. console.log(this.sportInfo)
  405. }
  406. })
  407. },
  408. GetSportInfo(data) {
  409. GetSportInfo(data).then(res => {
  410. // console.log(res)
  411. this.useTimeList = res.data.speed
  412. for (let k = 0; k < this.useTimeList.length; k++) {
  413. if (this.useTimeList[k] > this.maxSpeed) {
  414. this.maxSpeed = this.useTimeList[k]
  415. }
  416. if (this.useTimeList[k] < this.minSpeed) {
  417. this.minSpeed = this.useTimeList[k]
  418. }
  419. }
  420. this.cadenceInfo = res.data.cadence.cadence
  421. let arrIndex = []
  422. let maxCadence = 0
  423. let averageCadence = 0
  424. for (let i = 0; i < this.cadenceInfo.length; i++) {
  425. arrIndex.push(i+1)
  426. if (this.cadenceInfo[i] > maxCadence) {
  427. maxCadence = this.cadenceInfo[i]
  428. }
  429. averageCadence = this.cadenceInfo[i] + averageCadence
  430. if (i == this.cadenceInfo.length - 1) {
  431. Math.ceil(averageCadence / this.cadenceInfo.length)
  432. }
  433. // console.log(arrIndex)
  434. }
  435. this.maxCadence = maxCadence
  436. this.averageCadence = averageCadence
  437. // console.log(arrIndex)
  438. // console.log(this.cadenceInfo.length)
  439. let that = this
  440. let cadenceInfo = that.cadenceInfo
  441. const query = uni.createSelectorQuery().in(this);
  442. query.select('.chart').boundingClientRect((data, cadenceInfo) => {
  443. this.lineDraw("line", data, that.cadenceInfo, arrIndex);
  444. }).exec();
  445. // this.userInfo = res.data.data
  446. })
  447. },
  448. toShare () {
  449. uni.showLoading({
  450. title: '加载中',
  451. });
  452. uni.pageScrollTo({
  453. scrollTop: 0,
  454. duration: 0
  455. })
  456. var dom = document.querySelector('#poster'); // 获取dom元素
  457. console.log(dom.clientHeight)
  458. html2canvas(dom, {
  459. width: dom.clientWidth, //dom 原始宽度
  460. height: dom.clientHeight,
  461. scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
  462. scrollX: 0,
  463. useCORS: true, //支持跨域,但好像没什么用
  464. }).then((canvas) => {
  465. // 将生产的canvas转为base64图片
  466. this.base64 = canvas.toDataURL('image/png')
  467. let imgName = new Date().getTime();
  468. var file = this.dataURLtoFile(this.base64, imgName)
  469. console.log(this.base64)
  470. var dom1 = document.querySelector('#js-container');
  471. html2canvas(dom1, {
  472. width: dom1.clientWidth, //dom 原始宽度
  473. height: dom1.clientHeight,
  474. scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
  475. scrollX: 0,
  476. useCORS: true, //支持跨域,但好像没什么用
  477. }).then((canvas) => {
  478. this.mapBase = canvas.toDataURL('image/png')
  479. let dataBase = {
  480. "base64":this.base64,
  481. "task_id": this.$route.query.task_id,
  482. "user_id": this.$route.query.user_id,
  483. "map_base":this.mapBase,
  484. }
  485. let imgName = new Date().getTime() + "z"
  486. var file = this.dataURLtoFile(this.base64, imgName)
  487. uploadBase64(dataBase).then(res => {
  488. console.log(res)
  489. let data = {
  490. 'type':1,
  491. 'data':{
  492. 'title' :'荔枝悦动',
  493. 'content':'荔枝悦动',
  494. 'link':'',
  495. 'imageUrl':res.data.map_url
  496. }
  497. }
  498. uni.hideLoading();
  499. window.location.href="lzyd_web:"+JSON.stringify(data)
  500. // console.log(this.base64)
  501. // console.log(this.mapBase)
  502. })
  503. // 'mapBase':this.mapBase,
  504. // 'base64':this.base64,
  505. })
  506. });
  507. },
  508. toImg() {
  509. uni.showLoading({
  510. title: '加载中',
  511. });
  512. // 使页面滑到顶部,避免顶部出现白边
  513. uni.pageScrollTo({
  514. scrollTop: 0,
  515. duration: 0
  516. })
  517. var dom = document.querySelector('#poster'); // 获取dom元素
  518. // console.log(dom.clientHeight)
  519. html2canvas(dom, {
  520. width: dom.clientWidth, //dom 原始宽度
  521. height: dom.clientHeight,
  522. scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
  523. scrollX: 0,
  524. useCORS: true, //支持跨域,但好像没什么用
  525. }).then((canvas) => {
  526. this.base64 = canvas.toDataURL('image/png')
  527. let imgName = new Date().getTime();
  528. var file = this.dataURLtoFile(this.base64, imgName)
  529. var dom1 = document.querySelector('#js-container');
  530. html2canvas(dom1, {
  531. width: dom1.clientWidth, //dom 原始宽度
  532. height: dom1.clientHeight,
  533. scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
  534. scrollX: 0,
  535. useCORS: true, //支持跨域,但好像没什么用
  536. }).then((canvas) => {
  537. this.mapBase = canvas.toDataURL('image/png')
  538. let dataBase = {
  539. "base64":this.base64,
  540. "task_id": this.$route.query.task_id,
  541. "user_id": this.$route.query.user_id,
  542. "map_base":this.mapBase,
  543. }
  544. let imgName = new Date().getTime() + "z"
  545. var file = this.dataURLtoFile(this.base64, imgName)
  546. uploadBase64(dataBase).then(res => {
  547. console.log(res)
  548. let data = {
  549. 'type':0,
  550. 'data':{
  551. 'imageUrl':res.data.map_url
  552. }
  553. }
  554. uni.hideLoading();
  555. // window.location.href="lzyd_web:"+JSON.stringify(data)
  556. this.showPhoto = true
  557. // console.log(this.base64)
  558. // console.log(this.mapBase)
  559. })
  560. // 'mapBase':this.mapBase,
  561. // 'base64':this.base64,
  562. })
  563. // 将生产的canvas转为base64图片
  564. // uniapp.showToast('长按图片保存')
  565. });
  566. },
  567. getRoom(diff) {
  568. var room = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
  569. var diffArr = new Array(360, 180, 90, 45, 22, 11, 5, 2.5, 1.25, 0.6, 0.3, 0.15, 0.07, 0.03, 0);
  570. for (var i = 0; i < diffArr.length; i++) {
  571. if ((diff - diffArr[i]) >= 0) {
  572. return room[i] + 2;
  573. }
  574. }
  575. return 14;
  576. },
  577. getCenterPoint(maxJ, minJ, maxW, minW) { //通过经纬度获取中心位置和缩放级别
  578. if (maxJ == minJ && maxW == minW) return [maxJ, maxW, 17];
  579. var diff = maxJ - minJ;
  580. if (diff < (maxW - minW)) diff = maxW - minW;
  581. diff = parseInt(10000 * diff) / 10000;
  582. var centerJ = minJ * 1000000 + 1000000 * (maxJ - minJ) / 2;
  583. var centerW = minW * 1000000 + 1000000 * (maxW - minW) / 2;
  584. var zoom = this.getRoom(diff);
  585. this.centerLog = [centerJ / 1000000, centerW / 1000000]
  586. this.zoomNum = zoom - 1
  587. // console.log((centerJ/1000000),centerW/1000000,zoom)
  588. return [(centerJ / 1000000), centerW / 1000000, zoom];
  589. },
  590. // 搜索
  591. handleSearch() {
  592. if (this.searchKey) {
  593. this.placeSearch.search(this.searchKey);
  594. }
  595. },
  596. // 实例化地图
  597. initMap() {
  598. let AMapUI = (this.AMapUI = window.AMapUI);
  599. let AMap = (this.AMap = window.AMap);
  600. let that = this;
  601. let list = this.lineList
  602. if (list[0]) {
  603. var maxjd = list[0][0]
  604. var minjd = list[0][0]
  605. var maxwd = list[0][1]
  606. var minwd = list[0][1]
  607. }
  608. AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
  609. // console.log(this.lineList)
  610. list.filter((item) => {
  611. item[0] * 1 > maxjd
  612. maxjd = item[0] * 1
  613. })
  614. for (var i = 0; i < list.length; i++) {
  615. if (list[i][0] * 1 > maxjd) {
  616. maxjd = (list[i][0])
  617. }
  618. if (list[i][1] * 1 > maxwd) {
  619. maxwd = (list[i][1])
  620. }
  621. if (list[i][0] * 1 < minjd) {
  622. minjd = (list[i][0])
  623. }
  624. if (list[i][1] * 1 < minwd) {
  625. minwd = (list[i][1])
  626. }
  627. }
  628. that.getCenterPoint(maxjd, minjd, maxwd, minwd)
  629. let mapConfig = {
  630. zoom: that.zoomNum-1,
  631. center: that.centerLog,
  632. cityName: MapCityName
  633. };
  634. let map = new AMap.Map('js-container', mapConfig);
  635. // let map1 = new AMap.Map('js-container-1', mapConfig);
  636. // let list = this.lineList;
  637. let markers = [];
  638. for (var i = 0; i < list.length; i++) {
  639. if (i === 0) {
  640. var marker = new AMap.Marker({
  641. position: list[i],
  642. icon: new AMap.Icon({
  643. image: 'https://lzyd-app-image.lizhiyuedong.com/images/2021-04/bddada67de1d2c68192348ec1618388545.png',
  644. size: new AMap.Size(30, 30), //图标大小
  645. imageSize: new AMap.Size(20, 20)
  646. }),
  647. offset: new AMap.Pixel(0, 0)
  648. });
  649. } else if (i == list.length - 1) {
  650. var marker = new AMap.Marker({
  651. position: list[i],
  652. icon: new AMap.Icon({
  653. image: 'https://lzyd-app-image.lizhiyuedong.com/images/2021-04/1189fb2e36973cef09ff14be1618388569.png',
  654. size: new AMap.Size(30, 30), //图标大小
  655. imageSize: new AMap.Size(20, 20)
  656. }),
  657. offset: new AMap.Pixel(0, 0)
  658. });
  659. } else {
  660. // var marker = new AMap.Marker({
  661. // position: list[i],
  662. // icon: new AMap.Icon({
  663. // image: '',
  664. // // image: 'https://lzyd-image.lizhiyuedong.com/images/2021-03/cd4b33a0b3cf56942aad7cdb1616990068.png',
  665. // size: new AMap.Size(10, 10), //图标大小
  666. // imageSize: new AMap.Size(10, 10)
  667. // }),
  668. // offset: new AMap.Pixel(0, 0)
  669. // });
  670. }
  671. marker.setMap(map);
  672. // label默认蓝框白底左上角显示,样式className为:amap-marker-label
  673. marker.setLabel({
  674. offset: new AMap.Pixel(10, -30), //设置文本标注偏移量
  675. // content: "<div class='info' style='padding: 3px 5px;'>" + '' + '</div>', //设置文本标注内容
  676. direction: 'right' //设置文本标注方位
  677. });
  678. map.addControl(new AMap.ToolBar());
  679. marker.positon = list[i].id;
  680. markers.push(marker);
  681. // console.log(markers)
  682. }
  683. var polyline = new AMap.Polyline({
  684. path: list,
  685. strokeWeight: 6, // 线条宽度,默认为 1
  686. // strokeColor:'linear-gradient(270deg, #FF654C 0%, #FFC000 50%, #14D59C 100%);'
  687. strokeColor: "#14D59C", // 线条颜色
  688. lineJoin: "round", //折线拐点的绘制样式,默认值为'miter'尖角,其他可选值:'round'圆角、'bevel'斜角
  689. lineCap: "butt", //折线两端线帽的绘制样式,默认值为'butt'无头,其他可选值:'round'圆头、'square'方头
  690. zIndex: 50,
  691. }); // 将折线添加至地图实例// 显示一条已创建的 polyline// polyline.show();
  692. map.add(polyline);
  693. });
  694. },
  695. sortFn(arr) { //按小到大排序数组
  696. let arr2 = arr.sort((a, b) => {
  697. return a - b;
  698. })
  699. return arr2;
  700. },
  701. toFixedNumber(n = 2, val) { //去小数点后2位
  702. if (typeof val == "number") {
  703. return val.toFixed(n) * 1
  704. }
  705. },
  706. //绘制线条 line chart
  707. lineDraw(ids, elem, cadenceInfo, arrIndex) {
  708. let ctx = uni.createCanvasContext(ids);
  709. let grid = {
  710. top: (12 * elem.height) / 100, //canvas标签的高度的12%(相对总高的百分比)
  711. bottom: ((100 - 18) * elem.height) / 100, //canvas图形距离底部的百分比 18%
  712. left: (12 * elem.width) / 100, //距离左侧的百分比(12%总宽度)
  713. right: ((100 - 8) * elem.width) / 100 //距离右侧百分比(8%总宽度)
  714. },
  715. lineColor = "#999", //x,y轴线颜色
  716. fillColor = "#5B5E67", //x,y轴number颜色
  717. yAxis = {
  718. textSize: 10, //刻度数字fontSize
  719. maxNumber:Math.ceil(this.maxCadence/10) * 10 , //分段的最大值
  720. splitNumber: 5, //分成几段
  721. splitLen: 5, //轴左侧的小横线 -|
  722. marginSplit: 5 //刻度文字与 “-|”的距离
  723. },
  724. lineWidth = 1,
  725. xAxis = {
  726. textSize: 10, //刻度数字fontSize
  727. maxNumber: cadenceInfo.length ? cadenceInfo.length : 60,
  728. // maxNumber: 14,
  729. splitNumber: cadenceInfo.length ? Math.ceil(cadenceInfo.length / 2) : 6,
  730. // splitNumber: 7,
  731. splitLen: cadenceInfo.length ? Math.ceil(cadenceInfo.length / 2) : 6,
  732. // splitLen: 7,
  733. marginSplit: cadenceInfo.length ? Math.ceil(cadenceInfo.length / 2) : 6
  734. // marginSplit: 7
  735. },
  736. dotStyle = [{
  737. color: "#fff",
  738. arcR: 2, //半径
  739. dash: 0 //是否线条虚线 0实线 1以上虚线
  740. }],
  741. lineStyle = [{
  742. color: "#4caf50",
  743. lineDotType: "wave", //两圆点的连接线 line直线,wave二次贝塞尔曲线
  744. width: 2, //连线的width
  745. dash: 3 //是否线条虚线 0实线 1以上虚线
  746. }],
  747. dataJSON = [ //数据data
  748. {
  749. x: this.sortFn(arrIndex),
  750. y: cadenceInfo
  751. },
  752. // { x: this.sortFn([5, 23, 45, 39, 50, 28]), y: [9, 18, 70, 75, 56, 35] }
  753. ];
  754. ctx.beginPath();
  755. ctx.setLineWidth(lineWidth);
  756. ctx.setTextAlign("right");
  757. ctx.setTextBaseline("middle");
  758. ctx.setStrokeStyle(lineColor);
  759. ctx.setFillStyle(fillColor);
  760. //y轴纵轴 |
  761. ctx.moveTo(grid.left, grid.top);
  762. ctx.lineTo(grid.left, grid.bottom);
  763. ctx.setFontSize(yAxis.textSize);
  764. for (let n = 1; n <= yAxis.splitNumber; n++) {
  765. //刻度
  766. ctx.moveTo(grid.left, grid.bottom - (grid.bottom - grid.top) / yAxis.splitNumber * n + lineWidth);
  767. ctx.lineTo(grid.left - yAxis.splitLen, grid.bottom - (grid.bottom - grid.top) / yAxis.splitNumber * n +
  768. lineWidth);
  769. ctx.fillText(this.toFixedNumber(1, yAxis.maxNumber / yAxis.splitNumber * n), grid.left - yAxis
  770. .splitLen - lineWidth - yAxis.marginSplit, grid.bottom - (grid.bottom - grid.top) / yAxis
  771. .splitNumber * n + lineWidth)
  772. }
  773. //x轴横轴 一
  774. ctx.moveTo(grid.left, grid.bottom);
  775. ctx.lineTo(grid.right, grid.bottom);
  776. ctx.setTextAlign("center");
  777. ctx.setTextBaseline("top");
  778. ctx.setFontSize(xAxis.textSize);
  779. for (let n = 1; n <= xAxis.splitNumber; n++) {
  780. //刻度
  781. ctx.moveTo(grid.left + (grid.right - grid.left) / xAxis.splitNumber * n - lineWidth, grid.bottom);
  782. ctx.lineTo(grid.left + (grid.right - grid.left) / xAxis.splitNumber * n - lineWidth, grid.bottom +
  783. xAxis.splitLen);
  784. ctx.fillText(this.toFixedNumber(1, xAxis.maxNumber / xAxis.splitNumber * n), grid.left + (grid.right -
  785. grid.left) / xAxis.splitNumber * n - lineWidth, grid.bottom + xAxis.splitLen + lineWidth +
  786. xAxis.marginSplit)
  787. }
  788. ctx.stroke();
  789. //绘制线条函数方法new function
  790. let drawLineData = (dataX, dataY, ix) => {
  791. dataX.forEach((ele, indx) => {
  792. let x = grid.left + (grid.right - grid.left) * (ele / xAxis.maxNumber) - lineWidth,
  793. y = grid.bottom - (grid.bottom - grid.top) * (dataY[indx] / yAxis.maxNumber) +
  794. lineWidth;
  795. if (indx >= dataX.length - 1) {} else {
  796. let x2 = grid.left + (grid.right - grid.left) * (dataX[indx + 1] / xAxis
  797. .maxNumber) - lineWidth,
  798. y2 = grid.bottom - (grid.bottom - grid.top) * (dataY[indx + 1] / yAxis
  799. .maxNumber) + lineWidth;
  800. let dis = {
  801. x: x + (x2 - x) / 3 + (x2 - x) / 2,
  802. y: y2 - y > 0 ? y + (y2 - y) / 3 - (y2 - y) / 5 : y + (y2 - y) / 3 + (y2 -
  803. y) / 5
  804. };
  805. //绘制圆点之间连线
  806. ctx.beginPath();
  807. ctx.setStrokeStyle(lineStyle[ix].color);
  808. ctx.setLineDash([lineStyle[ix].dash]);
  809. ctx.moveTo(x, y);
  810. if (lineStyle[ix].lineDotType == "line") { //直线连接
  811. ctx.lineTo(x2, y2);
  812. } else if (lineStyle[ix].lineDotType == "wave") { //二次贝塞尔曲线连接
  813. ctx.quadraticCurveTo(dis.x, dis.y, x2, y2);
  814. }
  815. ctx.stroke();
  816. }
  817. //绘制圆点arc
  818. ctx.beginPath();
  819. ctx.setFillStyle(dotStyle[ix].color);
  820. ctx.setLineDash([dotStyle[ix].dash]);
  821. ctx.arc(x, y, dotStyle[ix].arcR, 0, 2 * Math.PI);
  822. ctx.fill();
  823. ctx.stroke();
  824. //绘制圆点的文字坐标
  825. // ctx.beginPath();
  826. // ctx.setFillStyle("#2C405A");
  827. // ctx.fillText(ele+","+dataY[indx], x,y);
  828. // ctx.fill();
  829. })
  830. }
  831. //遍历折线数据
  832. dataJSON.forEach((e, v) => {
  833. drawLineData(e.x, e.y, v);
  834. })
  835. ctx.draw();
  836. }
  837. }
  838. };
  839. </script>
  840. <style lang="less">
  841. .amap-marker-label {
  842. background-color: rgb(255, 255, 255);
  843. border: 1px dashed rgb(255, 204, 102) !important;
  844. }
  845. .content-window-card {
  846. position: relative;
  847. box-shadow: none;
  848. bottom: 0;
  849. left: 0;
  850. width: auto;
  851. padding: 0;
  852. }
  853. .content-window-card p {
  854. height: 2rem;
  855. }
  856. .custom-info {
  857. border: solid 1px silver;
  858. }
  859. .info-top {
  860. position: relative;
  861. background: none repeat scroll 0 0 #f9f9f9;
  862. border-bottom: 1px solid #ccc;
  863. border-radius: 5px 5px 0 0;
  864. }
  865. .info-top div {
  866. display: inline-block;
  867. color: #333333;
  868. font-size: 14px;
  869. font-weight: bold;
  870. line-height: 31px;
  871. padding: 0 10px;
  872. }
  873. .info-top img {
  874. position: absolute;
  875. top: 10px;
  876. right: 10px;
  877. transition-duration: 0.25s;
  878. }
  879. .info-top img:hover {
  880. box-shadow: 0px 0px 5px #000;
  881. }
  882. .info-middle {
  883. font-size: 12px;
  884. padding: 10px 6px;
  885. line-height: 20px;
  886. }
  887. .info-bottom {
  888. height: 0px;
  889. width: 100%;
  890. clear: both;
  891. text-align: center;
  892. }
  893. .info-bottom img {
  894. position: relative;
  895. z-index: 104;
  896. }
  897. span {
  898. margin-left: 5px;
  899. font-size: 11px;
  900. }
  901. .info-middle img {
  902. float: left;
  903. margin-right: 6px;
  904. }
  905. .m-map {
  906. width: 100%;
  907. min-height: 100%;
  908. position: fixed;
  909. top: 0;
  910. .zhezhaoMap {
  911. width: 100%;
  912. height: 100%;
  913. background-color: rgba(0, 0, 0, 0.3);
  914. position: absolute;
  915. top: 0;
  916. left: 0;
  917. z-index: 9;
  918. }
  919. }
  920. .m-map .map {
  921. width: 100%;
  922. height: 170vh;
  923. text-align: center;
  924. position: relative;
  925. top: -50vh;
  926. }
  927. .m-map .search {
  928. overflow: scroll;
  929. position: absolute;
  930. top: 10px;
  931. left: 10px;
  932. width: 500px;
  933. height: 30px;
  934. padding-left: 5px;
  935. z-index: 1;
  936. border: 1px solid #ccc;
  937. line-height: 20px;
  938. outline: none;
  939. }
  940. .m-map .result {
  941. max-height: 300px;
  942. overflow: auto;
  943. margin-top: 10px;
  944. }
  945. .m-map1 {
  946. margin-left: 5vw;
  947. }
  948. #poster {
  949. // overflow: hidden;
  950. width: 100%;
  951. height: 100%;
  952. }
  953. .map-box {
  954. width: 100vw;
  955. height: 100%;
  956. display: flex;
  957. flex-flow: row nowrap;
  958. position: relative;
  959. }
  960. /deep/.amap-logo {
  961. display: none;
  962. opacity: 0 !important;
  963. }
  964. /deep/.amap-copyright {
  965. opacity: 0;
  966. }
  967. /deep/.amap-zoomcontrol {
  968. display: none !important;
  969. opacity: 0;
  970. }
  971. .jiluBigBox {
  972. // padding-top: 600rpx;
  973. width: 750rpx;
  974. /* height: 1000rpx; */
  975. // position: relative;
  976. // top: 1000rpx;
  977. padding-top: 900rpx;
  978. padding-bottom: 150rpx;
  979. // left:30rpx;
  980. /* background-color:#000000; */
  981. .jiluBox1 {
  982. width: 690rpx;
  983. height: 600rpx;
  984. left: 30rpx;
  985. border-radius: 10rpx;
  986. margin-bottom: 20rpx;
  987. position: relative;
  988. background-color: #242529;
  989. .userPhoto {
  990. overflow: hidden;
  991. width: 120rpx;
  992. height: 120rpx;
  993. position: absolute;
  994. top: -30rpx;
  995. right: 30rpx;
  996. border-radius: 50%;
  997. // background-color: blue;
  998. }
  999. .distance {
  1000. position: absolute;
  1001. top: 22rpx;
  1002. left: 34rpx;
  1003. height: 140rpx;
  1004. font-size: 120rpx;
  1005. font-weight: bold;
  1006. color: #FFFFFF;
  1007. line-height: 140rpx;
  1008. letter-spacing: -3rpx;
  1009. .km {
  1010. width: 72rpx;
  1011. height: 50rpx;
  1012. font-size: 36rpx;
  1013. font-weight: 400;
  1014. color: #A2A5B9;
  1015. line-height: 50rpx;
  1016. }
  1017. }
  1018. .uesrName {
  1019. // width: 140rpx;
  1020. height: 42rpx;
  1021. font-size: 30rpx;
  1022. font-weight: 500;
  1023. color: #FFFFFF;
  1024. line-height: 42rpx;
  1025. position: absolute;
  1026. right: 27rpx;
  1027. top: 100rpx;
  1028. }
  1029. .title {
  1030. height: 33rpx;
  1031. font-size: 24rpx;
  1032. font-weight: 400;
  1033. color: #5B5E67;
  1034. line-height: 33rpx;
  1035. position: absolute;
  1036. top: 157rpx;
  1037. left: 43rpx;
  1038. }
  1039. .creatTime {
  1040. height: 33rpx;
  1041. font-size: 24rpx;
  1042. font-weight: 400;
  1043. color: #5B5E67;
  1044. line-height: 33rpx;
  1045. position: absolute;
  1046. top: 157rpx;
  1047. right: 43rpx;
  1048. }
  1049. .lineColor {
  1050. width: 690rpx;
  1051. height: 6rpx;
  1052. background: linear-gradient(270deg, #FF654C 0%, #FFC000 50%, #14D59C 100%);
  1053. position: absolute;
  1054. top: 223rpx;
  1055. left: 1rpx;
  1056. .lowSpeed {
  1057. width: 104rpx;
  1058. height: 28rpx;
  1059. font-size: 20rpx;
  1060. font-weight: 400;
  1061. color: #14D59C;
  1062. line-height: 28rpx;
  1063. position: absolute;
  1064. top: -11rpx;
  1065. left: 43rpx;
  1066. text-align: center;
  1067. }
  1068. .fastSpeed {
  1069. width: 104rpx;
  1070. height: 28rpx;
  1071. font-size: 20rpx;
  1072. font-weight: 400;
  1073. color: #FF5049;
  1074. line-height: 28rpx;
  1075. position: absolute;
  1076. text-align: center;
  1077. top: -11rpx;
  1078. right: 43rpx;
  1079. }
  1080. }
  1081. .boxLine {
  1082. width: 650rpx;
  1083. height: 2rpx;
  1084. background-color: #3F4047;
  1085. position: absolute;
  1086. top: 420rpx;
  1087. left: 20rpx;
  1088. }
  1089. .sportData {
  1090. width: 690rpx;
  1091. height: 170rpx;
  1092. position: absolute;
  1093. top: 250rpx;
  1094. font-weight: bold;
  1095. color: #A2A5B9;
  1096. line-height: 53px;
  1097. display: flex;
  1098. text-align: center;
  1099. flex-flow: row nowrap;
  1100. .dataBox {
  1101. width: 228rpx;
  1102. height: 100%;
  1103. .dataNum {
  1104. font-size: 46rpx;
  1105. font-weight: bold;
  1106. color: #A2A5B9;
  1107. }
  1108. .dataName {
  1109. // width: 104px;
  1110. height: 37rpx;
  1111. font-size: 26rpx;
  1112. font-weight: 400;
  1113. color: #5B5E67;
  1114. line-height: 37rpx;
  1115. }
  1116. }
  1117. .dateLine {
  1118. width: 2rpx;
  1119. height: 80rpx;
  1120. background: #3F4047;
  1121. position: relative;
  1122. top: 40rpx;
  1123. }
  1124. }
  1125. }
  1126. .jiluBox2 {
  1127. width: 690rpx;
  1128. left: 30rpx;
  1129. border-radius: 10rpx;
  1130. margin-bottom: 20rpx;
  1131. position: relative;
  1132. background-color: #242529;
  1133. padding-bottom: 20rpx;
  1134. .title {
  1135. width: 60rpx;
  1136. height: 42rpx;
  1137. font-size: 30rpx;
  1138. font-weight: 600;
  1139. color: #A2A5B9;
  1140. line-height: 42rpx;
  1141. position: relative;
  1142. top: 23rpx;
  1143. left: 40rpx;
  1144. }
  1145. .kmspeed {
  1146. width: 200rpx;
  1147. height: 37rpx;
  1148. font-size: 26rpx;
  1149. font-weight: 400;
  1150. color: #5B5E67;
  1151. line-height: 37rpx;
  1152. position: relative;
  1153. top: 50rpx;
  1154. left: 40rpx;
  1155. }
  1156. .allSpeedBox {
  1157. width: 100%;
  1158. margin-top: 80rpx;
  1159. // position: relative;
  1160. // top:68rpx;
  1161. }
  1162. .speedLineBox {
  1163. width: 600rpx;
  1164. height: 30rpx;
  1165. display: flex;
  1166. flex-flow: row nowrap;
  1167. position: relative;
  1168. left: 60rpx;
  1169. margin-bottom: 30rpx;
  1170. .lineNum {
  1171. width: 27rpx;
  1172. height: 37rpx;
  1173. font-size: 26rpx;
  1174. font-weight: 400;
  1175. color: #FFFFFF;
  1176. line-height: 37rpx;
  1177. }
  1178. .lineSpeed {
  1179. width: 70rpx;
  1180. height: 37rpx;
  1181. font-size: 26rpx;
  1182. font-weight: 400;
  1183. color: #FFFFFF;
  1184. line-height: 37rpx;
  1185. margin-left: 20rpx;
  1186. }
  1187. .speedColor {
  1188. width: 460rpx;
  1189. height: 24rpx;
  1190. position: relative;
  1191. margin-top: 7rpx;
  1192. background-color: #373B3C;
  1193. margin-left: 20rpx;
  1194. .speedLine {
  1195. // width: 318rpx;
  1196. height: 24rpx;
  1197. border-radius: 4rpx;
  1198. position: absolute;
  1199. left: 0;
  1200. top: 0;
  1201. }
  1202. .speedFast {
  1203. background: linear-gradient(270deg, #FF4D4C 0%, #FF8C00 100%);
  1204. }
  1205. .speedLow {
  1206. background: #14D59C;
  1207. }
  1208. }
  1209. }
  1210. .fengexian {
  1211. width: 560rpx;
  1212. height: 2rpx;
  1213. margin-top: 16rpx;
  1214. margin-left: 100rpx;
  1215. background-color: #3F4047;
  1216. }
  1217. .pinjunSpeed {
  1218. width: 292rpx;
  1219. height: 37rpx;
  1220. font-size: 26rpx;
  1221. font-weight: 400;
  1222. color: #5B5E67;
  1223. line-height: 37rpx;
  1224. margin-top: 34rpx;
  1225. margin-left: 100rpx;
  1226. }
  1227. }
  1228. .jiluBox3 {
  1229. width: 690rpx;
  1230. left: 30rpx;
  1231. // height: 621rpx;
  1232. padding-bottom: 40rpx;
  1233. border-radius: 10rpx;
  1234. margin-bottom: 20rpx;
  1235. position: relative;
  1236. background-color: #242529;
  1237. .danwei1 {
  1238. width: 180rpx;
  1239. height: 28rpx;
  1240. font-size: 20rpx;
  1241. font-weight: 400;
  1242. color: #666666;
  1243. line-height: 28rpx;
  1244. position: absolute;
  1245. top: 177rpx;
  1246. left: 20rpx;
  1247. z-index: 9;
  1248. }
  1249. .danwei2 {
  1250. width: 100rpx;
  1251. height: 28rpx;
  1252. font-size: 20rpx;
  1253. font-weight: 400;
  1254. color: #666666;
  1255. line-height: 28rpx;
  1256. position: absolute;
  1257. bottom: 50rpx;
  1258. right: 22rpx;
  1259. z-index: 9;
  1260. }
  1261. .title {
  1262. width: 60rpx;
  1263. height: 42rpx;
  1264. font-size: 30rpx;
  1265. font-weight: 600;
  1266. color: #A2A5B9;
  1267. line-height: 42rpx;
  1268. position: relative;
  1269. top: 23rpx;
  1270. left: 40rpx;
  1271. }
  1272. .bupinDataBox {
  1273. width: 460rpx;
  1274. height: 100rpx;
  1275. display: flex;
  1276. flex-flow: row nowrap;
  1277. position: relative;
  1278. top: 40rpx;
  1279. left: 115rpx;
  1280. justify-content: space-around;
  1281. .bupinData {
  1282. text-align: center;
  1283. .bupinDataNum {
  1284. // width: 67rpx;
  1285. height: 53rpx;
  1286. font-size: 46rpx;
  1287. font-weight: bold;
  1288. color: #14D59C;
  1289. line-height: 53rpx;
  1290. }
  1291. .bupinDataName {
  1292. width: 104rpx;
  1293. height: 37rpx;
  1294. font-size: 26rpx;
  1295. font-weight: 400;
  1296. color: #5B5E67;
  1297. line-height: 37rpx;
  1298. margin-top: 10rpx;
  1299. }
  1300. }
  1301. }
  1302. }
  1303. }
  1304. .fenxiangImageBox {
  1305. width: 100vw;
  1306. height: 100vh;
  1307. background-color: rgba(0, 0, 0, 0.4);
  1308. position: fixed;
  1309. top: 0;
  1310. left: 0;
  1311. z-index: 99;
  1312. }
  1313. .closePhoto {
  1314. width: 450rpx;
  1315. height: 86rpx;
  1316. background: #373B3C;
  1317. border-radius: 20rpx;
  1318. position: absolute;
  1319. bottom: 30rpx;
  1320. left: 150rpx;
  1321. text-align: center;
  1322. letter-spacing: 4rpx;
  1323. line-height: 86rpx;
  1324. color: white;
  1325. font-size: 28rpx;
  1326. }
  1327. .shareBox {
  1328. position: fixed;
  1329. bottom: 0;
  1330. left: 0;
  1331. background-color: #1A1A1A;
  1332. width: 100vw;
  1333. height: 150rpx;
  1334. z-index: 9;
  1335. }
  1336. .sharePhoto {
  1337. width: 250rpx;
  1338. height: 86rpx;
  1339. // background: #373B3C;
  1340. background-color: rgba(20, 213, 156, 1);
  1341. border-radius: 20rpx;
  1342. position: fixed;
  1343. bottom: 30rpx;
  1344. right: 80rpx;
  1345. text-align: center;
  1346. letter-spacing: 4rpx;
  1347. line-height: 86rpx;
  1348. color: white;
  1349. font-size: 28rpx;
  1350. z-index: 99;
  1351. }
  1352. .savePhoto {
  1353. width: 250rpx;
  1354. height: 86rpx;
  1355. // background: #373B3C;
  1356. background-color: #373B3C;
  1357. border-radius: 20rpx;
  1358. position: fixed;
  1359. bottom: 30rpx;
  1360. left: 80rpx;
  1361. text-align: center;
  1362. letter-spacing: 4rpx;
  1363. line-height: 86rpx;
  1364. color: white;
  1365. z-index: 99;
  1366. font-size: 28rpx;
  1367. }
  1368. .allImage {
  1369. width: 100%;
  1370. height: 100%;
  1371. }
  1372. .fenxiangImage {
  1373. width: 600rpx;
  1374. height: 1500rpx;
  1375. left: 75rpx;
  1376. // background-color: blue;
  1377. position: absolute;
  1378. top: 30rpx;
  1379. // z-index: 99;
  1380. }
  1381. .text-center {
  1382. text-align: center;
  1383. margin-bottom: 20rpx;
  1384. }
  1385. .mar-bot20 {
  1386. margin-bottom: 20rpx;
  1387. }
  1388. .line-chart {
  1389. padding: 20rpx;
  1390. padding-top: 50rpx;
  1391. }
  1392. .chart {
  1393. width: 100%;
  1394. height: 360rpx;
  1395. background: #242529;
  1396. border-radius: 10rpx;
  1397. // border: 1rpx solid #ccc;
  1398. color: #5B5E67;
  1399. }
  1400. </style>