├── LICENSE ├── README.md ├── color-palettes.json ├── demo.png ├── index.html ├── lib ├── WebMencoder.js └── download.js ├── random.js ├── randomart-eval.js ├── randomart-glsl.js ├── randomart.js └── render-test.html /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # randomart 2 | 3 | [![LIVE DEMO](https://github.com/vshymanskyy/miband-js/raw/master/public/live-demo-btn.png)](https://vshymanskyy.github.io/randomart/) 4 | 5 | ![demo](https://github.com/vshymanskyy/randomart/raw/master/demo.png) 6 | 7 | Based on Andrej Bauer's [random-art](http://math.andrej.com/2010/04/21/random-art-in-python/) 8 | -------------------------------------------------------------------------------- /color-palettes.json: -------------------------------------------------------------------------------- 1 | [["#69D2E7","#A7DBD8","#E0E4CC","#F38630","#FA6900"],["#FE4365","#FC9D9A","#F9CDAD","#C8C8A9","#83AF9B"],["#ECD078","#D95B43","#C02942","#542437","#53777A"],["#556270","#4ECDC4","#C7F464","#FF6B6B","#C44D58"],["#774F38","#E08E79","#F1D4AF","#ECE5CE","#C5E0DC"],["#E8DDCB","#CDB380","#036564","#033649","#031634"],["#490A3D","#BD1550","#E97F02","#F8CA00","#8A9B0F"],["#594F4F","#547980","#45ADA8","#9DE0AD","#E5FCC2"],["#00A0B0","#6A4A3C","#CC333F","#EB6841","#EDC951"],["#E94E77","#D68189","#C6A49A","#C6E5D9","#F4EAD5"],["#D9CEB2","#948C75","#D5DED9","#7A6A53","#99B2B7"],["#FFFFFF","#CBE86B","#F2E9E1","#1C140D","#CBE86B"],["#EFFFCD","#DCE9BE","#555152","#2E2633","#99173C"],["#3FB8AF","#7FC7AF","#DAD8A7","#FF9E9D","#FF3D7F"],["#343838","#005F6B","#008C9E","#00B4CC","#00DFFC"],["#413E4A","#73626E","#B38184","#F0B49E","#F7E4BE"],["#99B898","#FECEA8","#FF847C","#E84A5F","#2A363B"],["#FF4E50","#FC913A","#F9D423","#EDE574","#E1F5C4"],["#554236","#F77825","#D3CE3D","#F1EFA5","#60B99A"],["#351330","#424254","#64908A","#E8CAA4","#CC2A41"],["#00A8C6","#40C0CB","#F9F2E7","#AEE239","#8FBE00"],["#FF4242","#F4FAD2","#D4EE5E","#E1EDB9","#F0F2EB"],["#655643","#80BCA3","#F6F7BD","#E6AC27","#BF4D28"],["#8C2318","#5E8C6A","#88A65E","#BFB35A","#F2C45A"],["#FAD089","#FF9C5B","#F5634A","#ED303C","#3B8183"],["#BCBDAC","#CFBE27","#F27435","#F02475","#3B2D38"],["#D1E751","#FFFFFF","#000000","#4DBCE9","#26ADE4"],["#FF9900","#424242","#E9E9E9","#BCBCBC","#3299BB"],["#5D4157","#838689","#A8CABA","#CAD7B2","#EBE3AA"],["#5E412F","#FCEBB6","#78C0A8","#F07818","#F0A830"],["#EEE6AB","#C5BC8E","#696758","#45484B","#36393B"],["#1B676B","#519548","#88C425","#BEF202","#EAFDE6"],["#F8B195","#F67280","#C06C84","#6C5B7B","#355C7D"],["#452632","#91204D","#E4844A","#E8BF56","#E2F7CE"],["#F04155","#FF823A","#F2F26F","#FFF7BD","#95CFB7"],["#F0D8A8","#3D1C00","#86B8B1","#F2D694","#FA2A00"],["#2A044A","#0B2E59","#0D6759","#7AB317","#A0C55F"],["#67917A","#170409","#B8AF03","#CCBF82","#E33258"],["#B9D7D9","#668284","#2A2829","#493736","#7B3B3B"],["#BBBB88","#CCC68D","#EEDD99","#EEC290","#EEAA88"],["#A3A948","#EDB92E","#F85931","#CE1836","#009989"],["#E8D5B7","#0E2430","#FC3A51","#F5B349","#E8D5B9"],["#B3CC57","#ECF081","#FFBE40","#EF746F","#AB3E5B"],["#AB526B","#BCA297","#C5CEAE","#F0E2A4","#F4EBC3"],["#607848","#789048","#C0D860","#F0F0D8","#604848"],["#515151","#FFFFFF","#00B4FF","#EEEEEE"],["#3E4147","#FFFEDF","#DFBA69","#5A2E2E","#2A2C31"],["#300030","#480048","#601848","#C04848","#F07241"],["#1C2130","#028F76","#B3E099","#FFEAAD","#D14334"],["#A8E6CE","#DCEDC2","#FFD3B5","#FFAAA6","#FF8C94"],["#EDEBE6","#D6E1C7","#94C7B6","#403B33","#D3643B"],["#FDF1CC","#C6D6B8","#987F69","#E3AD40","#FCD036"],["#AAB3AB","#C4CBB7","#EBEFC9","#EEE0B7","#E8CAAF"],["#CC0C39","#E6781E","#C8CF02","#F8FCC1","#1693A7"],["#3A111C","#574951","#83988E","#BCDEA5","#E6F9BC"],["#FC354C","#29221F","#13747D","#0ABFBC","#FCF7C5"],["#B9D3B0","#81BDA4","#B28774","#F88F79","#F6AA93"],["#5E3929","#CD8C52","#B7D1A3","#DEE8BE","#FCF7D3"],["#230F2B","#F21D41","#EBEBBC","#BCE3C5","#82B3AE"],["#5C323E","#A82743","#E15E32","#C0D23E","#E5F04C"],["#4E395D","#827085","#8EBE94","#CCFC8E","#DC5B3E"],["#DAD6CA","#1BB0CE","#4F8699","#6A5E72","#563444"],["#C2412D","#D1AA34","#A7A844","#A46583","#5A1E4A"],["#D1313D","#E5625C","#F9BF76","#8EB2C5","#615375"],["#9D7E79","#CCAC95","#9A947C","#748B83","#5B756C"],["#1C0113","#6B0103","#A30006","#C21A01","#F03C02"],["#8DCCAD","#988864","#FEA6A2","#F9D6AC","#FFE9AF"],["#CFFFDD","#B4DEC1","#5C5863","#A85163","#FF1F4C"],["#75616B","#BFCFF7","#DCE4F7","#F8F3BF","#D34017"],["#382F32","#FFEAF2","#FCD9E5","#FBC5D8","#F1396D"],["#B6D8C0","#C8D9BF","#DADABD","#ECDBBC","#FEDCBA"],["#E3DFBA","#C8D6BF","#93CCC6","#6CBDB5","#1A1F1E"],["#A7C5BD","#E5DDCB","#EB7B59","#CF4647","#524656"],["#9DC9AC","#FFFEC7","#F56218","#FF9D2E","#919167"],["#413D3D","#040004","#C8FF00","#FA023C","#4B000F"],["#EDF6EE","#D1C089","#B3204D","#412E28","#151101"],["#A8A7A7","#CC527A","#E8175D","#474747","#363636"],["#7E5686","#A5AAD9","#E8F9A2","#F8A13F","#BA3C3D"],["#FFEDBF","#F7803C","#F54828","#2E0D23","#F8E4C1"],["#C1B398","#605951","#FBEEC2","#61A6AB","#ACCEC0"],["#5E9FA3","#DCD1B4","#FAB87F","#F87E7B","#B05574"],["#951F2B","#F5F4D7","#E0DFB1","#A5A36C","#535233"],["#FFFBB7","#A6F6AF","#66B6AB","#5B7C8D","#4F2958"],["#000000","#9F111B","#B11623","#292C37","#CCCCCC"],["#9CDDC8","#BFD8AD","#DDD9AB","#F7AF63","#633D2E"],["#EFF3CD","#B2D5BA","#61ADA0","#248F8D","#605063"],["#84B295","#ECCF8D","#BB8138","#AC2005","#2C1507"],["#FCFEF5","#E9FFE1","#CDCFB7","#D6E6C3","#FAFBE3"],["#0CA5B0","#4E3F30","#FEFEEB","#F8F4E4","#A5B3AA"],["#4D3B3B","#DE6262","#FFB88C","#FFD0B3","#F5E0D3"],["#B5AC01","#ECBA09","#E86E1C","#D41E45","#1B1521"],["#379F7A","#78AE62","#BBB749","#E0FBAC","#1F1C0D"],["#FFE181","#EEE9E5","#FAD3B2","#FFBA7F","#FF9C97"],["#4E4D4A","#353432","#94BA65","#2790B0","#2B4E72"],["#A70267","#F10C49","#FB6B41","#F6D86B","#339194"],["#30261C","#403831","#36544F","#1F5F61","#0B8185"],["#2D2D29","#215A6D","#3CA2A2","#92C7A3","#DFECE6"],["#F38A8A","#55443D","#A0CAB5","#CDE9CA","#F1EDD0"],["#793A57","#4D3339","#8C873E","#D1C5A5","#A38A5F"],["#11766D","#410936","#A40B54","#E46F0A","#F0B300"],["#AAFF00","#FFAA00","#FF00AA","#AA00FF","#00AAFF"],["#C75233","#C78933","#D6CEAA","#79B5AC","#5E2F46"],["#F8EDD1","#D88A8A","#474843","#9D9D93","#C5CFC6"],["#6DA67A","#77B885","#86C28B","#859987","#4A4857"],["#1B325F","#9CC4E4","#E9F2F9","#3A89C9","#F26C4F"],["#BED6C7","#ADC0B4","#8A7E66","#A79B83","#BBB2A1"],["#046D8B","#309292","#2FB8AC","#93A42A","#ECBE13"],["#82837E","#94B053","#BDEB07","#BFFA37","#E0E0E0"],["#312736","#D4838F","#D6ABB1","#D9D9D9","#C4FFEB"],["#E5EAA4","#A8C4A2","#69A5A4","#616382","#66245B"],["#6DA67A","#99A66D","#A9BD68","#B5CC6A","#C0DE5D"],["#395A4F","#432330","#853C43","#F25C5E","#FFA566"],["#331327","#991766","#D90F5A","#F34739","#FF6E27"],["#FDFFD9","#FFF0B8","#FFD6A3","#FAAD8E","#142F30"],["#E21B5A","#9E0C39","#333333","#FBFFE3","#83A300"],["#FBC599","#CDBB93","#9EAE8A","#335650","#F35F55"],["#C7FCD7","#D9D5A7","#D9AB91","#E6867A","#ED4A6A"],["#EC4401","#CC9B25","#13CD4A","#7B6ED6","#5E525C"],["#BF496A","#B39C82","#B8C99D","#F0D399","#595151"],["#FFEFD3","#FFFEE4","#D0ECEA","#9FD6D2","#8B7A5E"],["#F1396D","#FD6081","#F3FFEB","#ACC95F","#8F9924"],["#F6F6F6","#E8E8E8","#333333","#990100","#B90504"],["#261C21","#6E1E62","#B0254F","#DE4126","#EB9605"],["#E9E0D1","#91A398","#33605A","#070001","#68462B"],["#F2E3C6","#FFC6A5","#E6324B","#2B2B2B","#353634"],["#FFAB07","#E9D558","#72AD75","#0E8D94","#434D53"],["#59B390","#F0DDAA","#E47C5D","#E32D40","#152B3C"],["#FDE6BD","#A1C5AB","#F4DD51","#D11E48","#632F53"],["#E4E4C5","#B9D48B","#8D2036","#CE0A31","#D3E4C5"],["#512B52","#635274","#7BB0A8","#A7DBAB","#E4F5B1"],["#805841","#DCF7F3","#FFFCDD","#FFD8D8","#F5A2A2"],["#E65540","#F8ECC2","#65A8A6","#79896D"],["#CAFF42","#EBF7F8","#D0E0EB","#88ABC2","#49708A"],["#595643","#4E6B66","#ED834E","#EBCC6E","#EBE1C5"],["#E4DED0","#ABCCBD","#7DBEB8","#181619","#E32F21"],["#058789","#503D2E","#D54B1A","#E3A72F","#F0ECC9"],["#FF003C","#FF8A00","#FABE28","#88C100","#00C176"],["#311D39","#67434F","#9B8E7E","#C3CCAF","#A51A41"],["#EFD9B4","#D6A692","#A39081","#4D6160","#292522"],["#C6CCA5","#8AB8A8","#6B9997","#54787D","#615145"],["#CC5D4C","#FFFEC6","#C7D1AF","#96B49C","#5B5847"],["#111625","#341931","#571B3C","#7A1E48","#9D2053"],["#EFEECC","#FE8B05","#FE0557","#400403","#0AABBA"],["#CCF390","#E0E05A","#F7C41F","#FC930A","#FF003D"],["#73C8A9","#DEE1B6","#E1B866","#BD5532","#373B44"],["#79254A","#795C64","#79927D","#AEB18E","#E3CF9E"],["#E0EFF1","#7DB4B5","#FFFFFF","#680148","#000000"],["#F06D61","#DA825F","#C4975C","#A8AB7B","#8CBF99"],["#2D1B33","#F36A71","#EE887A","#E4E391","#9ABC8A"],["#2B2726","#0A516D","#018790","#7DAD93","#BACCA4"],["#95A131","#C8CD3B","#F6F1DE","#F5B9AE","#EE0B5B"],["#360745","#D61C59","#E7D84B","#EFEAC5","#1B8798"],["#E3E8CD","#BCD8BF","#D3B9A3","#EE9C92","#FE857E"],["#807462","#A69785","#B8FAFF","#E8FDFF","#665C49"],["#4B1139","#3B4058","#2A6E78","#7A907C","#C9B180"],["#FC284F","#FF824A","#FEA887","#F6E7F7","#D1D0D7"],["#FFB884","#F5DF98","#FFF8D4","#C0D1C2","#2E4347"],["#027B7F","#FFA588","#D62957","#BF1E62","#572E4F"],["#80A8A8","#909D9E","#A88C8C","#FF0D51","#7A8C89"],["#A69E80","#E0BA9B","#E7A97E","#D28574","#3B1922"],["#A1DBB2","#FEE5AD","#FACA66","#F7A541","#F45D4C"],["#641F5E","#676077","#65AC92","#C2C092","#EDD48E"],["#FFF3DB","#E7E4D5","#D3C8B4","#C84648","#703E3B"],["#F5DD9D","#BCC499","#92A68A","#7B8F8A","#506266"],["#2B222C","#5E4352","#965D62","#C7956D","#F2D974"],["#D4F7DC","#DBE7B4","#DBC092","#E0846D","#F51441"],["#A32C28","#1C090B","#384030","#7B8055","#BCA875"],["#85847E","#AB6A6E","#F7345B","#353130","#CBCFB4"],["#E6B39A","#E6CBA5","#EDE3B4","#8B9E9B","#6D7578"],["#11644D","#A0B046","#F2C94E","#F78145","#F24E4E"],["#6D9788","#1E2528","#7E1C13","#BF0A0D","#E6E1C2"],["#23192D","#FD0A54","#F57576","#FEBF97","#F5ECB7"],["#EB9C4D","#F2D680","#F3FFCF","#BAC9A9","#697060"],["#D3D5B0","#B5CEA4","#9DC19D","#8C7C62","#71443F"],["#452E3C","#FF3D5A","#FFB969","#EAF27E","#3B8C88"],["#041122","#259073","#7FDA89","#C8E98E","#E6F99D"],["#B1E6D1","#77B1A9","#3D7B80","#270A33","#451A3E"],["#9D9E94","#C99E93","#F59D92","#E5B8AD","#D5D2C8"],["#FDCFBF","#FEB89F","#E23D75","#5F0D3B","#742365"],["#540045","#C60052","#FF714B","#EAFF87","#ACFFE9"],["#B7CBBF","#8C886F","#F9A799","#F4BFAD","#F5DABD"],["#280904","#680E34","#9A151A","#C21B12","#FC4B2A"],["#F0FFC9","#A9DA88","#62997A","#72243D","#3B0819"],["#429398","#6B5D4D","#B0A18F","#DFCDB4","#FBEED3"],["#E6EBA9","#ABBB9F","#6F8B94","#706482","#703D6F"],["#A3C68C","#879676","#6E6662","#4F364A","#340735"],["#44749D","#C6D4E1","#FFFFFF","#EBE7E0","#BDB8AD"],["#322938","#89A194","#CFC89A","#CC883A","#A14016"],["#CFB590","#9E9A41","#758918","#564334","#49281F"],["#FA6A64","#7A4E48","#4A4031","#F6E2BB","#9EC6B8"],["#1D1313","#24B694","#D22042","#A3B808","#30C4C9"],["#F6D76B","#FF9036","#D6254D","#FF5475","#FDEBA9"],["#E7EDEA","#FFC52C","#FB0C06","#030D4F","#CEECEF"],["#373737","#8DB986","#ACCE91","#BADB73","#EFEAE4"],["#161616","#C94D65","#E7C049","#92B35A","#1F6764"],["#26251C","#EB0A44","#F2643D","#F2A73D","#A0E8B7"],["#4B3E4D","#1E8C93","#DBD8A2","#C4AC30","#D74F33"],["#8D7966","#A8A39D","#D8C8B8","#E2DDD9","#F8F1E9"],["#F2E8C4","#98D9B6","#3EC9A7","#2B879E","#616668"],["#5CACC4","#8CD19D","#CEE879","#FCB653","#FF5254"]] -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vshymanskyy/randomart/f3a0e9b147cd0d54969a9bac22358d6be9d4c14e/demo.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Random Art 8 | 9 | 10 | 11 | 86 | 87 | 88 | 89 |
90 | Seed: 91 | 92 |
93 | 94 |

95 |
96 | 97 |
98 | 99 | Your browser does not support the HTML5 canvas tag. 100 | 101 |
102 |
103 |
104 | 105 |

106 | 107 | Formula: 108 |
 
109 | 110 | Author: vshymanskyy. 111 | Source code on GitHub.
112 | Based on: Andrej Bauer's random-art. 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /lib/WebMencoder.js: -------------------------------------------------------------------------------- 1 | function EventEmitter() { 2 | let _handlers = {}; 3 | 4 | this.on = function(event, handler) { 5 | _handlers[event] = handler; 6 | }; 7 | 8 | this.emit = function(event) { 9 | let handler = _handlers[event]; 10 | if (handler) { 11 | handler.apply(null, Array.prototype.slice.call(arguments, 1)); 12 | } 13 | }; 14 | } 15 | 16 | class WebMencoder extends EventEmitter { 17 | 18 | constructor(settings) { 19 | super(); 20 | 21 | settings = settings || {}; 22 | this.framerate = settings.framerate || 60; 23 | this.frameLimit = settings.frameLimit; 24 | 25 | this.type = 'video/webm'; 26 | this.extension = '.webm'; 27 | this._init(); 28 | } 29 | 30 | static isSupported() { 31 | return (typeof MediaRecorder !== undefined); 32 | } 33 | 34 | _init() { 35 | this.chunks = []; 36 | this.mediaRecorder = null; 37 | this.stream = null; 38 | this.isRecording = false; 39 | this.frameCount = 0; 40 | } 41 | 42 | start() { 43 | this.isRecording = true; 44 | } 45 | 46 | stop() { 47 | this.isRecording = false; 48 | } 49 | 50 | addFrame( canvas ) { 51 | if (!this.isRecording) return; 52 | 53 | if( !this.stream ) { 54 | this.stream = canvas.captureStream( this.framerate ); 55 | this.mediaRecorder = new MediaRecorder( this.stream, { 56 | mimeType: this.type, 57 | videoBitsPerSecond : 2500000, 58 | }); 59 | this.mediaRecorder.start(); 60 | 61 | this.mediaRecorder.ondataavailable = function(e) { 62 | this.chunks.push(e.data); 63 | }.bind( this ); 64 | 65 | } 66 | this.frameCount++; 67 | 68 | if (this.frameCount >= this.frameLimit) { 69 | this.stop(); 70 | this.emit("stopped") 71 | } 72 | 73 | } 74 | 75 | save( callback ) { 76 | 77 | this.mediaRecorder.onstop = function( e ) { 78 | let blob = new Blob( this.chunks, { 'type' : this.type }); 79 | this._init(); 80 | callback( blob ); 81 | }.bind( this ); 82 | 83 | this.mediaRecorder.stop(); 84 | 85 | 86 | 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /lib/download.js: -------------------------------------------------------------------------------- 1 | //download.js v4.2, by dandavis; 2008-2016. [CCBY2] see http://danml.com/download.html for tests/usage 2 | // v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime 3 | // v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs 4 | // v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling. 5 | // v4 adds AMD/UMD, commonJS, and plain browser support 6 | // v4.1 adds url download capability via solo URL argument (same domain/CORS only) 7 | // v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors 8 | // https://github.com/rndme/download 9 | 10 | (function (root, factory) { 11 | if (typeof define === 'function' && define.amd) { 12 | // AMD. Register as an anonymous module. 13 | define([], factory); 14 | } else if (typeof exports === 'object') { 15 | // Node. Does not work with strict CommonJS, but 16 | // only CommonJS-like environments that support module.exports, 17 | // like Node. 18 | module.exports = factory(); 19 | } else { 20 | // Browser globals (root is window) 21 | root.download = factory(); 22 | } 23 | }(this, function () { 24 | 25 | return function download(data, strFileName, strMimeType) { 26 | 27 | var self = window, // this script is only for browsers anyway... 28 | defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads 29 | mimeType = strMimeType || defaultMime, 30 | payload = data, 31 | url = !strFileName && !strMimeType && payload, 32 | anchor = document.createElement("a"), 33 | toString = function(a){return String(a);}, 34 | myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString), 35 | fileName = strFileName || "download", 36 | blob, 37 | reader; 38 | myBlob= myBlob.call ? myBlob.bind(self) : Blob ; 39 | 40 | if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback 41 | payload=[payload, mimeType]; 42 | mimeType=payload[0]; 43 | payload=payload[1]; 44 | } 45 | 46 | 47 | if(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument 48 | fileName = url.split("/").pop().split("?")[0]; 49 | anchor.href = url; // assign href prop to temp anchor 50 | if(anchor.href.indexOf(url) !== -1){ // if the browser determines that it's a potentially valid url path: 51 | var ajax=new XMLHttpRequest(); 52 | ajax.open( "GET", url, true); 53 | ajax.responseType = 'blob'; 54 | ajax.onload= function(e){ 55 | download(e.target.response, fileName, defaultMime); 56 | }; 57 | setTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return: 58 | return ajax; 59 | } // end if valid url? 60 | } // end if url? 61 | 62 | 63 | //go ahead and download dataURLs right away 64 | if(/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)){ 65 | 66 | if(payload.length > (1024*1024*1.999) && myBlob !== toString ){ 67 | payload=dataUrlToBlob(payload); 68 | mimeType=payload.type || defaultMime; 69 | }else{ 70 | return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs: 71 | navigator.msSaveBlob(dataUrlToBlob(payload), fileName) : 72 | saver(payload) ; // everyone else can save dataURLs un-processed 73 | } 74 | 75 | }//end if dataURL passed? 76 | 77 | blob = payload instanceof myBlob ? 78 | payload : 79 | new myBlob([payload], {type: mimeType}) ; 80 | 81 | 82 | function dataUrlToBlob(strUrl) { 83 | var parts= strUrl.split(/[:;,]/), 84 | type= parts[1], 85 | decoder= parts[2] == "base64" ? atob : decodeURIComponent, 86 | binData= decoder( parts.pop() ), 87 | mx= binData.length, 88 | i= 0, 89 | uiArr= new Uint8Array(mx); 90 | 91 | for(i;i>> 8 ) ^ b_table[( crc ^ str.charCodeAt( i ) ) & 0xFF]; 8 | } 9 | return (crc ^ (-1)) >>> 0; 10 | }; 11 | 12 | 13 | function Alea(seed) { 14 | if(seed === undefined) {seed = +new Date() + Math.random();} 15 | function Mash() { 16 | let n = 4022871197; 17 | return function(r) { 18 | for(let t, s, u = 0, e = 0.02519603282416938; u < r.length; u++) 19 | s = r.charCodeAt(u), f = (e * (n += s) - (n*e|0)), 20 | n = 4294967296 * ((t = f * (e*n|0)) - (t|0)) + (t|0); 21 | return (n|0) * 2.3283064365386963e-10; 22 | } 23 | } 24 | return function() { 25 | let m = Mash(), a = m(" "), b = m(" "), c = m(" "), x = 1, y; 26 | seed = seed.toString(), a -= m(seed), b -= m(seed), c -= m(seed); 27 | a < 0 && a++, b < 0 && b++, c < 0 && c++; 28 | return function() { 29 | let y = x * 2.3283064365386963e-10 + a * 2091639; a = b, b = c; 30 | return c = y - (x = y|0); 31 | }; 32 | }(); 33 | } 34 | 35 | 36 | class Random { 37 | 38 | constructor(seed) { 39 | this.prng = Alea(seed); 40 | } 41 | 42 | uniform(min = 0, max = 1) { 43 | return this.prng() * (max - min) + min; 44 | } 45 | 46 | randrange(min, max) { 47 | if (max !== undefined) { 48 | min = Math.ceil(min); 49 | max = Math.floor(max); 50 | } else { 51 | min = 0; 52 | max = Math.ceil(min); 53 | } 54 | return Math.floor(this.prng() * (max - min)) + min; 55 | } 56 | 57 | choice(arr) { 58 | let idx = this.randrange(0, arr.length) 59 | return arr[idx] 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /randomart-eval.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Pure JS evaluator 3 | */ 4 | 5 | function average(c1, c2, w = 0.5) { 6 | let r1, g1, b1; [r1, g1, b1] = c1; 7 | let r2, g2, b2; [r2, g2, b2] = c2; 8 | let r3 = ((w * r1) + ((1 - w) * r2)); 9 | let g3 = ((w * g1) + ((1 - w) * g2)); 10 | let b3 = ((w * b1) + ((1 - w) * b2)); 11 | return [r3, g3, b3]; 12 | } 13 | 14 | function brightness(R,G,B) { 15 | R = (1.0 + R); 16 | G = (1.0 + G); 17 | B = (1.0 + B); 18 | return Math.sqrt(0.299*(R*R) + 0.587*(G*G) + 0.114*(B*B)) - 1.0; 19 | } 20 | 21 | function well(x) { 22 | return (1 - (2 / Math.pow((1 + (x * x)), 8))); 23 | } 24 | 25 | function tent(x) { 26 | return (1 - (2 * Math.abs(x))); 27 | } 28 | 29 | function modulo(x,y) { 30 | return x - y * Math.floor(x/y); 31 | } 32 | 33 | function BW(v) { return [v,v,v] } 34 | function Const(r,g,b) { return [r,g,b] } 35 | function RGB(c1,c2,c3) { return [brightness(...c1), brightness(...c2), brightness(...c3)] } 36 | 37 | function Sum(c1,c2) { return average(c1,c2) } 38 | function Mul(c1,c2) { 39 | let r1, g1, b1; [r1, g1, b1] = c1; 40 | let r2, g2, b2; [r2, g2, b2] = c2; 41 | return [r1 * r2, g1 * g2, b1 * b2]; 42 | } 43 | function Not(c1) { 44 | let r1, g1, b1; [r1, g1, b1] = c1; 45 | return [-r1, -g1, -b1] 46 | } 47 | function Mod(c1,c2) { 48 | let r1, g1, b1; [r1, g1, b1] = c1; 49 | let r2, g2, b2; [r2, g2, b2] = c2; 50 | 51 | if (r2 === 0 || g2 === 0 || b2 === 0) return [0, 0, 0]; 52 | return [modulo(r1,r2),modulo(g1,g2),modulo(b1,b2)]; 53 | } 54 | 55 | function Tent(c1) { let r,g,b; [r,g,b] = c1; return [tent(r), tent(g), tent(b)] } 56 | function Well(c1) { let r,g,b; [r,g,b] = c1; return [well(r), well(g), well(b)] } 57 | 58 | function Sin(phase,freq,c1) { 59 | let r,g,b; [r,g,b] = c1; 60 | return [Math.sin(phase+freq*r), Math.sin(phase+freq*g), Math.sin(phase+freq*b)] 61 | } 62 | function Mix(w,c1,c2) { 63 | w = brightness(...w); 64 | w = (0.5 * (w + 1.0)); 65 | return average(c1, c2, w); 66 | } 67 | function Level(treshold,level,c1,c2) { 68 | let r1, g1, b1; [r1, g1, b1] = level; 69 | let r2, g2, b2; [r2, g2, b2] = c1; 70 | let r3, g3, b3; [r3, g3, b3] = c2; 71 | 72 | return [ 73 | (r1 < treshold) ? r2 : r3, 74 | (g1 < treshold) ? g2 : g3, 75 | (b1 < treshold) ? b2 : b3 76 | ]; 77 | } 78 | function Closest(tgt,c1,c2) { 79 | let r1, g1, b1; [r1, g1, b1] = tgt; 80 | let r2, g2, b2; [r2, g2, b2] = c1; 81 | let r3, g3, b3; [r3, g3, b3] = c2; 82 | 83 | let d1 = Math.sqrt((r2-r1)**2+(g2-g1)**2+(b2-b1)**2); 84 | let d2 = Math.sqrt((r3-r1)**2+(g3-g1)**2+(b3-b1)**2); 85 | 86 | return (d1 < d2) ? c1 : c2; 87 | } 88 | 89 | function getEvaluator(formula) { 90 | formula = formula.replace(/posX/g, '[x,x,x]'); 91 | formula = formula.replace(/posY/g, '[y,y,y]'); 92 | formula = formula.replace(/frmT/g, '[1,1,1]'); 93 | 94 | return new Function('x', 'y', `return ${formula}`); 95 | } 96 | 97 | async function render_js(canvas, art) { 98 | const size = canvas.width; 99 | const size2 = size/2; 100 | 101 | const ctx = canvas.getContext("2d"); 102 | const imagedata = ctx.createImageData(size, size); 103 | const d = imagedata.data; 104 | 105 | const compute = getEvaluator(art.toString()) 106 | 107 | for (let y=0; y i/size2 - 1.0); 111 | 112 | let color = compute(u, v); 113 | color = color.map(i => (i+1.0) * 128); 114 | 115 | const idx = (y * size + x) * 4; 116 | d[idx] = color[0] 117 | d[idx+1] = color[1] 118 | d[idx+2] = color[2] 119 | d[idx+3] = 0xFF 120 | } 121 | if ((y % 16) == 0) { 122 | ctx.putImageData(imagedata, 0, 0, 0, 0, size, y+2); 123 | await delay(1); 124 | } 125 | } 126 | ctx.putImageData(imagedata, 0, 0); 127 | } 128 | -------------------------------------------------------------------------------- /randomart-glsl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * GLSL evaluator 3 | */ 4 | 5 | const shader_vert = ` 6 | attribute vec2 position; 7 | 8 | void main() { 9 | gl_Position = vec4(position, 0.0, 1.0); 10 | } 11 | `; 12 | 13 | const shader_frag = ` 14 | #ifdef GL_FRAGMENT_PRECISION_HIGH 15 | precision highp float; 16 | #endif 17 | 18 | uniform float size; 19 | uniform float frameT; 20 | 21 | float brightness(vec3 c) { 22 | c += 1.0; 23 | return sqrt(0.299*(c.r*c.r) + 0.587*(c.g*c.g) + 0.114*(c.b*c.b)) - 1.0; 24 | } 25 | 26 | float well(float x) { 27 | return (1.0 - (2.0 / pow((1.0 + (x * x)), float(8.0)))); 28 | } 29 | 30 | float tent(float x) { 31 | return (1.0 - (2.0 * abs(x))); 32 | } 33 | 34 | vec3 Const(float r, float g, float b) { 35 | return vec3(r, g, b); 36 | } 37 | 38 | vec3 BW(float f) { 39 | return vec3(f); 40 | } 41 | 42 | vec3 RGB(vec3 c1, vec3 c2, vec3 c3) { 43 | return vec3(brightness(c1), brightness(c2), brightness(c3)); 44 | } 45 | 46 | vec3 Sum(vec3 c1, vec3 c2) { 47 | return mix(c1, c2, vec3(0.5)); 48 | } 49 | 50 | vec3 Mul(vec3 c1, vec3 c2) { 51 | return c1 * c2; 52 | } 53 | 54 | vec3 Mod(vec3 c1, vec3 c2) { 55 | if (c1 == c2) return vec3(0.0); // Produces aliasing for some reason in this case... 56 | if (c2.r == 0.0 || c2.g == 0.0 || c2.b == 0.0) return vec3(0.0); 57 | return mod(c1,c2); 58 | } 59 | 60 | vec3 Not(vec3 c1) { 61 | return float(-1.0) * c1; 62 | } 63 | 64 | vec3 Well(vec3 c1) { 65 | return vec3(well(c1.r),well(c1.g),well(c1.b)); 66 | } 67 | 68 | vec3 Tent(vec3 c1) { 69 | return vec3(tent(c1.r),tent(c1.g),tent(c1.b)); 70 | } 71 | 72 | vec3 Sin(float phase, float freq, vec3 c1) { 73 | return sin(phase + freq * c1); 74 | } 75 | 76 | vec3 Mix(vec3 w, vec3 c1, vec3 c2) { 77 | float weight = 0.5 * (brightness(w) + 1.0); 78 | return mix(c2,c1,weight); 79 | } 80 | 81 | vec3 Level(float treshold, vec3 level, vec3 c1, vec3 c2) { 82 | float r = ((level.r < treshold) ? c1.r : c2.r); 83 | float g = ((level.g < treshold) ? c1.g : c2.g); 84 | float b = ((level.b < treshold) ? c1.b : c2.b); 85 | return vec3(r,g,b); 86 | } 87 | 88 | vec3 Closest(vec3 tgt, vec3 c1, vec3 c2) { 89 | float d1 = distance(c1, tgt); 90 | float d2 = distance(c2, tgt); 91 | return (d1 < d2) ? c1 : c2; 92 | } 93 | 94 | void main() { 95 | vec2 pos = (gl_FragCoord.xy / size) * float(2.0) - float(1.0); 96 | 97 | vec3 posX = vec3(pos.x); 98 | vec3 posY = vec3(-pos.y); 99 | 100 | vec3 frmT = vec3(frameT); 101 | 102 | vec3 result = $FORMULA; 103 | 104 | vec3 col = result * float(0.5) + float(0.5); 105 | gl_FragColor = vec4(col, 1); 106 | } 107 | `; 108 | 109 | 110 | const canvasGL = document.createElement("canvas"); 111 | const gl = canvasGL.getContext("webgl"); 112 | let animationHandle; 113 | 114 | let frameT = 0; 115 | 116 | function render_glsl(canvas, art, animate = false, oversample = 2) { 117 | const ctx2d = canvas.getContext("2d"); 118 | 119 | if (animationHandle) { 120 | cancelAnimationFrame(animationHandle); 121 | animationHandle = undefined; 122 | } 123 | 124 | const renderW = canvas.width * oversample; 125 | const renderH = canvas.height * oversample; 126 | const aspect = renderW / renderH; 127 | 128 | canvasGL.width = renderW; 129 | canvasGL.height = renderH; 130 | 131 | //createGL_Context(renderW, renderH); 132 | 133 | gl.viewport(0, 0, renderW, renderH); 134 | gl.clearColor(0, 0, 0, 1); 135 | gl.clear(gl.COLOR_BUFFER_BIT); 136 | 137 | var v = shader_vert; 138 | var f = shader_frag.replace('$FORMULA', art.toString()); 139 | 140 | var vs = gl.createShader(gl.VERTEX_SHADER); 141 | gl.shaderSource(vs, v); 142 | gl.compileShader(vs); 143 | 144 | var fs = gl.createShader(gl.FRAGMENT_SHADER); 145 | gl.shaderSource(fs, f); 146 | gl.compileShader(fs); 147 | 148 | program = gl.createProgram(); 149 | gl.attachShader(program, vs); 150 | gl.attachShader(program, fs); 151 | gl.linkProgram(program); 152 | 153 | if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { 154 | console.log(gl.getShaderInfoLog(vs)); 155 | return; 156 | } 157 | 158 | if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { 159 | console.log(gl.getShaderInfoLog(fs)); 160 | return; 161 | } 162 | 163 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 164 | console.log(gl.getProgramInfoLog(program)); 165 | return; 166 | } 167 | 168 | const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]); 169 | 170 | const buffer = gl.createBuffer(); 171 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 172 | gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); 173 | 174 | const itemSize = 2; 175 | const numItems = vertices.length / itemSize; 176 | 177 | gl.useProgram(program); 178 | 179 | program.size = gl.getUniformLocation(program, 'size'); 180 | gl.uniform1f(program.size, renderW); 181 | 182 | program.frameT = gl.getUniformLocation(program, 'frameT'); 183 | 184 | program.position = gl.getAttribLocation(program, "position"); 185 | gl.enableVertexAttribArray(program.position); 186 | gl.vertexAttribPointer(program.position, itemSize, gl.FLOAT, false, 0, 0); 187 | 188 | frameT = 0; 189 | 190 | function render_frame() { 191 | if (animate) { 192 | animationHandle = window.requestAnimationFrame(render_frame); 193 | } 194 | 195 | frameT = (frameT + 0.01) % (2*Math.PI); 196 | //console.log('t:', frameT.toFixed(2)); 197 | 198 | gl.uniform1f(program.frameT, Math.cos(frameT)); 199 | 200 | gl.drawArrays(gl.TRIANGLES, 0, numItems); 201 | // draw in 2d canvas 202 | ctx2d.drawImage(gl.canvas, 0, 0, canvas.width, canvas.height); 203 | 204 | capturer.addFrame( canvas ); 205 | } 206 | 207 | render_frame(); 208 | } 209 | 210 | -------------------------------------------------------------------------------- /randomart.js: -------------------------------------------------------------------------------- 1 | 2 | const palettes = [["#69D2E7","#A7DBD8","#E0E4CC","#F38630","#FA6900"],["#FE4365","#FC9D9A","#F9CDAD","#C8C8A9","#83AF9B"],["#ECD078","#D95B43","#C02942","#542437","#53777A"],["#556270","#4ECDC4","#C7F464","#FF6B6B","#C44D58"],["#774F38","#E08E79","#F1D4AF","#ECE5CE","#C5E0DC"],["#E8DDCB","#CDB380","#036564","#033649","#031634"],["#490A3D","#BD1550","#E97F02","#F8CA00","#8A9B0F"],["#594F4F","#547980","#45ADA8","#9DE0AD","#E5FCC2"],["#00A0B0","#6A4A3C","#CC333F","#EB6841","#EDC951"],["#E94E77","#D68189","#C6A49A","#C6E5D9","#F4EAD5"],["#D9CEB2","#948C75","#D5DED9","#7A6A53","#99B2B7"],["#FFFFFF","#CBE86B","#F2E9E1","#1C140D","#CBE86B"],["#EFFFCD","#DCE9BE","#555152","#2E2633","#99173C"],["#3FB8AF","#7FC7AF","#DAD8A7","#FF9E9D","#FF3D7F"],["#343838","#005F6B","#008C9E","#00B4CC","#00DFFC"],["#413E4A","#73626E","#B38184","#F0B49E","#F7E4BE"],["#99B898","#FECEA8","#FF847C","#E84A5F","#2A363B"],["#FF4E50","#FC913A","#F9D423","#EDE574","#E1F5C4"],["#554236","#F77825","#D3CE3D","#F1EFA5","#60B99A"],["#351330","#424254","#64908A","#E8CAA4","#CC2A41"],["#00A8C6","#40C0CB","#F9F2E7","#AEE239","#8FBE00"],["#FF4242","#F4FAD2","#D4EE5E","#E1EDB9","#F0F2EB"],["#655643","#80BCA3","#F6F7BD","#E6AC27","#BF4D28"],["#8C2318","#5E8C6A","#88A65E","#BFB35A","#F2C45A"],["#FAD089","#FF9C5B","#F5634A","#ED303C","#3B8183"],["#BCBDAC","#CFBE27","#F27435","#F02475","#3B2D38"],["#D1E751","#FFFFFF","#000000","#4DBCE9","#26ADE4"],["#FF9900","#424242","#E9E9E9","#BCBCBC","#3299BB"],["#5D4157","#838689","#A8CABA","#CAD7B2","#EBE3AA"],["#5E412F","#FCEBB6","#78C0A8","#F07818","#F0A830"],["#EEE6AB","#C5BC8E","#696758","#45484B","#36393B"],["#1B676B","#519548","#88C425","#BEF202","#EAFDE6"],["#F8B195","#F67280","#C06C84","#6C5B7B","#355C7D"],["#452632","#91204D","#E4844A","#E8BF56","#E2F7CE"],["#F04155","#FF823A","#F2F26F","#FFF7BD","#95CFB7"],["#F0D8A8","#3D1C00","#86B8B1","#F2D694","#FA2A00"],["#2A044A","#0B2E59","#0D6759","#7AB317","#A0C55F"],["#67917A","#170409","#B8AF03","#CCBF82","#E33258"],["#B9D7D9","#668284","#2A2829","#493736","#7B3B3B"],["#BBBB88","#CCC68D","#EEDD99","#EEC290","#EEAA88"],["#A3A948","#EDB92E","#F85931","#CE1836","#009989"],["#E8D5B7","#0E2430","#FC3A51","#F5B349","#E8D5B9"],["#B3CC57","#ECF081","#FFBE40","#EF746F","#AB3E5B"],["#AB526B","#BCA297","#C5CEAE","#F0E2A4","#F4EBC3"],["#607848","#789048","#C0D860","#F0F0D8","#604848"],["#515151","#FFFFFF","#00B4FF","#EEEEEE"],["#3E4147","#FFFEDF","#DFBA69","#5A2E2E","#2A2C31"],["#300030","#480048","#601848","#C04848","#F07241"],["#1C2130","#028F76","#B3E099","#FFEAAD","#D14334"],["#A8E6CE","#DCEDC2","#FFD3B5","#FFAAA6","#FF8C94"],["#EDEBE6","#D6E1C7","#94C7B6","#403B33","#D3643B"],["#FDF1CC","#C6D6B8","#987F69","#E3AD40","#FCD036"],["#AAB3AB","#C4CBB7","#EBEFC9","#EEE0B7","#E8CAAF"],["#CC0C39","#E6781E","#C8CF02","#F8FCC1","#1693A7"],["#3A111C","#574951","#83988E","#BCDEA5","#E6F9BC"],["#FC354C","#29221F","#13747D","#0ABFBC","#FCF7C5"],["#B9D3B0","#81BDA4","#B28774","#F88F79","#F6AA93"],["#5E3929","#CD8C52","#B7D1A3","#DEE8BE","#FCF7D3"],["#230F2B","#F21D41","#EBEBBC","#BCE3C5","#82B3AE"],["#5C323E","#A82743","#E15E32","#C0D23E","#E5F04C"],["#4E395D","#827085","#8EBE94","#CCFC8E","#DC5B3E"],["#DAD6CA","#1BB0CE","#4F8699","#6A5E72","#563444"],["#C2412D","#D1AA34","#A7A844","#A46583","#5A1E4A"],["#D1313D","#E5625C","#F9BF76","#8EB2C5","#615375"],["#9D7E79","#CCAC95","#9A947C","#748B83","#5B756C"],["#1C0113","#6B0103","#A30006","#C21A01","#F03C02"],["#8DCCAD","#988864","#FEA6A2","#F9D6AC","#FFE9AF"],["#CFFFDD","#B4DEC1","#5C5863","#A85163","#FF1F4C"],["#75616B","#BFCFF7","#DCE4F7","#F8F3BF","#D34017"],["#382F32","#FFEAF2","#FCD9E5","#FBC5D8","#F1396D"],["#B6D8C0","#C8D9BF","#DADABD","#ECDBBC","#FEDCBA"],["#E3DFBA","#C8D6BF","#93CCC6","#6CBDB5","#1A1F1E"],["#A7C5BD","#E5DDCB","#EB7B59","#CF4647","#524656"],["#9DC9AC","#FFFEC7","#F56218","#FF9D2E","#919167"],["#413D3D","#040004","#C8FF00","#FA023C","#4B000F"],["#EDF6EE","#D1C089","#B3204D","#412E28","#151101"],["#A8A7A7","#CC527A","#E8175D","#474747","#363636"],["#7E5686","#A5AAD9","#E8F9A2","#F8A13F","#BA3C3D"],["#FFEDBF","#F7803C","#F54828","#2E0D23","#F8E4C1"],["#C1B398","#605951","#FBEEC2","#61A6AB","#ACCEC0"],["#5E9FA3","#DCD1B4","#FAB87F","#F87E7B","#B05574"],["#951F2B","#F5F4D7","#E0DFB1","#A5A36C","#535233"],["#FFFBB7","#A6F6AF","#66B6AB","#5B7C8D","#4F2958"],["#000000","#9F111B","#B11623","#292C37","#CCCCCC"],["#9CDDC8","#BFD8AD","#DDD9AB","#F7AF63","#633D2E"],["#EFF3CD","#B2D5BA","#61ADA0","#248F8D","#605063"],["#84B295","#ECCF8D","#BB8138","#AC2005","#2C1507"],["#FCFEF5","#E9FFE1","#CDCFB7","#D6E6C3","#FAFBE3"],["#0CA5B0","#4E3F30","#FEFEEB","#F8F4E4","#A5B3AA"],["#4D3B3B","#DE6262","#FFB88C","#FFD0B3","#F5E0D3"],["#B5AC01","#ECBA09","#E86E1C","#D41E45","#1B1521"],["#379F7A","#78AE62","#BBB749","#E0FBAC","#1F1C0D"],["#FFE181","#EEE9E5","#FAD3B2","#FFBA7F","#FF9C97"],["#4E4D4A","#353432","#94BA65","#2790B0","#2B4E72"],["#A70267","#F10C49","#FB6B41","#F6D86B","#339194"],["#30261C","#403831","#36544F","#1F5F61","#0B8185"],["#2D2D29","#215A6D","#3CA2A2","#92C7A3","#DFECE6"],["#F38A8A","#55443D","#A0CAB5","#CDE9CA","#F1EDD0"],["#793A57","#4D3339","#8C873E","#D1C5A5","#A38A5F"],["#11766D","#410936","#A40B54","#E46F0A","#F0B300"],["#AAFF00","#FFAA00","#FF00AA","#AA00FF","#00AAFF"],["#C75233","#C78933","#D6CEAA","#79B5AC","#5E2F46"],["#F8EDD1","#D88A8A","#474843","#9D9D93","#C5CFC6"],["#6DA67A","#77B885","#86C28B","#859987","#4A4857"],["#1B325F","#9CC4E4","#E9F2F9","#3A89C9","#F26C4F"],["#BED6C7","#ADC0B4","#8A7E66","#A79B83","#BBB2A1"],["#046D8B","#309292","#2FB8AC","#93A42A","#ECBE13"],["#82837E","#94B053","#BDEB07","#BFFA37","#E0E0E0"],["#312736","#D4838F","#D6ABB1","#D9D9D9","#C4FFEB"],["#E5EAA4","#A8C4A2","#69A5A4","#616382","#66245B"],["#6DA67A","#99A66D","#A9BD68","#B5CC6A","#C0DE5D"],["#395A4F","#432330","#853C43","#F25C5E","#FFA566"],["#331327","#991766","#D90F5A","#F34739","#FF6E27"],["#FDFFD9","#FFF0B8","#FFD6A3","#FAAD8E","#142F30"],["#E21B5A","#9E0C39","#333333","#FBFFE3","#83A300"],["#FBC599","#CDBB93","#9EAE8A","#335650","#F35F55"],["#C7FCD7","#D9D5A7","#D9AB91","#E6867A","#ED4A6A"],["#EC4401","#CC9B25","#13CD4A","#7B6ED6","#5E525C"],["#BF496A","#B39C82","#B8C99D","#F0D399","#595151"],["#FFEFD3","#FFFEE4","#D0ECEA","#9FD6D2","#8B7A5E"],["#F1396D","#FD6081","#F3FFEB","#ACC95F","#8F9924"],["#F6F6F6","#E8E8E8","#333333","#990100","#B90504"],["#261C21","#6E1E62","#B0254F","#DE4126","#EB9605"],["#E9E0D1","#91A398","#33605A","#070001","#68462B"],["#F2E3C6","#FFC6A5","#E6324B","#2B2B2B","#353634"],["#FFAB07","#E9D558","#72AD75","#0E8D94","#434D53"],["#59B390","#F0DDAA","#E47C5D","#E32D40","#152B3C"],["#FDE6BD","#A1C5AB","#F4DD51","#D11E48","#632F53"],["#E4E4C5","#B9D48B","#8D2036","#CE0A31","#D3E4C5"],["#512B52","#635274","#7BB0A8","#A7DBAB","#E4F5B1"],["#805841","#DCF7F3","#FFFCDD","#FFD8D8","#F5A2A2"],["#E65540","#F8ECC2","#65A8A6","#79896D"],["#CAFF42","#EBF7F8","#D0E0EB","#88ABC2","#49708A"],["#595643","#4E6B66","#ED834E","#EBCC6E","#EBE1C5"],["#E4DED0","#ABCCBD","#7DBEB8","#181619","#E32F21"],["#058789","#503D2E","#D54B1A","#E3A72F","#F0ECC9"],["#FF003C","#FF8A00","#FABE28","#88C100","#00C176"],["#311D39","#67434F","#9B8E7E","#C3CCAF","#A51A41"],["#EFD9B4","#D6A692","#A39081","#4D6160","#292522"],["#C6CCA5","#8AB8A8","#6B9997","#54787D","#615145"],["#CC5D4C","#FFFEC6","#C7D1AF","#96B49C","#5B5847"],["#111625","#341931","#571B3C","#7A1E48","#9D2053"],["#EFEECC","#FE8B05","#FE0557","#400403","#0AABBA"],["#CCF390","#E0E05A","#F7C41F","#FC930A","#FF003D"],["#73C8A9","#DEE1B6","#E1B866","#BD5532","#373B44"],["#79254A","#795C64","#79927D","#AEB18E","#E3CF9E"],["#E0EFF1","#7DB4B5","#FFFFFF","#680148","#000000"],["#F06D61","#DA825F","#C4975C","#A8AB7B","#8CBF99"],["#2D1B33","#F36A71","#EE887A","#E4E391","#9ABC8A"],["#2B2726","#0A516D","#018790","#7DAD93","#BACCA4"],["#95A131","#C8CD3B","#F6F1DE","#F5B9AE","#EE0B5B"],["#360745","#D61C59","#E7D84B","#EFEAC5","#1B8798"],["#E3E8CD","#BCD8BF","#D3B9A3","#EE9C92","#FE857E"],["#807462","#A69785","#B8FAFF","#E8FDFF","#665C49"],["#4B1139","#3B4058","#2A6E78","#7A907C","#C9B180"],["#FC284F","#FF824A","#FEA887","#F6E7F7","#D1D0D7"],["#FFB884","#F5DF98","#FFF8D4","#C0D1C2","#2E4347"],["#027B7F","#FFA588","#D62957","#BF1E62","#572E4F"],["#80A8A8","#909D9E","#A88C8C","#FF0D51","#7A8C89"],["#A69E80","#E0BA9B","#E7A97E","#D28574","#3B1922"],["#A1DBB2","#FEE5AD","#FACA66","#F7A541","#F45D4C"],["#641F5E","#676077","#65AC92","#C2C092","#EDD48E"],["#FFF3DB","#E7E4D5","#D3C8B4","#C84648","#703E3B"],["#F5DD9D","#BCC499","#92A68A","#7B8F8A","#506266"],["#2B222C","#5E4352","#965D62","#C7956D","#F2D974"],["#D4F7DC","#DBE7B4","#DBC092","#E0846D","#F51441"],["#A32C28","#1C090B","#384030","#7B8055","#BCA875"],["#85847E","#AB6A6E","#F7345B","#353130","#CBCFB4"],["#E6B39A","#E6CBA5","#EDE3B4","#8B9E9B","#6D7578"],["#11644D","#A0B046","#F2C94E","#F78145","#F24E4E"],["#6D9788","#1E2528","#7E1C13","#BF0A0D","#E6E1C2"],["#23192D","#FD0A54","#F57576","#FEBF97","#F5ECB7"],["#EB9C4D","#F2D680","#F3FFCF","#BAC9A9","#697060"],["#D3D5B0","#B5CEA4","#9DC19D","#8C7C62","#71443F"],["#452E3C","#FF3D5A","#FFB969","#EAF27E","#3B8C88"],["#041122","#259073","#7FDA89","#C8E98E","#E6F99D"],["#B1E6D1","#77B1A9","#3D7B80","#270A33","#451A3E"],["#9D9E94","#C99E93","#F59D92","#E5B8AD","#D5D2C8"],["#FDCFBF","#FEB89F","#E23D75","#5F0D3B","#742365"],["#540045","#C60052","#FF714B","#EAFF87","#ACFFE9"],["#B7CBBF","#8C886F","#F9A799","#F4BFAD","#F5DABD"],["#280904","#680E34","#9A151A","#C21B12","#FC4B2A"],["#F0FFC9","#A9DA88","#62997A","#72243D","#3B0819"],["#429398","#6B5D4D","#B0A18F","#DFCDB4","#FBEED3"],["#E6EBA9","#ABBB9F","#6F8B94","#706482","#703D6F"],["#A3C68C","#879676","#6E6662","#4F364A","#340735"],["#44749D","#C6D4E1","#FFFFFF","#EBE7E0","#BDB8AD"],["#322938","#89A194","#CFC89A","#CC883A","#A14016"],["#CFB590","#9E9A41","#758918","#564334","#49281F"],["#FA6A64","#7A4E48","#4A4031","#F6E2BB","#9EC6B8"],["#1D1313","#24B694","#D22042","#A3B808","#30C4C9"],["#F6D76B","#FF9036","#D6254D","#FF5475","#FDEBA9"],["#E7EDEA","#FFC52C","#FB0C06","#030D4F","#CEECEF"],["#373737","#8DB986","#ACCE91","#BADB73","#EFEAE4"],["#161616","#C94D65","#E7C049","#92B35A","#1F6764"],["#26251C","#EB0A44","#F2643D","#F2A73D","#A0E8B7"],["#4B3E4D","#1E8C93","#DBD8A2","#C4AC30","#D74F33"],["#8D7966","#A8A39D","#D8C8B8","#E2DDD9","#F8F1E9"],["#F2E8C4","#98D9B6","#3EC9A7","#2B879E","#616668"],["#5CACC4","#8CD19D","#CEE879","#FCB653","#FF5254"]]; 3 | 4 | let random = new Random(); 5 | 6 | /* 7 | * Helpers 8 | */ 9 | 10 | function parseColor(s) { 11 | if (s.startsWith('#')) s = s.substring(1); 12 | const num = parseInt(s, 16); 13 | return [(num >> 16) & 0xFF, (num >> 8) & 0xFF, num & 0xFF ] 14 | } 15 | 16 | function fixStr(n) { return n.toFixed(4) } 17 | 18 | /* 19 | * Terminals 20 | */ 21 | 22 | class CConst { 23 | constructor(c) { 24 | this.c = c; 25 | if (typeof(c) === 'number') { 26 | this.val = [this.c, this.c, this.c]; 27 | } else { 28 | this.val = this.c; 29 | } 30 | } 31 | toString() { 32 | return `Const(${this.c})`; 33 | } 34 | } 35 | 36 | class CVarX { 37 | static get arity() { return 0 } 38 | static get mindepth() { return 4 } 39 | 40 | constructor() { 41 | } 42 | toString() { 43 | return "posX"; 44 | } 45 | } 46 | 47 | class CVarY { 48 | static get arity() { return 0 } 49 | static get mindepth() { return 4 } 50 | 51 | constructor() { 52 | } 53 | toString() { 54 | return "posY"; 55 | } 56 | } 57 | 58 | class CVarT { 59 | static get arity() { return 0 } 60 | static get mindepth() { return 4 } 61 | 62 | constructor() { 63 | } 64 | toString() { 65 | return "frmT"; 66 | } 67 | } 68 | 69 | class CBW { 70 | static get arity() { return 0 } 71 | static get mindepth() { return 4 } 72 | 73 | constructor() { 74 | this.c = random.uniform(-0.8, 0.8); 75 | } 76 | toString() { 77 | return `BW(${fixStr(this.c)})`; 78 | } 79 | } 80 | 81 | class CRandom { 82 | static get arity() { return 0 } 83 | static get mindepth() { return 4 } 84 | 85 | constructor() { 86 | this.c = [random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1)]; 87 | } 88 | toString() { 89 | return `Const(${fixStr(this.c[0])}, ${fixStr(this.c[1])}, ${fixStr(this.c[2])})`; 90 | } 91 | } 92 | 93 | let palette = palettes[0]; 94 | let paletteIdx = 0; 95 | 96 | class CPalette { 97 | static get arity() { return 0 } 98 | static get mindepth() { return 3 } 99 | 100 | constructor() { 101 | this.hex = palette[paletteIdx++]; 102 | if (paletteIdx >= palette.length) 103 | paletteIdx = 0; 104 | this.c = parseColor(this.hex).map(i => (i/128 - 1.0)); 105 | } 106 | toString() { 107 | return `Const(${fixStr(this.c[0])}, ${fixStr(this.c[1])}, ${fixStr(this.c[2])})`; 108 | } 109 | } 110 | 111 | /* 112 | * Mixers 113 | */ 114 | 115 | class CRGB { 116 | static get arity() { return 3 } 117 | static get mindepth() { return 4 } 118 | 119 | constructor(e1,e2,e3) { 120 | this.e1 = e1; 121 | this.e2 = e2; 122 | this.e3 = e3; 123 | } 124 | toString() { 125 | return `RGB(${this.e1}, ${this.e2}, ${this.e3})`; 126 | } 127 | } 128 | 129 | class CSum { 130 | static get arity() { return 2 } 131 | static get mindepth() { return 2 } 132 | 133 | constructor(e1, e2) { 134 | this.e1 = e1; 135 | this.e2 = e2; 136 | } 137 | toString() { 138 | return `Sum(${this.e1}, ${this.e2})`; 139 | } 140 | } 141 | 142 | class CMul { 143 | static get arity() { return 2 } 144 | static get mindepth() { return 2 } 145 | 146 | constructor(e1, e2) { 147 | this.e1 = e1; 148 | this.e2 = e2; 149 | } 150 | toString() { 151 | return `Mul(${this.e1}, ${this.e2})`; 152 | } 153 | } 154 | 155 | class CMod { 156 | static get arity() { return 2 } 157 | static get mindepth() { return 2 } 158 | 159 | constructor(e1, e2) { 160 | this.e1 = e1; 161 | this.e2 = e2; 162 | } 163 | toString() { 164 | return `Mod(${this.e1}, ${this.e2})`; 165 | } 166 | } 167 | 168 | /* 169 | class CChBoard { 170 | static get arity() { return 0 } 171 | static get mindepth() { return 5 } 172 | 173 | constructor(e1, e2) { 174 | this.wX = random.uniform(0.1, 1.0); 175 | this.wY = random.uniform(0.1, 1.0); 176 | } 177 | toString() { 178 | return `ChBoard()`; 179 | } 180 | eval(x, y) { 181 | let isOdd = false; 182 | isOdd ^= Math.floor(x/this.wX) & 1; 183 | isOdd ^= Math.floor(y/this.wY) & 1; 184 | 185 | return (isOdd) ? [-1,-1,-1] : [1,1,1]; 186 | } 187 | } 188 | 189 | class CTurbulence { 190 | static get arity() { return 1 } 191 | static get mindepth() { return 2 } 192 | 193 | constructor(e) { 194 | this.e = e; 195 | 196 | this.octaves = random.randrange(3, 6); 197 | this.freq = random.uniform(0.1, 4); 198 | this.ampl = random.uniform(0.1, 5); 199 | } 200 | toString() { 201 | return `Turbulence(${this.e})`; 202 | } 203 | eval(x, y) { 204 | let r = 0, g = 0, b = 0; 205 | let amp = this.ampl; 206 | 207 | x *= this.freq; 208 | y *= this.freq; 209 | 210 | for (let i=0; i (i.arity == 0)) 326 | const nonterminals = operators.filter(i => (i.arity > 0)) 327 | 328 | function generateTree(k, depth) { 329 | if (depth >= k) { 330 | return new (random.choice(terminals))(); 331 | } 332 | 333 | let op = random.choice(nonterminals.filter(i => (depth >= i.mindepth))); 334 | //while (depth < k && random.uniform() <= 0.3) depth++; 335 | //depth += random.randrange(0, op.arity-1); 336 | depth++; 337 | 338 | let args = []; 339 | for (let i = 0; i 2 | 3 | 4 | 5 | 12 | 13 | 14 | 15 | 42 | 43 | 44 | 45 |
46 | 47 | 48 | 49 | 50 | --------------------------------------------------------------------------------