Style.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. export class Style {
  2. static init() {
  3. if ( document.getElementById( 'profiler-styles' ) ) return;
  4. const css = `
  5. :root {
  6. --profiler-bg: #1e1e24f5;
  7. --profiler-header-bg: #2a2a33aa;
  8. --profiler-header: #2a2a33;
  9. --profiler-border: #4a4a5a;
  10. --text-primary: #e0e0e0;
  11. --text-secondary: #9a9aab;
  12. --accent-color: #00aaff;
  13. --color-green: #4caf50;
  14. --color-yellow: #ffc107;
  15. --color-red: #f44336;
  16. --font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  17. --font-mono: 'Fira Code', 'Courier New', Courier, monospace;
  18. }
  19. @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Fira+Code&display=swap');
  20. #profiler-panel *, #profiler-toggle * {
  21. text-transform: initial;
  22. line-height: normal;
  23. box-sizing: border-box;
  24. -webkit-font-smoothing: antialiased;
  25. -moz-osx-font-smoothing: grayscale;
  26. }
  27. #profiler-toggle {
  28. position: fixed;
  29. top: 15px;
  30. right: 15px;
  31. background-color: rgba(30, 30, 36, 0.85);
  32. border: 1px solid #4a4a5a54;
  33. border-radius: 6px 12px 12px 6px;
  34. color: var(--text-primary);
  35. cursor: pointer;
  36. z-index: 1001;
  37. transition: all 0.2s ease-in-out;
  38. font-size: 14px;
  39. backdrop-filter: blur(8px);
  40. box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
  41. display: flex;
  42. align-items: stretch;
  43. padding: 0;
  44. overflow: hidden;
  45. font-family: var(--font-family);
  46. }
  47. #profiler-toggle:hover {
  48. border-color: var(--accent-color);
  49. }
  50. #profiler-toggle.hidden {
  51. opacity: 0;
  52. pointer-events: none;
  53. }
  54. #toggle-icon {
  55. display: flex;
  56. align-items: center;
  57. justify-content: center;
  58. width: 40px;
  59. font-size: 20px;
  60. transition: background-color 0.2s;
  61. }
  62. #profiler-toggle:hover #toggle-icon {
  63. background-color: rgba(255, 255, 255, 0.05);
  64. }
  65. .toggle-separator {
  66. width: 1px;
  67. background-color: var(--profiler-border);
  68. }
  69. #toggle-text {
  70. display: flex;
  71. align-items: baseline;
  72. padding: 8px 14px;
  73. min-width: 80px;
  74. justify-content: right;
  75. }
  76. #toggle-text .fps-label {
  77. font-size: 0.7em;
  78. margin-left: 10px;
  79. color: #999;
  80. }
  81. #profiler-panel {
  82. position: fixed;
  83. z-index: 1001 !important;
  84. bottom: 0;
  85. left: 0;
  86. right: 0;
  87. height: 350px;
  88. background-color: var(--profiler-bg);
  89. backdrop-filter: blur(8px);
  90. border-top: 2px solid var(--profiler-border);
  91. color: var(--text-primary);
  92. display: flex;
  93. flex-direction: column;
  94. z-index: 1000;
  95. /*box-shadow: 0 -5px 25px rgba(0, 0, 0, 0.5);*/
  96. transform: translateY(100%);
  97. transition: transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), height 0.3s ease-out;
  98. font-family: var(--font-mono);
  99. }
  100. #profiler-panel.resizing {
  101. transition: none;
  102. }
  103. #profiler-panel.visible {
  104. transform: translateY(0);
  105. }
  106. #profiler-panel.maximized {
  107. height: 100vh;
  108. }
  109. .panel-resizer {
  110. position: absolute;
  111. top: -2px;
  112. left: 0;
  113. width: 100%;
  114. height: 5px;
  115. cursor: ns-resize;
  116. z-index: 1001;
  117. }
  118. .profiler-header {
  119. display: flex;
  120. background-color: var(--profiler-header-bg);
  121. border-bottom: 1px solid var(--profiler-border);
  122. flex-shrink: 0;
  123. justify-content: space-between;
  124. align-items: stretch;
  125. overflow-x: auto;
  126. overflow-y: hidden;
  127. width: calc(100% - 89px);
  128. height: 38px;
  129. }
  130. .profiler-tabs {
  131. display: flex;
  132. }
  133. .profiler-controls {
  134. display: flex;
  135. position: absolute;
  136. right: 0;
  137. top: 0;
  138. height: 38px;
  139. background: var(--profiler-header-bg);
  140. border-bottom: 1px solid var(--profiler-border);
  141. }
  142. .tab-btn {
  143. background: transparent;
  144. border: none;
  145. /*border-right: 1px solid var(--profiler-border);*/
  146. color: var(--text-secondary);
  147. padding: 8px 18px;
  148. cursor: pointer;
  149. display: flex;
  150. align-items: center;
  151. font-family: var(--font-family);
  152. font-weight: 600;
  153. font-size: 14px;
  154. }
  155. .tab-btn.active {
  156. border-bottom: 2px solid var(--accent-color);
  157. color: white;
  158. }
  159. #maximize-btn,
  160. #hide-panel-btn {
  161. background: transparent;
  162. border: none;
  163. border-left: 1px solid var(--profiler-border);
  164. color: var(--text-secondary);
  165. width: 45px;
  166. cursor: pointer;
  167. transition: all 0.2s;
  168. display: flex;
  169. align-items: center;
  170. justify-content: center;
  171. }
  172. #maximize-btn:hover,
  173. #hide-panel-btn:hover {
  174. background-color: rgba(255, 255, 255, 0.1);
  175. color: var(--text-primary);
  176. }
  177. .profiler-content-wrapper {
  178. flex-grow: 1;
  179. overflow: hidden;
  180. position: relative;
  181. }
  182. .profiler-content {
  183. position: absolute;
  184. top: 0;
  185. left: 0;
  186. width: 100%;
  187. height: 100%;
  188. overflow-y: auto;
  189. font-size: 13px;
  190. visibility: hidden;
  191. opacity: 0;
  192. transition: opacity 0.2s, visibility 0.2s;
  193. box-sizing: border-box;
  194. display: flex;
  195. flex-direction: column;
  196. }
  197. .profiler-content.active {
  198. visibility: visible;
  199. opacity: 1;
  200. }
  201. .profiler-content {
  202. overflow: auto; /* make sure scrollbars can appear */
  203. }
  204. .profiler-content::-webkit-scrollbar {
  205. width: 8px;
  206. height: 8px;
  207. }
  208. .profiler-content::-webkit-scrollbar-track {
  209. background: transparent;
  210. }
  211. .profiler-content::-webkit-scrollbar-thumb {
  212. background-color: rgba(0, 0, 0, 0.25);
  213. border-radius: 10px;
  214. transition: background 0.3s ease;
  215. }
  216. .profiler-content::-webkit-scrollbar-thumb:hover {
  217. background-color: rgba(0, 0, 0, 0.4);
  218. }
  219. .profiler-content::-webkit-scrollbar-corner {
  220. background: transparent;
  221. }
  222. .profiler-content {
  223. scrollbar-width: thin; /* "auto" | "thin" */
  224. scrollbar-color: rgba(0, 0, 0, 0.25) transparent;
  225. }
  226. .list-item-row {
  227. display: grid;
  228. align-items: center;
  229. padding: 4px 8px;
  230. border-radius: 3px;
  231. transition: background-color 0.2s;
  232. gap: 10px;
  233. border-bottom: none;
  234. }
  235. .list-item-wrapper {
  236. margin-top: 2px;
  237. margin-bottom: 2px;
  238. }
  239. .list-item-wrapper:first-child {
  240. /*margin-top: 0;*/
  241. }
  242. .list-item-wrapper:not(.header-wrapper):nth-child(odd) > .list-item-row {
  243. background-color: rgba(0,0,0,0.1);
  244. }
  245. .list-item-wrapper.header-wrapper>.list-item-row {
  246. color: var(--accent-color);
  247. background-color: rgba(0, 170, 255, 0.1);
  248. }
  249. .list-item-wrapper.header-wrapper>.list-item-row>.list-item-cell:first-child {
  250. font-weight: 600;
  251. }
  252. .list-item-row.collapsible,
  253. .list-item-row.actionable {
  254. cursor: pointer;
  255. }
  256. .list-item-row.collapsible {
  257. background-color: rgba(0, 170, 255, 0.15) !important;
  258. }
  259. .list-item-row.collapsible.alert,
  260. .list-item-row.alert {
  261. background-color: rgba(244, 67, 54, 0.1) !important;
  262. }
  263. @media (hover: hover) {
  264. .list-item-row:hover:not(.collapsible):not(.no-hover),
  265. .list-item-row:hover:not(.no-hover),
  266. .list-item-row.actionable:hover,
  267. .list-item-row.collapsible.actionable:hover {
  268. background-color: rgba(255, 255, 255, 0.05) !important;
  269. }
  270. .list-item-row.collapsible:hover {
  271. background-color: rgba(0, 170, 255, 0.25) !important;
  272. }
  273. }
  274. .list-item-cell {
  275. white-space: pre;
  276. display: flex;
  277. align-items: center;
  278. }
  279. .list-item-cell:not(:first-child) {
  280. justify-content: flex-end;
  281. font-weight: 600;
  282. }
  283. .list-header {
  284. display: grid;
  285. align-items: center;
  286. padding: 4px 8px;
  287. font-weight: 600;
  288. color: var(--text-secondary);
  289. padding-bottom: 6px;
  290. border-bottom: 1px solid var(--profiler-border);
  291. margin-bottom: 5px;
  292. gap: 10px;
  293. }
  294. .list-item-wrapper.section-start {
  295. margin-top: 5px;
  296. margin-bottom: 5px;
  297. }
  298. .list-header .list-header-cell:not(:first-child) {
  299. text-align: right;
  300. }
  301. .list-children-container {
  302. padding-left: 1.5em;
  303. overflow: hidden;
  304. transition: max-height 0.1s ease-out;
  305. margin-top: 2px;
  306. }
  307. .list-children-container.closed {
  308. max-height: 0;
  309. }
  310. .item-toggler {
  311. display: inline-block;
  312. margin-right: 0.8em;
  313. text-align: left;
  314. }
  315. .list-item-row.open .item-toggler::before {
  316. content: '-';
  317. }
  318. .list-item-row:not(.open) .item-toggler::before {
  319. content: '+';
  320. }
  321. .list-item-cell .value.good {
  322. color: var(--color-green);
  323. }
  324. .list-item-cell .value.warn {
  325. color: var(--color-yellow);
  326. }
  327. .list-item-cell .value.bad {
  328. color: var(--color-red);
  329. }
  330. .list-scroll-wrapper {
  331. overflow-x: auto;
  332. width: 100%;
  333. }
  334. .list-container.parameters .list-item-row:not(.collapsible) {
  335. height: 31px;
  336. }
  337. .graph-container {
  338. width: 100%;
  339. box-sizing: border-box;
  340. padding: 8px 0;
  341. position: relative;
  342. }
  343. .graph-svg {
  344. width: 100%;
  345. height: 80px;
  346. background-color: var(--profiler-header);
  347. border: 1px solid var(--profiler-border);
  348. border-radius: 4px;
  349. }
  350. .graph-path {
  351. stroke-width: 2;
  352. fill-opacity: 0.4;
  353. }
  354. .console-header {
  355. padding: 10px;
  356. border-bottom: 1px solid var(--profiler-border);
  357. display: flex;
  358. gap: 20px;
  359. flex-shrink: 0;
  360. align-items: center;
  361. justify-content: space-between;
  362. }
  363. .console-filters-group {
  364. display: flex;
  365. gap: 20px;
  366. }
  367. .console-filter-input {
  368. background-color: var(--profiler-bg);
  369. border: 1px solid var(--profiler-border);
  370. color: var(--text-primary);
  371. border-radius: 4px;
  372. padding: 4px 8px;
  373. font-family: var(--font-mono);
  374. flex-grow: 1;
  375. max-width: 300px;
  376. border-radius: 15px;
  377. }
  378. #console-log {
  379. display: flex;
  380. flex-direction: column;
  381. gap: 4px;
  382. padding: 10px;
  383. overflow-y: auto;
  384. flex-grow: 1;
  385. }
  386. .log-message {
  387. padding: 2px 5px;
  388. white-space: pre-wrap;
  389. word-break: break-all;
  390. border-radius: 3px;
  391. line-height: 1.5 !important;
  392. }
  393. .log-message.hidden {
  394. display: none;
  395. }
  396. .log-message.info {
  397. color: var(--text-primary);
  398. }
  399. .log-message.warn {
  400. color: var(--color-yellow);
  401. }
  402. .log-message.error {
  403. color: #f9dedc;
  404. background-color: rgba(244, 67, 54, 0.1);
  405. }
  406. .log-prefix {
  407. color: var(--text-secondary);
  408. margin-right: 8px;
  409. }
  410. .log-code {
  411. background-color: rgba(255, 255, 255, 0.1);
  412. border-radius: 3px;
  413. padding: 1px 4px;
  414. }
  415. .thumbnail-container {
  416. display: flex;
  417. align-items: center;
  418. }
  419. .thumbnail-svg {
  420. width: 40px;
  421. height: 22.5px;
  422. flex-shrink: 0;
  423. margin-right: 8px;
  424. }
  425. .param-control {
  426. display: flex;
  427. align-items: center;
  428. justify-content: flex-end;
  429. gap: 10px;
  430. width: 100%;
  431. }
  432. .param-control input,
  433. .param-control select,
  434. .param-control button {
  435. background-color: var(--profiler-bg);
  436. border: 1px solid var(--profiler-border);
  437. color: var(--text-primary);
  438. border-radius: 4px;
  439. padding: 4px 6px;
  440. padding-bottom: 2px;
  441. font-family: var(--font-mono);
  442. width: 100%;
  443. box-sizing: border-box;
  444. }
  445. .param-control select {
  446. padding-top: 3px;
  447. padding-bottom: 1px;
  448. }
  449. .param-control input[type="number"] {
  450. cursor: ns-resize;
  451. }
  452. .param-control input[type="color"] {
  453. padding: 2px;
  454. }
  455. .param-control button {
  456. cursor: pointer;
  457. transition: background-color 0.2s;
  458. }
  459. .param-control button:hover {
  460. background-color: var(--profiler-header);
  461. }
  462. .param-control-vector {
  463. display: flex;
  464. gap: 5px;
  465. }
  466. .custom-checkbox {
  467. display: inline-flex;
  468. align-items: center;
  469. cursor: pointer;
  470. gap: 8px;
  471. }
  472. .custom-checkbox input {
  473. display: none;
  474. }
  475. .custom-checkbox .checkmark {
  476. width: 14px;
  477. height: 14px;
  478. border: 1px solid var(--profiler-border);
  479. border-radius: 3px;
  480. display: inline-flex;
  481. justify-content: center;
  482. align-items: center;
  483. transition: background-color 0.2s, border-color 0.2s;
  484. }
  485. .custom-checkbox .checkmark::after {
  486. content: '';
  487. width: 8px;
  488. height: 8px;
  489. background-color: var(--accent-color);
  490. border-radius: 1px;
  491. display: block;
  492. transform: scale(0);
  493. transition: transform 0.2s;
  494. }
  495. .custom-checkbox input:checked+.checkmark {
  496. border-color: var(--accent-color);
  497. }
  498. .custom-checkbox input:checked+.checkmark::after {
  499. transform: scale(1);
  500. }
  501. .param-control input[type="range"] {
  502. -webkit-appearance: none;
  503. appearance: none;
  504. width: 100%;
  505. height: 16px;
  506. background: var(--profiler-header);
  507. border-radius: 5px;
  508. border: 1px solid var(--profiler-border);
  509. outline: none;
  510. padding: 0px;
  511. padding-top: 8px;
  512. }
  513. .param-control input[type="range"]::-webkit-slider-thumb {
  514. -webkit-appearance: none;
  515. appearance: none;
  516. width: 18px;
  517. height: 18px;
  518. background: var(--profiler-bg);
  519. border: 1px solid var(--accent-color);
  520. border-radius: 3px;
  521. cursor: pointer;
  522. margin-top: -8px;
  523. }
  524. .param-control input[type="range"]::-moz-range-thumb {
  525. width: 18px;
  526. height: 18px;
  527. background: var(--profiler-bg);
  528. border: 2px solid var(--accent-color);
  529. border-radius: 3px;
  530. cursor: pointer;
  531. }
  532. .param-control input[type="range"]::-moz-range-track {
  533. width: 100%;
  534. height: 16px;
  535. background: var(--profiler-header);
  536. border-radius: 5px;
  537. border: 1px solid var(--profiler-border);
  538. }
  539. @media screen and (max-width: 768px) and (orientation: portrait) {
  540. .console-filter-input {
  541. max-width: 100px;
  542. }
  543. }
  544. `;
  545. const styleElement = document.createElement( 'style' );
  546. styleElement.id = 'profiler-styles';
  547. styleElement.textContent = css;
  548. document.head.appendChild( styleElement );
  549. }
  550. }
粤ICP备19079148号