Common.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. import * as THREE from "../../../libs/three.js/build/three.module.js";
  2. var Common = {
  3. /* sortByScore: function(list, request, rank){
  4. var i = request ? Common.filterAll(list, request) : list
  5. return 0 === i.length ? null : i = i.map(function(e) {
  6. return {
  7. item: e,
  8. score: rank.reduce(function(t, i) {
  9. return t + i(e)
  10. }, 0)
  11. }
  12. }).sort(function(e, t) {
  13. return t.score - e.score;
  14. })
  15. } */
  16. sortByScore: function(list, request, rank){
  17. var i = request ? Common.filterAll(list, request) : list
  18. return 0 === i.length ? null : i = i.map(function(e) {
  19. let scores = rank.map(function(f){return f(e)}) //add
  20. return {
  21. item: e,
  22. scores,
  23. score: scores.reduce(function(t, i) {
  24. return t + i
  25. }, 0)
  26. }
  27. }).sort(function(e, t) {
  28. return t.score - e.score;
  29. })
  30. }
  31. ,
  32. filterAll: function(e, t) {
  33. return e.filter(function (e) {
  34. return t.every(function (t) {
  35. return t(e)
  36. })
  37. })
  38. },
  39. //---------------
  40. find : function(list, request, rank, sortByScore ) {
  41. if(sortByScore){
  42. var r = this.sortByScore(list, request, rank)
  43. return r && r[0] && r[0].item
  44. }else{
  45. var i = request ? Common.filterAll(list, request) : list
  46. return 0 === i.length ? null : (rank && rank.forEach(function(e) {
  47. i = Common.stableSort(i, e)
  48. }),
  49. i[0])
  50. }
  51. }
  52. ,
  53. stableSort: function(e, f) {//用到排序函数,涉及到两个item相减
  54. return e.map(function(e, i) {
  55. return {
  56. value: e,
  57. index: i
  58. }
  59. }).sort(function(e, u) {
  60. var n = f(e.value, u.value);
  61. return 0 !== n ? n : e.index - u.index //似乎就是加多了这一步:若差距为0,按照原顺序
  62. }).map(function(e) {
  63. return e.value
  64. })
  65. },
  66. average: function (e, t) {
  67. if (0 === e.length)
  68. return null;
  69. for (var i = 0, n = 0, r = 0; r < e.length; r++) {
  70. var o = t ? e[r][t] : e[r];
  71. i += o,
  72. n++
  73. }
  74. return i / n
  75. },
  76. //---------------------------
  77. getMixedSet : function(arr1, arr2){//交集
  78. return arr1.filter(item=>arr2.includes(item));
  79. },
  80. getUnionSet : function(arr1, arr2){//并集
  81. return arr1.concat(arr2.filter(item=>!arr1.includes(item)))
  82. },
  83. getDifferenceSet : function(arr1, arr2){//差集 不能识别重复的,如getDifferenceSet([1,2,2],[1,1,2]) 为空
  84. var arr11 = arr1.filter(item=>!arr2.includes(item));
  85. var arr22 = arr2.filter(item=>!arr1.includes(item));
  86. return arr11.concat(arr22)
  87. },
  88. getDifferenceSetMuti : function(arr){//收集绝对没有重复的元素,也就是判断出现次数=1的
  89. var set = [];
  90. arr.forEach(arr1=>{
  91. arr1.forEach(item=>{
  92. var index = set.indexOf(item)
  93. if(index>-1){
  94. set.splice(index, 1)
  95. }else{
  96. set.push(item)
  97. }
  98. })
  99. })
  100. return set;
  101. }
  102. ,
  103. CloneJson : function(data){
  104. var str = JSON.stringify(data)
  105. return JSON.parse(str)
  106. }
  107. ,
  108. CloneObject : function(copyObj, result, isSimpleCopy, simpleCopyList=[]) {
  109. //isSimpleCopy 只复制最外层
  110. //复制json result的可能:普通数字或字符串、普通数组、复杂对象
  111. simpleCopyList.push(THREE.Object3D) //遇到simpleCopyList中的类直接使用不拷贝
  112. if(!copyObj || typeof copyObj == 'number' || typeof copyObj == 'string' || copyObj instanceof Function || simpleCopyList.some(className => copyObj instanceof className)){
  113. return copyObj
  114. }
  115. result = result || {};
  116. if (copyObj instanceof Array) {
  117. return copyObj.map(e=>{
  118. return this.CloneObject(e)
  119. })
  120. }else{
  121. if(copyObj.clone instanceof Function ){ //解决一部分
  122. return copyObj.clone()
  123. }
  124. }
  125. for (var key in copyObj) {
  126. if (copyObj[key] instanceof Object && !isSimpleCopy)
  127. result[key] = this.CloneObject(copyObj[key]);
  128. else
  129. result[key] = copyObj[key];
  130. //如果是函数类同基本数据,即复制引用
  131. }
  132. return result;
  133. }
  134. ,
  135. CloneClassObject :function(copyObj ){//复杂类对象
  136. var newobj = new copyObj.constructor();
  137. this.CopyClassObject(newobj, copyObj)
  138. return newobj
  139. }
  140. ,
  141. CopyClassObject :function(targetObj, copyObj){//复杂类对象
  142. for(let i in copyObj){
  143. if(i in copyObj.__proto__)break; //到函数了跳出
  144. targetObj[i] = this.CloneObject(copyObj[i], null )
  145. /* else if(copyObj[i].clone instanceof Function ){
  146. targetObj[i] = copyObj[i].clone()
  147. }else{
  148. targetObj[i] = copyObj[i];
  149. } */
  150. }
  151. }
  152. ,
  153. ifSame : function(object1, object2, simpleEqualClass=[]){ //对于复杂的类对象,若能简单判断就直接写进simpleEqualClass
  154. if(object1 == object2 )return true // 0 != undefined , 0 == ''
  155. else if(!object1 || !object2) return false
  156. else if(object1.constructor != object2.constructor){
  157. return false
  158. }else if(simpleEqualClass.some(className => object1 instanceof className)){
  159. return object1 == object2
  160. }else if(object1 instanceof Array ) {
  161. if(object1.length != object2.length)return false;
  162. var _object2 = object2.slice(0);
  163. for(let i=0;i<object1.length;i++){
  164. var u = _object2.find(e=>Common.ifSame(object1[i], e, simpleEqualClass));
  165. if(u == void 0 && !_object2.includes(u) && !object1.includes(u))return false;
  166. else{
  167. let index = _object2.indexOf(u);
  168. _object2.splice(index,1);
  169. }
  170. }
  171. return true
  172. }else if(object1.equals instanceof Function ){//复杂数据仅支持这种,其他的可能卡住?
  173. return object1.equals(object2)
  174. }else if(typeof object1 == 'number' || typeof object1 == 'string'){
  175. if(isNaN(object1) && isNaN(object2))return true
  176. else return object1 == object2
  177. }else if(typeof object1 == "object"){
  178. var keys1 = Object.keys(object1)
  179. var keys2 = Object.keys(object2)
  180. if(!Common.ifSame(keys1,keys2,simpleEqualClass))return false;
  181. for(let i in object1){
  182. var same = Common.ifSame(object1[i], object2[i],simpleEqualClass);
  183. if(!same)return false
  184. }
  185. return true
  186. }else{
  187. console.log('isSame出现例外')
  188. }
  189. }
  190. ,
  191. replaceAll : function (str, f, e) {
  192. //f全部替换成e
  193. var reg = new RegExp(f, "g"); //创建正则RegExp对象
  194. return str.replace(reg, e);
  195. }
  196. ,
  197. downloadFile : function(data, filename, cb) {
  198. var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
  199. save_link.href = data;
  200. save_link.download = filename;
  201. var event = document.createEvent('MouseEvents');
  202. event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  203. save_link.dispatchEvent(event);
  204. cb && cb();
  205. },
  206. intervalTool:{ //延时update,防止卡顿
  207. list:[],
  208. isWaiting:function(name, func, delayTime){
  209. if(!this.list.includes(name)){ //如果没有该项, 则开始判断
  210. var needWait = func(); //触发了改变,则等待一段时间后再自动判断
  211. if(needWait){
  212. this.list.push(name);
  213. setTimeout(()=>{
  214. var a = this.list.indexOf(name);
  215. this.list.splice(a,1);
  216. this.isWaiting(name, func, delayTime) //循环
  217. },delayTime)
  218. }
  219. }
  220. },
  221. /* wait:function(name, delayTime){
  222. this.list.push(name);
  223. setTimeout(()=>{
  224. },delayTime)
  225. }, */
  226. }
  227. ,
  228. pushToGroupAuto : function(items, groups, recognizeFunction){//自动分组。 items是将分到一起的组合。items.length = 1 or 2.
  229. recognizeFunction = recognizeFunction || function(){}
  230. var atGroups = groups.filter(group=>group.find(
  231. item => items[0] == item || recognizeFunction(item, items[0]) || items[1] == item || items[1] && recognizeFunction(item, items[1])
  232. ))
  233. if(atGroups.length){//在不同组
  234. //因为items是一组的,所以先都放入组1
  235. items.forEach(item=> {if(!atGroups[0].includes(item)) atGroups[0].push(item);})
  236. if(atGroups.length>1){//如果在不同组,说明这两个组需要合并
  237. var combineGroup = []
  238. atGroups.forEach(group=>{
  239. combineGroup = Common.getUnionSet(combineGroup, group)
  240. groups.splice(groups.indexOf(group),1)
  241. })
  242. groups.push(combineGroup)
  243. }
  244. }else{//直接加入为一组
  245. groups.push(items)
  246. }
  247. },
  248. getBestCount : function(name, minCount=1,maxCount=6, durBound1 = 1.2, durBound2 = 8, ifLog){
  249. let timeStamp = performance.getEntriesByName("loop-start");
  250. let count
  251. if(timeStamp.length){
  252. let dur = performance.now() - timeStamp[timeStamp.length-1].startTime;
  253. let k = -(maxCount-minCount)/(durBound2 - durBound1)
  254. let m = maxCount - durBound1 * k
  255. count = THREE.MathUtils.clamp(Math.round(k * dur + m), minCount, maxCount ) //dur在iphoneX中静止有7,pc是2
  256. if(ifLog){//注意,console.log本身用时挺高, 降4倍时可能占用0.5毫秒
  257. name && console.log(name, count , ' ,dur:', dur)
  258. }
  259. }else{
  260. count = maxCount // ?
  261. }
  262. //主要在手机端有效果。
  263. return count
  264. },
  265. batchHandling : {//分批处理
  266. lists:[],
  267. getSlice : function(name, items , {stopWhenAllUsed, min=5,max=100, durBound1 , durBound2 }){
  268. if(!this.lists[name]) this.lists[name] = {list:[] }
  269. //更新列表项目,但不变原来的顺序
  270. let list = this.lists[name].list.filter(a=>items.some(item=>a.item == item))//去掉已经不在items里的项目
  271. this.lists[name].list = list
  272. items.forEach(item=>{//增加新的项目。
  273. if(!list.some(a=>a.item == item)){
  274. list.push({item, count:0})
  275. }
  276. })
  277. //至此,在后排的都是未使用的
  278. const maxUseCount = Common.getBestCount(name, min,max , durBound1, durBound2 /* , true */ ) ; //本次最多可以使用的个数
  279. let unUsed = list.filter(e=>e.count == 0)//未使用的项目(count为0)优先
  280. let result = []
  281. unUsed.slice(0,maxUseCount).forEach(e=>{
  282. result.push(e.item);
  283. e.count ++;
  284. })
  285. if(unUsed.length > maxUseCount){
  286. //还是剩有未使用的项目,等待下一次
  287. }else{
  288. //所有项目都能使用一次
  289. if(!stopWhenAllUsed){ //若不是全部使用就停止
  290. let wholeCount = Math.min(items.length, maxUseCount);
  291. let restCount = wholeCount - result.length; //补齐
  292. list.slice(0,restCount).forEach(e=>{
  293. result.push(e.item);
  294. e.count ++;
  295. })
  296. }
  297. list.forEach(e=>e.count--) //复原,等待新的循环
  298. }
  299. return {list:result }
  300. }
  301. },
  302. }
  303. Potree.Common = Common
  304. export default Common