settings.html 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <style>
  2. .settings > label:first-child {
  3. font-weight: bold;
  4. }
  5. #export-clips {
  6. margin-right: auto;
  7. }
  8. section.settings .hbox {
  9. display: flex;
  10. align-items: center;
  11. }
  12. section.settings .hbox > * + * {
  13. margin-left: .25em;
  14. }
  15. #import-export {
  16. margin-top: .5em;
  17. margin-bottom: .5em;
  18. }
  19. section.settings .hbox h2 {
  20. margin: 0px;
  21. margin-right: auto;
  22. }
  23. .example {
  24. align-items: center;
  25. }
  26. section.settings select {
  27. width: 50ch;
  28. flex-shrink: 1;
  29. }
  30. </style>
  31. <section class="settings">
  32. <h2>Your Data</h2>
  33. <div id="import-export" class="hbox">
  34. <button id="export-clips">Export</button>
  35. <input type="file" id="import-clips-file"/>
  36. <button id="import-clips">Import</button>
  37. </div>
  38. <script>
  39. $('#export-clips').addEventListener('click', evt => {
  40. let cloneClips = JSON.parse(JSON.stringify(globalState.get('clips')));
  41. for (let clip of cloneClips) delete clip.marker;
  42. downloadFile('data:text/json;charset=utf-8,' + encodeURIComponent(
  43. JSON.stringify(cloneClips)
  44. ), 'clips.json');
  45. });
  46. $('#import-clips').addEventListener('click', evt => {
  47. if ($('#import-clips-file').files.length > 0) {
  48. let reader = new FileReader();
  49. reader.onload = evt => {
  50. let loadedClips = JSON.parse(evt.target.result);
  51. globalState.set('clips', loadedClips);
  52. globalState.set('playingClip', last(loadedClips));
  53. globalState.set('previewClip', last(loadedClips));
  54. }
  55. reader.readAsText($('#import-clips-file').files[0]);
  56. } else {
  57. alert('You need to select the file containing your exported data.');
  58. }
  59. });
  60. </script>
  61. <hr>
  62. <div class="hbox examples">
  63. <h2>Examples</h2>
  64. <button id="load-default-clips" onclick="loadDefaultClips()">Reload Defaults</button>
  65. <button id="load-extended-clips" onclick="loadExtendedClips()">Load Extended</button>
  66. </div>
  67. <p>Warning: The extended set of examples may use large amounts of data.</p>
  68. <hr>
  69. <h2>Theme</h2>
  70. <select id="theme-select">
  71. <option value="Deep Dark">Deep Dark</option>
  72. <option value="Light Blue">Light Blue</option>
  73. <option value="Light Red">Light Red</option>
  74. <option value="Popular">Popular</option>
  75. <option value="Pinkin Blue">Pinkin Blue</option>
  76. <option value="Pink Pank">Pink Pank</option>
  77. <option value="80s">80's</option>
  78. <option value="90s">90's</option>
  79. <option value="00s">00's</option>
  80. <option value="10s">10's</option>
  81. <option value="custom">Custom</option>
  82. <select>
  83. <br>
  84. <br>
  85. <details id="set-colors">
  86. <summary>Customize</summary>
  87. Rounded Corners:
  88. <input type="range" value="15" id="border-radius" />
  89. <br>
  90. Shadow Strength:
  91. <input type="range" value="5" id="box-shadow-strength" class="proportion" />
  92. <br>
  93. Shadow Spread:
  94. <input type="range" value="15" id="box-shadow-spread" />
  95. <br>
  96. Highlight Strength:
  97. <input type="range" value="0" id="highlight-strength" class="proportion" />
  98. <br>
  99. <br>
  100. <input type="color" id="body-background" >
  101. <label for="body-background">background color</label>
  102. <br>
  103. <input type="color" id="body-color" >
  104. <label for="body-color">text color</label>
  105. <br>
  106. <input type="color" id="chrome-color" >
  107. <label for="chrome-color">chrome color</label>
  108. <br>
  109. <input type="color" id="chrome-background" >
  110. <label for="chrome-background">chrome background</label>
  111. <br>
  112. <input type="color" id="chrome-border" >
  113. <label for="chrome-border">chrome border</label>
  114. <br>
  115. <input type="color" id="accent" >
  116. <label for="accent">accent</label>
  117. <br>
  118. <input type="color" id="accent-text" >
  119. <label for="accent">accent text</label>
  120. <br>
  121. <input type="color" id="button-color" >
  122. <label for="button-color">button color</label>
  123. <br>
  124. <input type="color" id="button-background" >
  125. <label for="button-background">button background</label>
  126. <br>
  127. <input type="color" id="input-color" >
  128. <label for="input-color">input color</label>
  129. <br>
  130. <input type="color" id="input-background" >
  131. <label for="input-background">input background</label>
  132. <br>
  133. </details>
  134. <script>
  135. let themeState = new StateManager();
  136. let themes = {% include 'themes.json' %};
  137. let theme = $('#theme-select').value;
  138. loadTheme(themes[theme]);
  139. for (let colorSelect of $$('#set-colors > input[type=color]')) {
  140. if (!themeState.state.hasOwnProperty(colorSelect.id)) {
  141. themeState.init(colorSelect.id, null);
  142. }
  143. themeState.render([colorSelect.id], current => {
  144. document.body.style.setProperty('--' + colorSelect.id, current[colorSelect.id]);
  145. });
  146. }
  147. for (let colorSelect of $$('#set-colors > input[type=color]')) {
  148. themeState.sync(colorSelect.id, colorSelect, 'value');
  149. themeState.set(colorSelect.id, colorSelect.value);
  150. colorSelect.addEventListener('change', evt => {
  151. $('#theme-select').value = 'custom';
  152. });
  153. }
  154. for (let select of $$('#set-colors > input[type=range]')) {
  155. themeState.sync(select.id, select, 'value');
  156. select.addEventListener('change', evt => {
  157. $('#theme-select').value = 'custom';
  158. });
  159. }
  160. for (let select of $$('#set-colors > input[type=range]')) {
  161. themeState.render([select.id], current => {
  162. if (select.classList.contains('proportion')) {
  163. document.body.style.setProperty('--' + select.id, current[select.id] / 100);
  164. }
  165. if (select.id == 'border-radius') {
  166. document.body.style.setProperty('--' + select.id, (current[select.id] / 50) + 'em');
  167. }
  168. if (select.id == 'box-shadow-spread') {
  169. document.body.style.setProperty('--' + select.id, (current[select.id] / 100) * 10 + 'px');
  170. }
  171. });
  172. }
  173. function doLoadTheme(theme) {
  174. if (themes[theme]) {
  175. loadTheme(themes[theme]);
  176. } else {
  177. setTimeout(() => doLoadTheme(theme), 1000);
  178. }
  179. }
  180. $('#theme-select').addEventListener('change', evt => {
  181. let theme = $('#theme-select').value;
  182. doLoadTheme(theme);
  183. });
  184. for (let colorSelect of $$('#set-colors > input[type=color]')) {
  185. if (!themeState.state.hasOwnProperty(colorSelect.id)) {
  186. themeState.init(colorSelect.id, current[colorSelect.id]);
  187. }
  188. themeState.render([colorSelect.id], current => {
  189. document.body.style.setProperty('--' + colorSelect.id, current[colorSelect.id]);
  190. });
  191. }
  192. theme = $('#theme-select').value;
  193. loadTheme(themes[theme]);
  194. function nativeWidgets() {$('body').classList.remove('custom-widgets')};
  195. function customWidgets() {$('body').classList.add('custom-widgets')};
  196. function recordTheme() {
  197. let theme = {};
  198. for (let key in themeState.state) {
  199. theme[key] = themeState.get(key);
  200. }
  201. alert(JSON.stringify(theme));
  202. }
  203. function loadTheme(theme) {
  204. for (let key in theme) {
  205. if (themeState.state.hasOwnProperty(key)) {
  206. themeState.set(key, theme[key]);
  207. } else {
  208. themeState.init(key, theme[key]);
  209. }
  210. }
  211. }
  212. function nativeStyle() {
  213. whiteLight();
  214. document.body.style.setProperty('--body-background', 'White');
  215. document.body.style.setProperty('--body-color', 'Black');
  216. document.body.style.setProperty('--chrome-color', 'WindowText');
  217. document.body.style.setProperty('--chrome-background', 'Window');
  218. document.body.style.setProperty('--chrome-border', 'ButtonShadow');
  219. document.body.style.setProperty('--accent', 'Highlight');
  220. document.body.style.setProperty('--button-color', 'ButtonText');
  221. document.body.style.setProperty('--button-background', 'ButtonFace');
  222. document.body.style.setProperty('--input-color', '#000000');
  223. document.body.style.setProperty('--border-radius', 15 / 50 + "em");
  224. document.body.style.setProperty('--box-shadow-spread', .50 * 10 + "px");
  225. document.body.style.setProperty('--box-shadow-strength', '0.05');
  226. document.body.style.setProperty('--highlight-strength', '0');
  227. document.querySelector('input.highlight-strength').value = '0';
  228. nativeWidgets();
  229. }
  230. </script>
  231. </section>