util.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. import Config from './config.js'
  2. import store from '@/store/index.js'
  3. import Http from './http.js'
  4. export default {
  5. /**
  6. * 页面跳转
  7. * @param {string} to 跳转链接 /pages/idnex/index
  8. * @param {Object} param 参数 {key : value, ...}
  9. * @param {string} mode 模式
  10. */
  11. redirectTo(to, param, mode) {
  12. let url = to;
  13. let tabbarList = ['/pages/index/index', '/pages/goods/category', '/pages/goods/cart',
  14. '/pages/member/index'
  15. ]
  16. if (param != undefined) {
  17. Object.keys(param).forEach(function(key) {
  18. if (url.indexOf('?') != -1) {
  19. url += "&" + key + "=" + param[key];
  20. } else {
  21. url += "?" + key + "=" + param[key];
  22. }
  23. });
  24. }
  25. for (let i = 0; i < tabbarList.length; i++) {
  26. if (url.indexOf(tabbarList[i]) == 0) {
  27. uni.switchTab({
  28. url
  29. })
  30. return;
  31. }
  32. }
  33. switch (mode) {
  34. case 'tabbar':
  35. // 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
  36. uni.switchTab({
  37. url
  38. })
  39. break;
  40. case 'redirectTo':
  41. // 关闭当前页面,跳转到应用内的某个页面。
  42. uni.redirectTo({
  43. url
  44. });
  45. break;
  46. case 'reLaunch':
  47. // 关闭所有页面,打开到应用内的某个页面。
  48. uni.reLaunch({
  49. url
  50. });
  51. break;
  52. default:
  53. // 保留当前页面,跳转到应用内的某个页面
  54. uni.navigateTo({
  55. url
  56. });
  57. }
  58. },
  59. /**
  60. * 图片路径转换
  61. * @param {String} img_path 图片地址
  62. * @param {Object} params 参数,针对商品、相册里面的图片区分大中小,size: big、mid、small
  63. */
  64. img(img_path, params) {
  65. var path = "";
  66. if (img_path != undefined && img_path != "") {
  67. if (img_path.split(',').length > 1) {
  68. img_path = img_path.split(',')[0];
  69. }
  70. if (params && img_path != this.getDefaultImage().goods) {
  71. // 过滤默认图
  72. let arr = img_path.split(".");
  73. let suffix = arr[arr.length - 1];
  74. arr.pop();
  75. arr[arr.length - 1] = arr[arr.length - 1] + "_" + params.size.toUpperCase();
  76. arr.push(suffix);
  77. img_path = arr.join(".");
  78. }
  79. if (img_path.indexOf("http://") == -1 && img_path.indexOf("https://") == -1) {
  80. path = Config.imgDomain + "/" + img_path;
  81. } else {
  82. path = img_path;
  83. }
  84. // 处理商品助手的图片路径
  85. path = path.replace("addons/NsGoodsAssist/", "").replace("shop/goods/", "");
  86. }
  87. // path += '?t=' + parseInt(new Date().getTime() / 1000);
  88. return path;
  89. },
  90. /**
  91. * 时间戳转日期格式
  92. * @param {Object} timeStamp
  93. */
  94. timeStampTurnTime(timeStamp, type = "") {
  95. if (timeStamp != undefined && timeStamp != "" && timeStamp > 0) {
  96. var date = new Date();
  97. date.setTime(timeStamp * 1000);
  98. var y = date.getFullYear();
  99. var m = date.getMonth() + 1;
  100. m = m < 10 ? ('0' + m) : m;
  101. var d = date.getDate();
  102. d = d < 10 ? ('0' + d) : d;
  103. var h = date.getHours();
  104. h = h < 10 ? ('0' + h) : h;
  105. var minute = date.getMinutes();
  106. var second = date.getSeconds();
  107. minute = minute < 10 ? ('0' + minute) : minute;
  108. second = second < 10 ? ('0' + second) : second;
  109. if (type) {
  110. if (type == 'yearMonthDay') {
  111. return y + '年' + m + '月' + d + '日';
  112. }
  113. return y + '-' + m + '-' + d;
  114. } else {
  115. return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  116. }
  117. } else {
  118. return "";
  119. }
  120. },
  121. /**
  122. * 日期格式转时间戳
  123. * @param {Object} timeStamp
  124. */
  125. timeTurnTimeStamp(string) {
  126. var f = string.split(' ', 2);
  127. var d = (f[0] ? f[0] : '').split('-', 3);
  128. var t = (f[1] ? f[1] : '').split(':', 3);
  129. return (new Date(
  130. parseInt(d[0], 10) || null,
  131. (parseInt(d[1], 10) || 1) - 1,
  132. parseInt(d[2], 10) || null,
  133. parseInt(t[0], 10) || null,
  134. parseInt(t[1], 10) || null,
  135. parseInt(t[2], 10) || null
  136. )).getTime() / 1000;
  137. },
  138. /**
  139. * 倒计时
  140. * @param {Object} seconds 秒
  141. */
  142. countDown(seconds) {
  143. let [day, hour, minute, second] = [0, 0, 0, 0]
  144. if (seconds > 0) {
  145. day = Math.floor(seconds / (60 * 60 * 24))
  146. hour = Math.floor(seconds / (60 * 60)) - (day * 24)
  147. minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
  148. second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
  149. }
  150. if (day < 10) {
  151. day = '0' + day
  152. }
  153. if (hour < 10) {
  154. hour = '0' + hour
  155. }
  156. if (minute < 10) {
  157. minute = '0' + minute
  158. }
  159. if (second < 10) {
  160. second = '0' + second
  161. }
  162. return {
  163. d: day,
  164. h: hour,
  165. i: minute,
  166. s: second
  167. };
  168. },
  169. /**
  170. * 数值去重
  171. * @param {Array} arr 数组
  172. * @param {string} field 字段
  173. */
  174. unique(arr, field) {
  175. const res = new Map();
  176. return arr.filter((a) => !res.has(a[field]) && res.set(a[field], 1));
  177. },
  178. /**
  179. * 判断值是否在数组中
  180. * @param {Object} elem
  181. * @param {Object} arr
  182. * @param {Object} i
  183. */
  184. inArray: function(elem, arr) {
  185. return arr == null ? -1 : arr.indexOf(elem);
  186. },
  187. /**
  188. * 获取某天日期
  189. * @param {Object} day
  190. */
  191. getDay: function(day) {
  192. var today = new Date();
  193. var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day;
  194. today.setTime(targetday_milliseconds);
  195. const doHandleMonth = function(month) {
  196. var m = month;
  197. if (month.toString().length == 1) {
  198. m = "0" + month;
  199. }
  200. return m
  201. }
  202. var tYear = today.getFullYear();
  203. var tMonth = today.getMonth();
  204. var tDate = today.getDate();
  205. var tWeek = today.getDay();
  206. var time = parseInt(today.getTime() / 1000);
  207. tMonth = doHandleMonth(tMonth + 1);
  208. tDate = doHandleMonth(tDate);
  209. const week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  210. return {
  211. 't': time,
  212. 'y': tYear,
  213. 'm': tMonth,
  214. 'd': tDate,
  215. 'w': week[tWeek]
  216. };
  217. },
  218. //上传
  219. upload_file_server(tempFilePath, data, path, url = "", callback) {
  220. if (url) {
  221. var uploadUrl = Config.baseUrl + url
  222. } else {
  223. var uploadUrl = Config.baseUrl + '/api/upload/' + path
  224. }
  225. return new Promise((resolve, reject) => {
  226. uni.uploadFile({
  227. url: uploadUrl,
  228. filePath: tempFilePath,
  229. name: 'file',
  230. formData: data,
  231. success: function(res) {
  232. var path_str = JSON.parse(res.data);
  233. if (path_str.code >= 0) {
  234. resolve(path_str.data.pic_path);
  235. typeof callback == 'function' && callback(path_str.data.pic_path);
  236. } else {
  237. reject("error");
  238. }
  239. }
  240. });
  241. });
  242. },
  243. /**
  244. * 复制
  245. * @param {Object} message
  246. * @param {Object} callback
  247. */
  248. copy(value, callback) {
  249. // #ifdef H5
  250. var oInput = document.createElement('input'); //创建一个隐藏input(重要!)
  251. oInput.value = value; //赋值
  252. oInput.setAttribute("readonly", "readonly");
  253. document.body.appendChild(oInput);
  254. oInput.select(); // 选择对象
  255. document.execCommand("Copy"); // 执行浏览器复制命令
  256. oInput.className = 'oInput';
  257. oInput.style.display = 'none';
  258. uni.hideKeyboard();
  259. this.showToast({
  260. title: '复制成功'
  261. });
  262. typeof callback == 'function' && callback();
  263. // #endif
  264. // #ifdef MP || APP-PLUS
  265. uni.setClipboardData({
  266. data: value,
  267. success: () => {
  268. typeof callback == 'function' && callback();
  269. }
  270. });
  271. // #endif
  272. },
  273. /**
  274. * 显示消息提示框
  275. * @param {Object} params 参数
  276. */
  277. showToast(params = {}) {
  278. params.title = params.title || "";
  279. params.icon = params.icon || "none";
  280. // params.position = params.position || 'bottom';
  281. params.duration = params.duration || 1500;
  282. uni.showToast(params);
  283. if (params.success) params.success();
  284. },
  285. /**
  286. * 检测苹果X以上的手机
  287. */
  288. isIPhoneX() {
  289. let res = uni.getSystemInfoSync();
  290. if (res.model.search('iPhone X') != -1) {
  291. return true;
  292. }
  293. return false;
  294. },
  295. //判断安卓还是iOS
  296. isAndroid() {
  297. let platform = uni.getSystemInfoSync().platform
  298. if (platform == 'ios') {
  299. return false;
  300. } else if (platform == 'android') {
  301. return true;
  302. }
  303. },
  304. /**
  305. * 深度拷贝对象
  306. * @param {Object} obj
  307. */
  308. deepClone(obj) {
  309. const isObject = function(obj) {
  310. return typeof obj == 'object';
  311. }
  312. if (!isObject(obj)) {
  313. throw new Error('obj 不是一个对象!')
  314. }
  315. //判断传进来的是对象还是数组
  316. let isArray = Array.isArray(obj)
  317. let cloneObj = isArray ? [] : {}
  318. //通过for...in来拷贝
  319. for (let key in obj) {
  320. cloneObj[key] = isObject(obj[key]) ? this.deepClone(obj[key]) : obj[key]
  321. }
  322. return cloneObj
  323. },
  324. /**
  325. * 获取默认图
  326. * @param {Object} link
  327. */
  328. getDefaultImage() {
  329. let defaultImg = uni.getStorageSync('default_img');
  330. if (defaultImg) {
  331. defaultImg.goods = this.img(defaultImg.goods);
  332. defaultImg.head = this.img(defaultImg.head);
  333. defaultImg.store = this.img(defaultImg.store);
  334. defaultImg.article = this.img(defaultImg.article);
  335. return defaultImg;
  336. } else {
  337. return {
  338. goods: '',
  339. head: '',
  340. store: '',
  341. article: ''
  342. };
  343. }
  344. },
  345. /**
  346. * 判断手机是否为iphoneX系列
  347. */
  348. uniappIsIPhoneX() {
  349. let isIphoneX = false;
  350. let systemInfo = uni.getSystemInfoSync();
  351. // #ifdef MP
  352. if (systemInfo.model.search('iPhone X') != -1 || systemInfo.model.search('iPhone 11') != -1 || systemInfo.model
  353. .search('iPhone 12') != -1 || systemInfo.model.search('iPhone 13') != -1) {
  354. isIphoneX = true;
  355. }
  356. // #endif
  357. // #ifdef H5
  358. var u = navigator.userAgent;
  359. var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  360. if (isIOS) {
  361. if (systemInfo.screenWidth == 375 && systemInfo.screenHeight == 812 && systemInfo.pixelRatio == 3) {
  362. isIphoneX = true;
  363. } else if (systemInfo.screenWidth == 414 && systemInfo.screenHeight == 896 && systemInfo.pixelRatio == 3) {
  364. isIphoneX = true;
  365. } else if (systemInfo.screenWidth == 414 && systemInfo.screenHeight == 896 && systemInfo.pixelRatio == 2) {
  366. isIphoneX = true;
  367. }
  368. }
  369. // #endif
  370. return isIphoneX;
  371. },
  372. /**
  373. * 判断手机是否为iphone11系列
  374. */
  375. uniappIsIPhone11() {
  376. let isIphone11 = false;
  377. let systemInfo = uni.getSystemInfoSync();
  378. // #ifdef MP
  379. if (systemInfo.model.search('iPhone 11') != -1) {
  380. isIphone11 = true;
  381. }
  382. // #endif
  383. return isIphone11;
  384. },
  385. // #ifdef H5
  386. //判断该浏览器是否为safaria浏览器
  387. isSafari() {
  388. let res = uni.getSystemInfoSync();
  389. var ua = navigator.userAgent.toLowerCase();
  390. if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 &&
  391. ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 &&
  392. ua.indexOf('ios') === -1 && ua.indexOf('browser') === -1) {
  393. return true;
  394. } else {
  395. return false;
  396. }
  397. },
  398. // #endif
  399. numberFixed(e, f) {
  400. if (!f) {
  401. f = 0;
  402. }
  403. return Number(e).toFixed(f);
  404. },
  405. /**
  406. * 获取url参数
  407. */
  408. getUrlCode(callback) {
  409. var url = location.search;
  410. var theRequest = new Object();
  411. if (url.indexOf('?') != -1) {
  412. var str = url.substr(1);
  413. var strs = str.split('&');
  414. for (var i = 0; i < strs.length; i++) {
  415. theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1];
  416. }
  417. }
  418. typeof callback == 'function' && callback(theRequest);
  419. },
  420. /**
  421. * 获取当前页面路由
  422. */
  423. getCurrRoute() {
  424. let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
  425. return routes.length ? routes[routes.length - 1].route : '';
  426. },
  427. goBack(backUrl = '/pages/index/index') {
  428. if (getCurrentPages().length == 1) {
  429. this.redirectTo(backUrl);
  430. } else {
  431. uni.navigateBack();
  432. }
  433. },
  434. /**
  435. * @param {Object} 转化时间字符串 (转化时分秒)
  436. */
  437. getTimeStr(val) {
  438. var h = parseInt(val / 3600).toString();
  439. var m = parseInt((val % 3600) / 60).toString();
  440. if (m.length == 1) {
  441. m = '0' + m;
  442. }
  443. if (h.length == 1) {
  444. h = '0' + h;
  445. }
  446. return h + ':' + m;
  447. },
  448. /**
  449. * 获取定位信息
  450. */
  451. getLocation(param = {}) {
  452. uni.getLocation({
  453. type: param.type ?? 'gcj02',
  454. success: res => {
  455. store.commit('setLocation', res);
  456. typeof param.success == 'function' && param.success(res);
  457. },
  458. fail: res => {
  459. typeof param.fail == 'function' && param.fail(res);
  460. },
  461. complete: res => {
  462. typeof param.complete == 'function' && param.complete(res);
  463. }
  464. });
  465. },
  466. // 计算两个经纬度之间的距离
  467. getDistance(lat1, lng1, lat2, lng2) {
  468. var radLat1 = lat1 * Math.PI / 180.0;
  469. var radLat2 = lat2 * Math.PI / 180.0;
  470. var a = radLat1 - radLat2;
  471. var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
  472. var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
  473. Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
  474. s = s * 6378.137; // EARTH_RADIUS;
  475. s = Math.round(s * 10000) / 10000;
  476. return s;
  477. },
  478. //记录分享人
  479. onSourceMember(source_member) {
  480. Http.sendRequest({
  481. url: '/api/Member/alterShareRelation',
  482. data: {
  483. share_member: source_member,
  484. },
  485. success: res => {
  486. if (res.code >= 0) {
  487. uni.removeStorage({
  488. key: 'source_member',
  489. success: res => {
  490. console.log('删除成功', res)
  491. }
  492. })
  493. }
  494. }
  495. })
  496. },
  497. /**
  498. * 微信订阅消息
  499. */
  500. subscribeMessage(string) {
  501. let keywords = string;
  502. Http.sendRequest({
  503. url: '/weapp/api/weapp/messagetmplids',
  504. data: {
  505. keywords: keywords
  506. },
  507. success: res => {
  508. if (res.data.length) {
  509. uni.requestSubscribeMessage({
  510. tmplIds: res.data,
  511. success: (res) => {
  512. console.log("res", res)
  513. },
  514. fail: (res) => {
  515. console.log('fail', res)
  516. }
  517. })
  518. }
  519. }
  520. })
  521. },
  522. /**
  523. * 分享获取memberId,进行上下级绑定
  524. */
  525. getMemberId() {
  526. return new Promise((resolve, reject) => {
  527. Http.sendRequest({
  528. url: "/api/member/id",
  529. success: res => {
  530. if (res.code >= 0) {
  531. resolve(res.data)
  532. } else {
  533. reject(res)
  534. }
  535. }
  536. });
  537. })
  538. },
  539. /**
  540. * 获取小程序分享内容数据
  541. */
  542. getMpShare(path) {
  543. //如果没有特别指定 则获取当前页面的路由
  544. if (!path) {
  545. let route = this.getCurrentRoute();
  546. path = route.path;
  547. if (path == '/pages/member/index') {
  548. return new Promise((resolve, reject) => {
  549. resolve({})
  550. });
  551. };
  552. }
  553. return new Promise((resolve, reject) => {
  554. Http.sendRequest({
  555. url: "/weapp/api/weapp/share",
  556. data: {
  557. path: path
  558. },
  559. success: res => {
  560. if (res.code >= 0) {
  561. let shareConfig = res.data.data;
  562. if (shareConfig) {
  563. //分享给好友
  564. let appMessageData = {
  565. title: shareConfig.title,
  566. path: shareConfig.path,
  567. imageUrl: shareConfig.imageUrl,
  568. success: res => {},
  569. fail: res => {}
  570. }
  571. //分享到朋友圈
  572. let query = '';
  573. if (shareConfig.path.indexOf('?') > 0) {
  574. query = shareConfig.path.split('?')[1];
  575. }
  576. let timeLineData = {
  577. title: shareConfig.title,
  578. query: shareConfig.path,
  579. imageUrl: shareConfig.imageUrl,
  580. }
  581. resolve({
  582. appMessage: appMessageData,
  583. timeLine: timeLineData,
  584. })
  585. } else {
  586. reject(res.data);
  587. }
  588. } else {
  589. reject(res.data)
  590. }
  591. }
  592. });
  593. })
  594. },
  595. //获取当前路由
  596. getCurrentRoute() {
  597. let currentRoutes = getCurrentPages(); // 获取当前打开过的页面路由数组
  598. let currentRoute = currentRoutes[currentRoutes.length - 1].route //获取当前页面路由
  599. let currentParam = currentRoutes[currentRoutes.length - 1].options; //获取路由参数
  600. // 拼接参数
  601. let param = [];
  602. for (let key in currentParam) {
  603. param.push(key + '=' + currentParam[key])
  604. }
  605. let currentPath = '/' + currentRoute;
  606. let currentQuery = param.join('&');
  607. if (currentQuery) currentPath += '?' + currentQuery;
  608. return {
  609. path: currentPath,
  610. query: currentQuery,
  611. }
  612. },
  613. //获取分享路由
  614. getCurrentShareRoute(member_id) {
  615. let route = this.getCurrentRoute();
  616. //去掉原来的分享人数据
  617. route.path = route.path.replace(/[?|&]source_member=\d+/, '');
  618. if (member_id) {
  619. //路径的处理
  620. if (route.path.indexOf('?') > 0) {
  621. route.path += '&';
  622. } else {
  623. route.path += '?';
  624. }
  625. route.path += 'source_member=' + member_id;
  626. //参数的处理
  627. if (route.query) {
  628. route.query += '&';
  629. }
  630. route.query += 'source_member=' + member_id;
  631. }
  632. return route;
  633. },
  634. /**
  635. * 对象转style字符串
  636. * @param {Object} obj
  637. */
  638. objToStyle(obj) {
  639. let s = [];
  640. for (let i in obj) {
  641. s.push(i + ':' + obj[i]);
  642. }
  643. return s.join(';')
  644. },
  645. /**
  646. * 颜色减值
  647. * @param {Object} c1
  648. * @param {Object} c2
  649. * @param {Object} ratio
  650. */
  651. colourBlend(c1, c2, ratio) {
  652. ratio = Math.max(Math.min(Number(ratio), 1), 0)
  653. let r1 = parseInt(c1.substring(1, 3), 16)
  654. let g1 = parseInt(c1.substring(3, 5), 16)
  655. let b1 = parseInt(c1.substring(5, 7), 16)
  656. let r2 = parseInt(c2.substring(1, 3), 16)
  657. let g2 = parseInt(c2.substring(3, 5), 16)
  658. let b2 = parseInt(c2.substring(5, 7), 16)
  659. let r = Math.round(r1 * (1 - ratio) + r2 * ratio)
  660. let g = Math.round(g1 * (1 - ratio) + g2 * ratio)
  661. let b = Math.round(b1 * (1 - ratio) + b2 * ratio)
  662. r = ('0' + (r || 0).toString(16)).slice(-2)
  663. g = ('0' + (g || 0).toString(16)).slice(-2)
  664. b = ('0' + (b || 0).toString(16)).slice(-2)
  665. return '#' + r + g + b
  666. },
  667. /**
  668. * 生成贝塞尔曲线轨迹
  669. * @param {Object} points
  670. * @param {Object} times
  671. */
  672. bezier(points, times) {
  673. var bezier_points = [];
  674. var points_D = [];
  675. var points_E = [];
  676. const DIST_AB = Math.sqrt(Math.pow(points[1]['x'] - points[0]['x'], 2) + Math.pow(points[1]['y'] - points[0][
  677. 'y'
  678. ], 2));
  679. // 邻控制BC点间距
  680. const DIST_BC = Math.sqrt(Math.pow(points[2]['x'] - points[1]['x'], 2) + Math.pow(points[2]['y'] - points[1][
  681. 'y'
  682. ], 2));
  683. // D每次在AB方向上移动的距离
  684. if (points[0]['x'] > points[2]['x']) {
  685. var EACH_MOVE_AD = -(DIST_AB / times);
  686. // E每次在BC方向上移动的距离
  687. var EACH_MOVE_BE = -(DIST_BC / times);
  688. } else {
  689. var EACH_MOVE_AD = +(DIST_AB / times);
  690. // E每次在BC方向上移动的距离
  691. var EACH_MOVE_BE = +(DIST_BC / times);
  692. }
  693. // 点AB的正切
  694. const TAN_AB = (points[1]['y'] - points[0]['y']) / (points[1]['x'] - points[0]['x']);
  695. // 点BC的正切
  696. const TAN_BC = (points[2]['y'] - points[1]['y']) / (points[2]['x'] - points[1]['x']);
  697. // 点AB的弧度值
  698. const RADIUS_AB = Math.atan(TAN_AB);
  699. // 点BC的弧度值
  700. const RADIUS_BC = Math.atan(TAN_BC);
  701. // 每次执行
  702. for (var i = 1; i <= times; i++) {
  703. // AD的距离
  704. var dist_AD = EACH_MOVE_AD * i;
  705. // BE的距离
  706. var dist_BE = EACH_MOVE_BE * i;
  707. // D点的坐标
  708. var point_D = {};
  709. point_D['x'] = dist_AD * Math.cos(RADIUS_AB) + points[0]['x'];
  710. point_D['y'] = dist_AD * Math.sin(RADIUS_AB) + points[0]['y'];
  711. points_D.push(point_D);
  712. // E点的坐标
  713. var point_E = {};
  714. point_E['x'] = dist_BE * Math.cos(RADIUS_BC) + points[1]['x'];
  715. point_E['y'] = dist_BE * Math.sin(RADIUS_BC) + points[1]['y'];
  716. points_E.push(point_E);
  717. // 此时线段DE的正切值
  718. var tan_DE = (point_E['y'] - point_D['y']) / (point_E['x'] - point_D['x']);
  719. // tan_DE的弧度值
  720. var radius_DE = Math.atan(tan_DE);
  721. // 地市DE的间距
  722. var dist_DE = Math.sqrt(Math.pow((point_E['x'] - point_D['x']), 2) + Math.pow((point_E['y'] - point_D['y']),
  723. 2));
  724. // 此时DF的距离
  725. var dist_DF = (dist_AD / DIST_AB) * dist_DE;
  726. // 此时DF点的坐标
  727. var point_F = {};
  728. point_F['x'] = dist_DF * Math.cos(radius_DE) + point_D['x'];
  729. point_F['y'] = dist_DF * Math.sin(radius_DE) + point_D['y'];
  730. bezier_points.push(point_F);
  731. }
  732. return {
  733. 'bezier_points': bezier_points
  734. };
  735. }
  736. }