├── LICENSE.txt ├── README.md ├── css ├── icons │ ├── Email.png │ ├── Facebook.png │ └── Twitter.png └── index.css ├── favicon.png ├── img ├── feature_draw.gif ├── feature_play.gif ├── feature_remix.gif ├── logo.png ├── use_1.png ├── use_2.png ├── use_3.png ├── use_4.png └── use_5.png ├── index.html ├── social ├── thumbnail.png └── thumbnail_small.png ├── splash ├── css │ ├── balloon.css │ ├── cursors │ │ ├── drag.png │ │ ├── erase.png │ │ ├── ink.png │ │ └── label.png │ ├── icons │ │ ├── controls.png │ │ ├── drag.png │ │ ├── erase.png │ │ ├── ink.png │ │ ├── label.png │ │ ├── speed_fast.png │ │ └── speed_slow.png │ ├── loopy.css │ └── sliders │ │ ├── color.png │ │ ├── initial.png │ │ ├── slider_pointer.png │ │ ├── strength.png │ │ └── strength_original.png ├── index.html └── js │ ├── Dragger.js │ ├── Edge.js │ ├── Eraser.js │ ├── Ink.js │ ├── Key.js │ ├── Label.js │ ├── Labeller.js │ ├── Loopy.js │ ├── Modal.js │ ├── Model.js │ ├── Mouse.js │ ├── Node.js │ ├── PageUI.js │ ├── PlayControls.js │ ├── Sidebar.js │ ├── Toolbar.js │ ├── helpers.js │ └── minpubsub.js ├── v1.1 ├── css │ ├── balloon.css │ ├── cursors │ │ ├── drag.png │ │ ├── erase.png │ │ ├── ink.png │ │ └── label.png │ ├── icons │ │ ├── controls.png │ │ ├── drag.png │ │ ├── erase.png │ │ ├── ink.png │ │ ├── label.png │ │ ├── speed_fast.png │ │ └── speed_slow.png │ ├── loopy.css │ └── sliders │ │ ├── color.png │ │ ├── initial.png │ │ ├── slider_pointer.png │ │ ├── strength.png │ │ └── strength_original.png ├── favicon.png ├── index.html ├── js │ ├── Dragger.js │ ├── Edge.js │ ├── Eraser.js │ ├── Ink.js │ ├── Key.js │ ├── Label.js │ ├── Labeller.js │ ├── Loopy.js │ ├── Modal.js │ ├── Model.js │ ├── Mouse.js │ ├── Node.js │ ├── PageUI.js │ ├── PlayControls.js │ ├── Sidebar.js │ ├── Toolbar.js │ ├── helpers.js │ └── minpubsub.js └── pages │ ├── credits │ ├── favicon.png │ ├── index.html │ ├── peep │ │ ├── aimee.png │ │ ├── buster.png │ │ ├── chad.png │ │ ├── jared.png │ │ ├── ljt.png │ │ ├── mark.png │ │ ├── matt.png │ │ ├── michael_duke.png │ │ ├── michael_huff.png │ │ ├── natalie.png │ │ ├── nicholas.png │ │ ├── noel.png │ │ ├── phil.png │ │ ├── philippe.png │ │ ├── thomas.png │ │ ├── travis.png │ │ └── yu-han.png │ └── polygon │ │ ├── aimee.png │ │ ├── buster.png │ │ ├── cedric.png │ │ ├── chad.png │ │ ├── dylan.png │ │ ├── dylan_s.png │ │ ├── feiya.png │ │ ├── glen.png │ │ ├── iago.png │ │ ├── jared.png │ │ ├── karen.png │ │ ├── kate.png │ │ ├── kevin.png │ │ ├── klemen.png │ │ ├── kuerqing1024.png │ │ ├── ljt.png │ │ ├── mark.png │ │ ├── matt.png │ │ ├── michael_duke.png │ │ ├── michael_huff.png │ │ ├── michelle.png │ │ ├── natalie.png │ │ ├── nicholas.png │ │ ├── nimrod.png │ │ ├── noel.png │ │ ├── phil.png │ │ ├── philippe.png │ │ ├── rob.png │ │ ├── thomas.png │ │ ├── travis.png │ │ ├── william.png │ │ ├── yu-han.png │ │ └── zach.png │ ├── examples │ ├── favicon.png │ └── index.html │ ├── gif.html │ ├── gifs.gif │ ├── howto.html │ ├── howto │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ └── 5.png │ └── page.css └── v1 ├── css ├── balloon.css ├── cursors │ ├── drag.png │ ├── erase.png │ ├── ink.png │ └── label.png ├── icons │ ├── controls.png │ ├── drag.png │ ├── erase.png │ ├── ink.png │ ├── label.png │ ├── speed_fast.png │ └── speed_slow.png ├── loopy.css └── sliders │ ├── color.png │ ├── initial.png │ ├── slider_pointer.png │ ├── strength.png │ └── strength_original.png ├── favicon.png ├── index.html ├── js ├── Dragger.js ├── Edge.js ├── Eraser.js ├── Ink.js ├── Key.js ├── Label.js ├── Labeller.js ├── Loopy.js ├── Modal.js ├── Model.js ├── Mouse.js ├── Node.js ├── PageUI.js ├── PlayControls.js ├── Sidebar.js ├── Toolbar.js ├── helpers.js └── minpubsub.js └── pages ├── credits ├── favicon.png ├── index.html ├── peep │ ├── aimee.png │ ├── buster.png │ ├── chad.png │ ├── jared.png │ ├── ljt.png │ ├── mark.png │ ├── matt.png │ ├── michael_duke.png │ ├── michael_huff.png │ ├── natalie.png │ ├── nicholas.png │ ├── noel.png │ ├── phil.png │ ├── philippe.png │ ├── travis.png │ └── yu-han.png └── polygon │ ├── aimee.png │ ├── buster.png │ ├── cedric.png │ ├── chad.png │ ├── dylan.png │ ├── dylan_s.png │ ├── feiya.png │ ├── glen.png │ ├── iago.png │ ├── jared.png │ ├── karen.png │ ├── kate.png │ ├── kevin.png │ ├── klemen.png │ ├── kuerqing1024.png │ ├── ljt.png │ ├── mark.png │ ├── matt.png │ ├── michael_duke.png │ ├── michael_huff.png │ ├── michelle.png │ ├── natalie.png │ ├── nicholas.png │ ├── nimrod.png │ ├── noel.png │ ├── phil.png │ ├── philippe.png │ ├── rob.png │ ├── thomas.png │ ├── travis.png │ ├── william.png │ ├── yu-han.png │ └── zach.png ├── examples ├── favicon.png └── index.html ├── gif.html ├── gifs.gif ├── howto.html ├── howto ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png └── page.css /LICENSE.txt: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://i.imgur.com/S8c7E8o.gif) 2 | 3 | ### [LOOPY - a tool for thinking in systems](http://ncase.me/loopy/) 4 | 5 | [Zero Rights Reserved](http://creativecommons.org/publicdomain/zero/1.0/): 6 | LOOPY is entirely open source/public domain. 7 | 8 | To mirror LOOPY, just clone this Github Repo with the gh-pages branch. 9 | ([learn more about these free Github Pages](https://pages.github.com/)) 10 | 11 | Other Peeps' Open Source Code I Used: 12 | - [minpubsub](https://github.com/daniellmb/MinPubSub) 13 | - [balloon.css](https://kazzkiq.github.io/balloon.css/) 14 | - [simple sharing buttons](https://simplesharingbuttons.com/) 15 | 16 | Check out these [user-made LOOPY's!](http://ncase.me/loopy/v1.1/pages/examples) 17 | 18 | --- 19 | 20 | Version 1.1: 21 | - node amounts are now "uncapped" 22 | - better distribution of "signals" 23 | 24 | Version 1.0: the whole everything. 25 | -------------------------------------------------------------------------------- /css/icons/Email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/css/icons/Email.png -------------------------------------------------------------------------------- /css/icons/Facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/css/icons/Facebook.png -------------------------------------------------------------------------------- /css/icons/Twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/css/icons/Twitter.png -------------------------------------------------------------------------------- /css/index.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin:0; 3 | background: #fff; 4 | 5 | font-family: Helvetica, Arial, sans-serif; 6 | font-weight: 100; 7 | 8 | color: #444; 9 | font-size: 25px; 10 | text-align: justify; 11 | 12 | line-height: 1.7em; 13 | 14 | } 15 | .section{ 16 | padding: 50px; 17 | } 18 | .white.section{ background: #fff; } 19 | .light-gray.section{ background: #e9e9e9; } 20 | .dark-gray.section{ background: #444; color: #aaa; } 21 | .black.section{ background: #222; color: #fff; } 22 | 23 | .section .content{ 24 | width: 640px; 25 | margin: 0 auto; 26 | margin-top: 2em; 27 | } 28 | .section .content:first-child{ 29 | margin-top: 0em; 30 | } 31 | 32 | .dark-gray .content, .black .content{ 33 | font-size: 20px; 34 | line-height: 1.7em; 35 | } 36 | 37 | /********** 38 | 39 | SPLASH 40 | 41 | **********/ 42 | 43 | #splash{ 44 | position: relative; 45 | padding:0; 46 | overflow:hidden; 47 | width:100%; 48 | height: 380px; 49 | } 50 | #logo_container{ 51 | 52 | width: 800px; 53 | height: 360px; 54 | 55 | position: absolute; 56 | margin: auto; 57 | top:0; left:0; right:0; bottom:0; 58 | 59 | } 60 | #logo_interactive{ 61 | position: absolute; 62 | transform: scale(1.36,1.36); 63 | top: 65px; 64 | left: 165px; 65 | } 66 | #logo{ 67 | position: absolute; 68 | top: 80px; 69 | width: 800px; 70 | height: 250px; 71 | background-image: url(../img/logo.png); 72 | background-size: 100% 100%; 73 | pointer-events: none; 74 | } 75 | #arrow{ 76 | margin: 0 auto; 77 | width: 0; 78 | height: 0; 79 | border-left: 30px solid transparent; 80 | border-right: 30px solid transparent; 81 | border-top: 30px solid #fff; 82 | } 83 | 84 | /********** 85 | 86 | INFORMATION: 87 | - a "why" statement 88 | - three features 89 | 90 | **********/ 91 | 92 | #why{} 93 | #features{ 94 | overflow: hidden; 95 | color: #777; 96 | font-size: 18px; 97 | } 98 | #features > div{ 99 | float: left; 100 | margin-bottom: 2em; 101 | } 102 | #features > div:nth-child(even){ 103 | margin-left: 30px; 104 | } 105 | #features > div:nth-child(n+5){ 106 | margin-bottom: 0; 107 | } 108 | #features > .feature-image{ 109 | width: 305px; 110 | height: 220px; 111 | background: #888; 112 | } 113 | #features > .feature-text{ 114 | width: 305px; 115 | height: 220px; 116 | line-height: 1.5em; 117 | } 118 | #features > .feature-text > div{ 119 | font-size: 24px; 120 | font-weight: bold; 121 | color: #444; 122 | margin-bottom: 0.7em; 123 | } 124 | 125 | 126 | /********** 127 | 128 | EXAMPLES: 129 | 130 | **********/ 131 | 132 | #example_header{ 133 | font-size: 40px; 134 | text-align: center; 135 | font-weight: bold; 136 | } 137 | #examples{ 138 | overflow: hidden; 139 | width: 620px; 140 | margin-top: 0; 141 | } 142 | 143 | .cool_button{ 144 | text-decoration:none; 145 | display: block; 146 | } 147 | .cool_button > div{ 148 | 149 | border: 2px solid #999; 150 | color: #555; 151 | 152 | text-align: center; 153 | text-decoration: none; 154 | line-height: 25px; 155 | 156 | width: 490px; 157 | height: 20px; 158 | padding: 15px; 159 | border-radius: 10px; 160 | 161 | margin: 0 auto; 162 | margin-top: 0px; 163 | 164 | cursor: pointer; 165 | 166 | position: relative; 167 | top: 0; 168 | 169 | transition: all 0.1s ease-in-out; 170 | 171 | } 172 | .cool_button:hover > div{ 173 | border-color: #ccc; 174 | color: #999; 175 | top: -2px; 176 | } 177 | .cool_button:active > div{ 178 | border-color: #666; 179 | color: #333; 180 | top: 2px; 181 | } 182 | #start_blank{ 183 | width:520px; 184 | margin: 0 auto; 185 | } 186 | #splash_buttons{ 187 | width: 280px; 188 | margin: 0 auto; 189 | overflow: hidden; 190 | padding: 5px 0; 191 | } 192 | .splash_button{ 193 | width: 140px; 194 | font-size: 20px; 195 | float: left; 196 | } 197 | .splash_button > div{ 198 | width: 100px; 199 | line-height: 22px; 200 | } 201 | #final_button{ 202 | width:400px; 203 | margin: 0 auto; 204 | } 205 | #final_button > div{ 206 | background: #ee3939; 207 | color: #fff; 208 | 209 | font-size: 35px; 210 | line-height: 35px; 211 | width: 360px; 212 | height: 30px; 213 | 214 | border:none; 215 | border-bottom: 4px solid rgba(0,0,0,0.25); 216 | } 217 | #final_button:hover > div{ 218 | background: #ff4f4f; 219 | color: #fff; 220 | } 221 | #final_button:active > div{ 222 | background: #aa1616; 223 | color: #fff; 224 | } 225 | 226 | /********** 227 | 228 | CONCLUSION: 229 | 230 | **********/ 231 | 232 | #uses{ 233 | overflow: hidden; 234 | text-align: center; 235 | } 236 | #uses > img{ 237 | width:120px; 238 | } 239 | #uses > img:nth-child(n+2){ 240 | margin-left: 9px; 241 | } 242 | 243 | /********** 244 | 245 | CREDITS: 246 | 247 | **********/ 248 | 249 | .dark-gray a{ 250 | color: hsl(0,80%,60%); 251 | } 252 | .dark-gray a:hover{ 253 | color: hsl(0,80%,70%); 254 | } 255 | 256 | #sharing{ 257 | text-align: center; 258 | } 259 | 260 | ul.share-buttons{ 261 | display: inline-block; 262 | list-style: none; 263 | padding: 0; 264 | } 265 | ul.share-buttons li{ 266 | display: inline; 267 | margin-right: -6px; 268 | } -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/favicon.png -------------------------------------------------------------------------------- /img/feature_draw.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/feature_draw.gif -------------------------------------------------------------------------------- /img/feature_play.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/feature_play.gif -------------------------------------------------------------------------------- /img/feature_remix.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/feature_remix.gif -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/logo.png -------------------------------------------------------------------------------- /img/use_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/use_1.png -------------------------------------------------------------------------------- /img/use_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/use_2.png -------------------------------------------------------------------------------- /img/use_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/use_3.png -------------------------------------------------------------------------------- /img/use_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/use_4.png -------------------------------------------------------------------------------- /img/use_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/img/use_5.png -------------------------------------------------------------------------------- /social/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/social/thumbnail.png -------------------------------------------------------------------------------- /social/thumbnail_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/social/thumbnail_small.png -------------------------------------------------------------------------------- /splash/css/balloon.css: -------------------------------------------------------------------------------- 1 | button[data-balloon] { 2 | overflow: visible; 3 | } 4 | [data-balloon] { 5 | position: relative; 6 | } 7 | [data-balloon]:before, 8 | [data-balloon]:after { 9 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 10 | filter: alpha(opacity=0); 11 | -khtml-opacity: 0; 12 | -moz-opacity: 0; 13 | opacity: 0; 14 | pointer-events: none; 15 | -webkit-transition: all 0.1s ease-out 0.1s; 16 | transition: all 0.1s ease-out 0.1s; 17 | bottom: 100%; 18 | left: 50%; 19 | position: absolute; 20 | z-index: 10; 21 | -webkit-transform: translate(-50%, 10px); 22 | -ms-transform: translate(-50%, 10px); 23 | transform: translate(-50%, 10px); 24 | -webkit-transform-origin: top; 25 | -ms-transform-origin: top; 26 | transform-origin: top; 27 | } 28 | [data-balloon]:after { 29 | background: rgba(17, 17, 17, 0.9); 30 | border-radius: 4px; 31 | color: #fff; 32 | content: attr(data-balloon); 33 | font-size: 18px; 34 | padding: .5em 1em; 35 | white-space: nowrap; 36 | margin-bottom: 11px; 37 | } 38 | [data-balloon]:before { 39 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 40 | background-size: 100% auto; 41 | height: 6px; 42 | width: 18px; 43 | content: ""; 44 | margin-bottom: 5px; 45 | } 46 | [data-balloon]:hover:before, 47 | [data-balloon][data-balloon-visible]:before, 48 | [data-balloon]:hover:after, 49 | [data-balloon][data-balloon-visible]:after { 50 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; 51 | filter: alpha(opacity=100); 52 | -khtml-opacity: 1; 53 | -moz-opacity: 1; 54 | opacity: 1; 55 | pointer-events: auto; 56 | -webkit-transform: translate(-50%, 0); 57 | -ms-transform: translate(-50%, 0); 58 | transform: translate(-50%, 0); 59 | } 60 | [data-balloon].font-awesome:after { 61 | font-family: FontAwesome; 62 | } 63 | [data-balloon][data-balloon-break]:after { 64 | white-space: pre; 65 | } 66 | [data-balloon-pos="down"]:before, 67 | [data-balloon-pos="down"]:after { 68 | bottom: auto; 69 | left: 50%; 70 | top: 100%; 71 | -webkit-transform: translate(-50%, -10px); 72 | -ms-transform: translate(-50%, -10px); 73 | transform: translate(-50%, -10px); 74 | } 75 | [data-balloon-pos="down"]:after { 76 | margin-top: 11px; 77 | } 78 | [data-balloon-pos="down"]:before { 79 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 80 | background-size: 100% auto; 81 | height: 6px; 82 | width: 18px; 83 | margin-top: 5px; 84 | margin-bottom: 0; 85 | } 86 | [data-balloon-pos="down"]:hover:before, 87 | [data-balloon-pos="down"][data-balloon-visible]:before, 88 | [data-balloon-pos="down"]:hover:after, 89 | [data-balloon-pos="down"][data-balloon-visible]:after { 90 | -webkit-transform: translate(-50%, 0); 91 | -ms-transform: translate(-50%, 0); 92 | transform: translate(-50%, 0); 93 | } 94 | [data-balloon-pos="left"]:before, 95 | [data-balloon-pos="left"]:after { 96 | bottom: auto; 97 | left: auto; 98 | right: 100%; 99 | top: 50%; 100 | -webkit-transform: translate(10px, -50%); 101 | -ms-transform: translate(10px, -50%); 102 | transform: translate(10px, -50%); 103 | } 104 | [data-balloon-pos="left"]:after { 105 | margin-right: 11px; 106 | } 107 | [data-balloon-pos="left"]:before { 108 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 109 | background-size: 100% auto; 110 | height: 18px; 111 | width: 6px; 112 | margin-right: 5px; 113 | margin-bottom: 0; 114 | } 115 | [data-balloon-pos="left"]:hover:before, 116 | [data-balloon-pos="left"][data-balloon-visible]:before, 117 | [data-balloon-pos="left"]:hover:after, 118 | [data-balloon-pos="left"][data-balloon-visible]:after { 119 | -webkit-transform: translate(0, -50%); 120 | -ms-transform: translate(0, -50%); 121 | transform: translate(0, -50%); 122 | } 123 | [data-balloon-pos="right"]:before, 124 | [data-balloon-pos="right"]:after { 125 | bottom: auto; 126 | left: 100%; 127 | top: 50%; 128 | -webkit-transform: translate(-10px, -50%); 129 | -ms-transform: translate(-10px, -50%); 130 | transform: translate(-10px, -50%); 131 | } 132 | [data-balloon-pos="right"]:after { 133 | margin-left: 11px; 134 | } 135 | [data-balloon-pos="right"]:before { 136 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 137 | background-size: 100% auto; 138 | height: 18px; 139 | width: 6px; 140 | margin-bottom: 0; 141 | margin-left: 5px; 142 | } 143 | [data-balloon-pos="right"]:hover:before, 144 | [data-balloon-pos="right"][data-balloon-visible]:before, 145 | [data-balloon-pos="right"]:hover:after, 146 | [data-balloon-pos="right"][data-balloon-visible]:after { 147 | -webkit-transform: translate(0, -50%); 148 | -ms-transform: translate(0, -50%); 149 | transform: translate(0, -50%); 150 | } 151 | [data-balloon-length]:after { 152 | white-space: normal; 153 | } 154 | [data-balloon-length="small"]:after { 155 | width: 80px; 156 | } 157 | [data-balloon-length="medium"]:after { 158 | width: 150px; 159 | } 160 | [data-balloon-length="large"]:after { 161 | width: 260px; 162 | } 163 | [data-balloon-length="xlarge"]:after { 164 | width: 90vw; 165 | } 166 | @media screen and (min-width: 768px) { 167 | [data-balloon-length="xlarge"]:after { 168 | width: 380px; 169 | } 170 | } 171 | [data-balloon-length="fit"]:after { 172 | width: 100%; 173 | } 174 | -------------------------------------------------------------------------------- /splash/css/cursors/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/cursors/drag.png -------------------------------------------------------------------------------- /splash/css/cursors/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/cursors/erase.png -------------------------------------------------------------------------------- /splash/css/cursors/ink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/cursors/ink.png -------------------------------------------------------------------------------- /splash/css/cursors/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/cursors/label.png -------------------------------------------------------------------------------- /splash/css/icons/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/controls.png -------------------------------------------------------------------------------- /splash/css/icons/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/drag.png -------------------------------------------------------------------------------- /splash/css/icons/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/erase.png -------------------------------------------------------------------------------- /splash/css/icons/ink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/ink.png -------------------------------------------------------------------------------- /splash/css/icons/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/label.png -------------------------------------------------------------------------------- /splash/css/icons/speed_fast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/speed_fast.png -------------------------------------------------------------------------------- /splash/css/icons/speed_slow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/icons/speed_slow.png -------------------------------------------------------------------------------- /splash/css/sliders/color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/sliders/color.png -------------------------------------------------------------------------------- /splash/css/sliders/initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/sliders/initial.png -------------------------------------------------------------------------------- /splash/css/sliders/slider_pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/sliders/slider_pointer.png -------------------------------------------------------------------------------- /splash/css/sliders/strength.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/sliders/strength.png -------------------------------------------------------------------------------- /splash/css/sliders/strength_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/splash/css/sliders/strength_original.png -------------------------------------------------------------------------------- /splash/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | LOOPY (v1.0) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /splash/js/Dragger.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | DRAGGER 4 | 5 | **********************************/ 6 | 7 | function Dragger(loopy){ 8 | 9 | var self = this; 10 | self.loopy = loopy; 11 | 12 | // Dragging anything? 13 | self.dragging = null; 14 | self.offsetX = 0; 15 | self.offsetY = 0; 16 | 17 | subscribe("mousedown",function(){ 18 | 19 | // ONLY WHEN EDITING w DRAG 20 | if(self.loopy.mode!=Loopy.MODE_EDIT) return; 21 | if(self.loopy.tool!=Loopy.TOOL_DRAG) return; 22 | 23 | // Any node under here? If so, start dragging! 24 | var dragNode = loopy.model.getNodeByPoint(Mouse.x, Mouse.y); 25 | if(dragNode){ 26 | self.dragging = dragNode; 27 | self.offsetX = Mouse.x - dragNode.x; 28 | self.offsetY = Mouse.y - dragNode.y; 29 | loopy.sidebar.edit(dragNode); // and edit! 30 | return; 31 | } 32 | 33 | // Any label under here? If so, start dragging! 34 | var dragLabel = loopy.model.getLabelByPoint(Mouse.x, Mouse.y); 35 | if(dragLabel){ 36 | self.dragging = dragLabel; 37 | self.offsetX = Mouse.x - dragLabel.x; 38 | self.offsetY = Mouse.y - dragLabel.y; 39 | loopy.sidebar.edit(dragLabel); // and edit! 40 | return; 41 | } 42 | 43 | // Any edge under here? If so, start dragging! 44 | var dragEdge = loopy.model.getEdgeByPoint(Mouse.x, Mouse.y); 45 | if(dragEdge){ 46 | self.dragging = dragEdge; 47 | self.offsetX = Mouse.x - dragEdge.labelX; 48 | self.offsetY = Mouse.y - dragEdge.labelY; 49 | loopy.sidebar.edit(dragEdge); // and edit! 50 | return; 51 | } 52 | 53 | }); 54 | subscribe("mousemove",function(){ 55 | 56 | // ONLY WHEN EDITING w DRAG 57 | if(self.loopy.mode!=Loopy.MODE_EDIT) return; 58 | if(self.loopy.tool!=Loopy.TOOL_DRAG) return; 59 | 60 | // If you're dragging a NODE, move it around! 61 | if(self.dragging && self.dragging._CLASS_=="Node"){ 62 | 63 | // Model's been changed! 64 | publish("model/changed"); 65 | 66 | var node = self.dragging; 67 | node.x = Mouse.x - self.offsetX; 68 | node.y = Mouse.y - self.offsetY; 69 | 70 | // update coz visual glitches 71 | loopy.model.update(); 72 | 73 | } 74 | 75 | // If you're dragging an EDGE, move it around! 76 | if(self.dragging && self.dragging._CLASS_=="Edge"){ 77 | 78 | // Model's been changed! 79 | publish("model/changed"); 80 | 81 | var edge = self.dragging; 82 | var labelX = Mouse.x - self.offsetX; 83 | var labelY = Mouse.y - self.offsetY; 84 | 85 | // TODO: also works for self-arrow! 86 | if(edge.from!=edge.to){ 87 | 88 | // The Arc: whatever label *Y* is, relative to angle & first node's pos 89 | var fx=edge.from.x, fy=edge.from.y, tx=edge.to.x, ty=edge.to.y; 90 | var dx=tx-fx, dy=ty-fy; 91 | var a = Math.atan2(dy,dx); 92 | 93 | // Calculate arc 94 | var points = [[labelX,labelY]]; 95 | var translated = _translatePoints(points, -fx, -fy); 96 | var rotated = _rotatePoints(translated, -a); 97 | var newLabelPoint = rotated[0]; 98 | 99 | // ooookay. 100 | edge.arc = -newLabelPoint[1]; // WHY NEGATIVE? I DON'T KNOW. 101 | 102 | }else{ 103 | 104 | // For SELF-ARROWS: just get angle & mag for label. 105 | var dx = labelX - edge.from.x, 106 | dy = labelY - edge.from.y; 107 | var a = Math.atan2(dy,dx); 108 | var mag = Math.sqrt(dx*dx + dy*dy); 109 | 110 | // Minimum mag 111 | var minimum = edge.from.radius+25; 112 | if(magMath.abs(bounds.bottom)) edgeConfig.arc = -bounds.top; 161 | else edgeConfig.arc = -bounds.bottom; 162 | 163 | } 164 | 165 | // Add the edge! 166 | if(edgeConfig){ 167 | var newEdge = loopy.model.addEdge(edgeConfig); 168 | loopy.sidebar.edit(newEdge); 169 | } 170 | 171 | } 172 | 173 | // NODE: did NOT start in a node. 174 | if(!startNode){ 175 | 176 | // Just roughly make a circle the size of the bounds of the circle 177 | var bounds = _getBounds(self.strokeData); 178 | var x = (bounds.left+bounds.right)/2; 179 | var y = (bounds.top+bounds.bottom)/2; 180 | var r = ((bounds.width/2)+(bounds.height/2))/2; 181 | 182 | // Circle can't be TOO smol 183 | if(r>15){ 184 | 185 | // Snap to radius 186 | /*r = Math.round(r/Ink.SNAP_TO_RADIUS)*Ink.SNAP_TO_RADIUS; 187 | if(rthe examples!"; 82 | page.dom.appendChild(label); 83 | 84 | self.addPage("howto", page); 85 | 86 | })(); 87 | 88 | // Credits 89 | (function(){ 90 | var page = new Page(); 91 | page.width = 530; 92 | page.height = 400; 93 | page.addComponent(new ModalIframe({ 94 | page: page, 95 | src: "pages/credits.html", 96 | width: 500, 97 | height: 350 98 | })) 99 | self.addPage("credits", page); 100 | })(); 101 | 102 | 103 | // Save as link 104 | (function(){ 105 | var page = new Page(); 106 | page.width = 500; 107 | page.height = 135; 108 | page.addComponent(new ComponentHTML({ 109 | html: "copy your link:" 110 | })); 111 | var output = page.addComponent(new ComponentOutput({})); 112 | 113 | var label = document.createElement("div"); 114 | label.style.textAlign = "right"; 115 | label.style.fontSize = "15px"; 116 | label.style.marginTop = "6px"; 117 | label.style.color = "#888"; 118 | label.innerHTML = "(this is a long URL, so you may want to use a link-shortener like bit.ly)"; 119 | page.dom.appendChild(label); 120 | 121 | page.onshow = function(){ 122 | 123 | // Copy-able link 124 | var link = loopy.saveToURL(); 125 | output.output(link); 126 | output.dom.select(); 127 | 128 | }; 129 | // or, tweet it 130 | self.addPage("save_link", page); 131 | })(); 132 | 133 | // Embed 134 | (function(){ 135 | var page = new Page(); 136 | page.width = 700; 137 | page.height = 500; 138 | 139 | // ON UPDATE DIMENSIONS 140 | var iframeSRC; 141 | var _onUpdate = function(){ 142 | var embedCode = ''; 143 | output.output(embedCode); 144 | }; 145 | 146 | // THE SHTUFF 147 | var sidebar = document.createElement("div"); 148 | sidebar.style.width = "150px"; 149 | sidebar.style.height = "440px"; 150 | sidebar.style.float = "left"; 151 | page.dom.appendChild(sidebar); 152 | 153 | // Label 154 | var label = document.createElement("div"); 155 | label.innerHTML = "
PREVIEW →

"; 156 | sidebar.appendChild(label); 157 | 158 | // Label 2 159 | var label = document.createElement("div"); 160 | label.style.fontSize = "15px"; 161 | label.innerHTML = "what size do you want your embed to be?"; 162 | sidebar.appendChild(label); 163 | 164 | // Size! 165 | var width = _createNumberInput(_onUpdate); 166 | sidebar.appendChild(width.dom); 167 | var label = document.createElement("div"); 168 | label.style.display = "inline-block"; 169 | label.style.fontSize = "15px"; 170 | label.innerHTML = " × "; 171 | sidebar.appendChild(label); 172 | var height = _createNumberInput(_onUpdate); 173 | sidebar.appendChild(height.dom); 174 | 175 | // Label 3 176 | var label = document.createElement("div"); 177 | label.style.fontSize = "15px"; 178 | label.innerHTML = "

copy this code into your website's html:"; 179 | sidebar.appendChild(label); 180 | 181 | // Output! 182 | var output = new ComponentOutput({}); 183 | output.dom.style.fontSize = "12px"; 184 | sidebar.appendChild(output.dom); 185 | 186 | // IFRAME 187 | var iframe = page.addComponent(new ModalIframe({ 188 | page: page, 189 | manual: true, 190 | src: "", 191 | width: 500, 192 | height: 440 193 | })).dom; 194 | iframe.style.float = "right"; 195 | page.onshow = function(){ 196 | 197 | // Default dimensions 198 | width.setValue(500); 199 | height.setValue(440); 200 | 201 | // The iframe! 202 | iframeSRC = loopy.saveToURL(true); 203 | iframe.src = iframeSRC; 204 | 205 | // Select to copy-paste 206 | _onUpdate(); 207 | output.dom.select(); 208 | 209 | }; 210 | page.onhide = function(){ 211 | iframe.removeAttribute("src"); 212 | }; 213 | self.addPage("embed", page); 214 | 215 | 216 | })(); 217 | 218 | // GIF 219 | (function(){ 220 | var page = new Page(); 221 | page.width = 530; 222 | page.height = 400; 223 | page.addComponent(new ModalIframe({ 224 | page: page, 225 | src: "pages/gif.html", 226 | width: 500, 227 | height: 350 228 | })) 229 | self.addPage("save_gif", page); 230 | })(); 231 | 232 | } 233 | 234 | function ModalIframe(config){ 235 | 236 | var self = this; 237 | 238 | // IFRAME 239 | var iframe = document.createElement("iframe"); 240 | self.dom = iframe; 241 | iframe.width = config.width; 242 | iframe.height = config.height; 243 | 244 | // Show & Hide 245 | if(!config.manual){ 246 | config.page.onshow = function(){ 247 | iframe.src = config.src; 248 | }; 249 | config.page.onhide = function(){ 250 | iframe.removeAttribute("src"); 251 | }; 252 | } 253 | 254 | } -------------------------------------------------------------------------------- /splash/js/Mouse.js: -------------------------------------------------------------------------------- 1 | window.Mouse = {}; 2 | Mouse.init = function(target){ 3 | 4 | // Events! 5 | var _onmousedown = function(event){ 6 | Mouse.moved = false; 7 | Mouse.pressed = true; 8 | Mouse.startedOnTarget = true; 9 | publish("mousedown"); 10 | }; 11 | var _onmousemove = function(event){ 12 | 13 | // DO THE INVERSE 14 | var canvasses = document.getElementById("canvasses"); 15 | var tx = 0; 16 | var ty = 0; 17 | var s = 1/loopy.offsetScale; 18 | var CW = canvasses.clientWidth - _PADDING - _PADDING; 19 | var CH = canvasses.clientHeight - _PADDING_BOTTOM - _PADDING; 20 | 21 | if(loopy.embedded){ 22 | tx -= _PADDING/2; // dunno why but this is needed 23 | ty -= _PADDING/2; // dunno why but this is needed 24 | } 25 | 26 | tx -= (CW+_PADDING)/2; 27 | ty -= (CH+_PADDING)/2; 28 | 29 | tx = s*tx; 30 | ty = s*ty; 31 | 32 | tx += (CW+_PADDING)/2; 33 | ty += (CH+_PADDING)/2; 34 | 35 | tx -= loopy.offsetX; 36 | ty -= loopy.offsetY; 37 | 38 | // Mutliply by Mouse vector 39 | var mx = event.x*s + tx; 40 | var my = event.y*s + ty; 41 | 42 | // Mouse! 43 | Mouse.x = mx; 44 | Mouse.y = my; 45 | 46 | Mouse.moved = true; 47 | publish("mousemove"); 48 | 49 | }; 50 | var _onmouseup = function(){ 51 | Mouse.pressed = false; 52 | if(Mouse.startedOnTarget){ 53 | publish("mouseup"); 54 | if(!Mouse.moved) publish("mouseclick"); 55 | } 56 | Mouse.moved = false; 57 | Mouse.startedOnTarget = false; 58 | }; 59 | 60 | // Add mouse & touch events! 61 | Mouse.makeReal = function(){ 62 | _addMouseEvents(target, _onmousedown, _onmousemove, _onmouseup); 63 | }; 64 | 65 | // Cursor & Update 66 | Mouse.target = target; 67 | Mouse.showCursor = function(cursor){ 68 | Mouse.target.style.cursor = cursor; 69 | }; 70 | Mouse.update = function(){ 71 | Mouse.showCursor(""); 72 | }; 73 | 74 | }; -------------------------------------------------------------------------------- /splash/js/PageUI.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | PAGE UI: to extend to Sidebar, Play Controls, Modal. 4 | 5 | **********************************/ 6 | 7 | function PageUI(dom){ 8 | 9 | var self = this; 10 | self.dom = dom; 11 | 12 | self.pages = []; 13 | self.addPage = function(id, page){ 14 | page.id = id; 15 | self.dom.appendChild(page.dom); 16 | self.pages.push(page); 17 | }; 18 | self.currentPage = null; 19 | self.showPage = function(id){ 20 | var shownPage = null; 21 | for(var i=0; i " 131 | + "
"+config.label+"
"; 132 | 133 | self.dom = _createButton(label, function(){ 134 | config.onclick(); 135 | }); 136 | 137 | // Tooltip! 138 | if(config.tooltip){ 139 | self.dom.setAttribute("data-balloon", config.tooltip); 140 | self.dom.setAttribute("data-balloon-pos", "top"); 141 | } 142 | 143 | } 144 | function PlaySlider(config){ 145 | 146 | var self = this; 147 | self.dom = document.createElement("div"); 148 | self.dom.style.bottom = "0px"; 149 | self.dom.style.position = "absolute"; 150 | self.dom.style.width = "100%"; 151 | self.dom.style.height = "20px"; 152 | 153 | // Input 154 | var input = document.createElement("input"); 155 | input.setAttribute("class","play_slider"); 156 | self.dom.appendChild(input); 157 | 158 | // Slow & Fast Icons 159 | var img = new Image(); 160 | img.src = "css/icons/speed_slow.png"; 161 | img.width = 20; 162 | img.height = 15; 163 | img.style.position = "absolute"; 164 | img.style.left = "5px"; 165 | img.style.top = "-2px"; 166 | self.dom.appendChild(img); 167 | var img = new Image(); 168 | img.src = "css/icons/speed_fast.png"; 169 | img.width = 20; 170 | img.height = 15; 171 | img.style.position = "absolute"; 172 | img.style.right = "5px"; 173 | img.style.top = "-2px"; 174 | self.dom.appendChild(img); 175 | 176 | // Properties 177 | input.type = "range"; 178 | input.value = config.value; 179 | input.step = config.step; 180 | input.min = config.min; 181 | input.max = config.max; 182 | input.oninput = function(event){ 183 | config.oninput(input.value); 184 | }; 185 | 186 | } -------------------------------------------------------------------------------- /splash/js/Toolbar.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | TOOLBAR CODE 4 | 5 | **********************************/ 6 | 7 | function Toolbar(loopy){ 8 | 9 | var self = this; 10 | 11 | // Tools & Buttons 12 | var buttons = []; 13 | var buttonsByID = {}; 14 | self.dom = document.getElementById("toolbar"); 15 | self.addButton = function(options){ 16 | 17 | var id = options.id; 18 | var tooltip = options.tooltip; 19 | var callback = options.callback; 20 | 21 | // Add the button 22 | var button = new ToolbarButton(self,{ 23 | id: id, 24 | icon: "css/icons/"+id+".png", 25 | tooltip: tooltip, 26 | callback: callback 27 | }); 28 | self.dom.appendChild(button.dom); 29 | buttons.push(button); 30 | buttonsByID[id] = button; 31 | 32 | // Keyboard shortcut! 33 | (function(id){ 34 | subscribe("key/"+id,function(){ 35 | buttonsByID[id].callback(); 36 | }); 37 | })(id); 38 | 39 | }; 40 | 41 | // Select button 42 | self.selectButton = function(button){ 43 | for(var i=0;i 4 | * MIT Licensed 5 | */ 6 | (function (context) { 7 | var MinPubSub = {}; 8 | 9 | // the topic/subscription hash 10 | var cache = context.c_ || {}; //check for 'c_' cache for unit testing 11 | 12 | MinPubSub.publish = function ( /* String */ topic, /* Array? */ args) { 13 | // summary: 14 | // Publish some data on a named topic. 15 | // topic: String 16 | // The channel to publish on 17 | // args: Array? 18 | // The data to publish. Each array item is converted into an ordered 19 | // arguments on the subscribed functions. 20 | // 21 | // example: 22 | // Publish stuff on '/some/topic'. Anything subscribed will be called 23 | // with a function signature like: function(a,b,c){ ... } 24 | // 25 | // publish('/some/topic', ['a','b','c']); 26 | 27 | var subs = cache[topic], 28 | len = subs ? subs.length : 0; 29 | 30 | //can change loop or reverse array if the order matters 31 | while (len--) { 32 | subs[len].apply(context, args || []); 33 | } 34 | }; 35 | 36 | MinPubSub.subscribe = function ( /* String */ topic, /* Function */ callback) { 37 | // summary: 38 | // Register a callback on a named topic. 39 | // topic: String 40 | // The channel to subscribe to 41 | // callback: Function 42 | // The handler event. Anytime something is publish'ed on a 43 | // subscribed channel, the callback will be called with the 44 | // published array as ordered arguments. 45 | // 46 | // returns: Array 47 | // A handle which can be used to unsubscribe this particular subscription. 48 | // 49 | // example: 50 | // subscribe('/some/topic', function(a, b, c){ /* handle data */ }); 51 | 52 | if (!cache[topic]) { 53 | cache[topic] = []; 54 | } 55 | cache[topic].push(callback); 56 | return [topic, callback]; // Array 57 | }; 58 | 59 | MinPubSub.unsubscribe = function ( /* Array */ handle, /* Function? */ callback) { 60 | // summary: 61 | // Disconnect a subscribed function for a topic. 62 | // handle: Array 63 | // The return value from a subscribe call. 64 | // example: 65 | // var handle = subscribe('/some/topic', function(){}); 66 | // unsubscribe(handle); 67 | 68 | var subs = cache[callback ? handle : handle[0]], 69 | callback = callback || handle[1], 70 | len = subs ? subs.length : 0; 71 | 72 | while (len--) { 73 | if (subs[len] === callback) { 74 | subs.splice(len, 1); 75 | } 76 | } 77 | }; 78 | 79 | // UMD definition to allow for CommonJS, AMD and legacy window 80 | if (typeof module === 'object' && module.exports) { 81 | // CommonJS, just export 82 | module.exports = exports = MinPubSub; 83 | } else if (typeof define === 'function' && define.amd) { 84 | // AMD support 85 | define(function () { 86 | return MinPubSub; 87 | }); 88 | } else if (typeof context === 'object') { 89 | // If no AMD and we are in the browser, attach to window 90 | context.publish = MinPubSub.publish; 91 | context.subscribe = MinPubSub.subscribe; 92 | context.unsubscribe = MinPubSub.unsubscribe; 93 | } 94 | 95 | })(this.window); -------------------------------------------------------------------------------- /v1.1/css/balloon.css: -------------------------------------------------------------------------------- 1 | button[data-balloon] { 2 | overflow: visible; 3 | } 4 | [data-balloon] { 5 | position: relative; 6 | } 7 | [data-balloon]:before, 8 | [data-balloon]:after { 9 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 10 | filter: alpha(opacity=0); 11 | -khtml-opacity: 0; 12 | -moz-opacity: 0; 13 | opacity: 0; 14 | pointer-events: none; 15 | -webkit-transition: all 0.1s ease-out 0.1s; 16 | transition: all 0.1s ease-out 0.1s; 17 | bottom: 100%; 18 | left: 50%; 19 | position: absolute; 20 | z-index: 10; 21 | -webkit-transform: translate(-50%, 10px); 22 | -ms-transform: translate(-50%, 10px); 23 | transform: translate(-50%, 10px); 24 | -webkit-transform-origin: top; 25 | -ms-transform-origin: top; 26 | transform-origin: top; 27 | } 28 | [data-balloon]:after { 29 | background: rgba(17, 17, 17, 0.9); 30 | border-radius: 4px; 31 | color: #fff; 32 | content: attr(data-balloon); 33 | font-size: 18px; 34 | padding: .5em 1em; 35 | white-space: nowrap; 36 | margin-bottom: 11px; 37 | } 38 | [data-balloon]:before { 39 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 40 | background-size: 100% auto; 41 | height: 6px; 42 | width: 18px; 43 | content: ""; 44 | margin-bottom: 5px; 45 | } 46 | [data-balloon]:hover:before, 47 | [data-balloon][data-balloon-visible]:before, 48 | [data-balloon]:hover:after, 49 | [data-balloon][data-balloon-visible]:after { 50 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; 51 | filter: alpha(opacity=100); 52 | -khtml-opacity: 1; 53 | -moz-opacity: 1; 54 | opacity: 1; 55 | pointer-events: auto; 56 | -webkit-transform: translate(-50%, 0); 57 | -ms-transform: translate(-50%, 0); 58 | transform: translate(-50%, 0); 59 | } 60 | [data-balloon].font-awesome:after { 61 | font-family: FontAwesome; 62 | } 63 | [data-balloon][data-balloon-break]:after { 64 | white-space: pre; 65 | } 66 | [data-balloon-pos="down"]:before, 67 | [data-balloon-pos="down"]:after { 68 | bottom: auto; 69 | left: 50%; 70 | top: 100%; 71 | -webkit-transform: translate(-50%, -10px); 72 | -ms-transform: translate(-50%, -10px); 73 | transform: translate(-50%, -10px); 74 | } 75 | [data-balloon-pos="down"]:after { 76 | margin-top: 11px; 77 | } 78 | [data-balloon-pos="down"]:before { 79 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 80 | background-size: 100% auto; 81 | height: 6px; 82 | width: 18px; 83 | margin-top: 5px; 84 | margin-bottom: 0; 85 | } 86 | [data-balloon-pos="down"]:hover:before, 87 | [data-balloon-pos="down"][data-balloon-visible]:before, 88 | [data-balloon-pos="down"]:hover:after, 89 | [data-balloon-pos="down"][data-balloon-visible]:after { 90 | -webkit-transform: translate(-50%, 0); 91 | -ms-transform: translate(-50%, 0); 92 | transform: translate(-50%, 0); 93 | } 94 | [data-balloon-pos="left"]:before, 95 | [data-balloon-pos="left"]:after { 96 | bottom: auto; 97 | left: auto; 98 | right: 100%; 99 | top: 50%; 100 | -webkit-transform: translate(10px, -50%); 101 | -ms-transform: translate(10px, -50%); 102 | transform: translate(10px, -50%); 103 | } 104 | [data-balloon-pos="left"]:after { 105 | margin-right: 11px; 106 | } 107 | [data-balloon-pos="left"]:before { 108 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 109 | background-size: 100% auto; 110 | height: 18px; 111 | width: 6px; 112 | margin-right: 5px; 113 | margin-bottom: 0; 114 | } 115 | [data-balloon-pos="left"]:hover:before, 116 | [data-balloon-pos="left"][data-balloon-visible]:before, 117 | [data-balloon-pos="left"]:hover:after, 118 | [data-balloon-pos="left"][data-balloon-visible]:after { 119 | -webkit-transform: translate(0, -50%); 120 | -ms-transform: translate(0, -50%); 121 | transform: translate(0, -50%); 122 | } 123 | [data-balloon-pos="right"]:before, 124 | [data-balloon-pos="right"]:after { 125 | bottom: auto; 126 | left: 100%; 127 | top: 50%; 128 | -webkit-transform: translate(-10px, -50%); 129 | -ms-transform: translate(-10px, -50%); 130 | transform: translate(-10px, -50%); 131 | } 132 | [data-balloon-pos="right"]:after { 133 | margin-left: 11px; 134 | } 135 | [data-balloon-pos="right"]:before { 136 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 137 | background-size: 100% auto; 138 | height: 18px; 139 | width: 6px; 140 | margin-bottom: 0; 141 | margin-left: 5px; 142 | } 143 | [data-balloon-pos="right"]:hover:before, 144 | [data-balloon-pos="right"][data-balloon-visible]:before, 145 | [data-balloon-pos="right"]:hover:after, 146 | [data-balloon-pos="right"][data-balloon-visible]:after { 147 | -webkit-transform: translate(0, -50%); 148 | -ms-transform: translate(0, -50%); 149 | transform: translate(0, -50%); 150 | } 151 | [data-balloon-length]:after { 152 | white-space: normal; 153 | } 154 | [data-balloon-length="small"]:after { 155 | width: 80px; 156 | } 157 | [data-balloon-length="medium"]:after { 158 | width: 150px; 159 | } 160 | [data-balloon-length="large"]:after { 161 | width: 260px; 162 | } 163 | [data-balloon-length="xlarge"]:after { 164 | width: 90vw; 165 | } 166 | @media screen and (min-width: 768px) { 167 | [data-balloon-length="xlarge"]:after { 168 | width: 380px; 169 | } 170 | } 171 | [data-balloon-length="fit"]:after { 172 | width: 100%; 173 | } 174 | -------------------------------------------------------------------------------- /v1.1/css/cursors/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/cursors/drag.png -------------------------------------------------------------------------------- /v1.1/css/cursors/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/cursors/erase.png -------------------------------------------------------------------------------- /v1.1/css/cursors/ink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/cursors/ink.png -------------------------------------------------------------------------------- /v1.1/css/cursors/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/cursors/label.png -------------------------------------------------------------------------------- /v1.1/css/icons/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/controls.png -------------------------------------------------------------------------------- /v1.1/css/icons/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/drag.png -------------------------------------------------------------------------------- /v1.1/css/icons/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/erase.png -------------------------------------------------------------------------------- /v1.1/css/icons/ink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/ink.png -------------------------------------------------------------------------------- /v1.1/css/icons/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/label.png -------------------------------------------------------------------------------- /v1.1/css/icons/speed_fast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/speed_fast.png -------------------------------------------------------------------------------- /v1.1/css/icons/speed_slow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/icons/speed_slow.png -------------------------------------------------------------------------------- /v1.1/css/loopy.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin:0; 3 | background: #fff; 4 | 5 | font-family: Helvetica, Arial, sans-serif; 6 | font-weight: normal; 7 | font-size: 20px; 8 | 9 | overflow: hidden; 10 | } 11 | canvas{ 12 | position:absolute; 13 | top:0; left:0; 14 | } 15 | 16 | #canvasses{ 17 | position:absolute; 18 | top:0; left:0; 19 | width: calc(100% - 300px); 20 | height: 100%; 21 | } 22 | #canvasses[fullscreen=yes]{ 23 | width: 100%; 24 | } 25 | #canvasses[cursor=ink]{ 26 | cursor: url('cursors/ink.png') 0 30, auto; 27 | } 28 | #canvasses[cursor=drag]{ 29 | cursor: url('cursors/drag.png') 15 15, auto; 30 | } 31 | #canvasses[cursor=erase]{ 32 | cursor: url('cursors/erase.png') 5 25, auto; 33 | } 34 | #canvasses[cursor=label]{ 35 | cursor: url('cursors/label.png') 15 15, auto; 36 | } 37 | 38 | 39 | 40 | /********** 41 | PLAY CONTROLS 42 | **********/ 43 | 44 | #playbar{ 45 | position: absolute; 46 | bottom: 15px; 47 | left: calc(50% - 275px); /* 50% - half of (playbar width + sidebar width)*/ 48 | 49 | width: 250px; 50 | height: 75px; 51 | 52 | -webkit-user-select: none; 53 | -moz-user-select: none; 54 | -ms-user-select: none; 55 | user-select: none; 56 | } 57 | #playbar[fullscreen=yes]{ 58 | left: calc(50% - 125px); /* 50% - half of (playbar width)*/ 59 | } 60 | #playbar .component_button{ 61 | position: absolute; 62 | bottom: 0; 63 | width: 230px; 64 | height: 25px; 65 | background: #444; 66 | } 67 | #playbar .component_button:hover{ 68 | background: #555; 69 | } 70 | #playbar .play_slider{ 71 | width: 190px; 72 | position: absolute; 73 | left: 30px; 74 | margin: 0; 75 | } 76 | .play_button_icon{ 77 | width: 25px; 78 | height: 25px; 79 | background-image: url(icons/controls.png); 80 | display: inline-block; 81 | background-size: 400% 100%; 82 | } 83 | .play_button_icon[icon="0"]{ background-position: 0 0; } 84 | .play_button_icon[icon="1"]{ background-position: -25px 0; } 85 | .play_button_icon[icon="2"]{ background-position: -50px 0; } 86 | .play_button_icon[icon="3"]{ background-position: -75px 0; } 87 | .play_button_label{ 88 | display: inline-block; 89 | position: relative; 90 | top: -5px; 91 | } 92 | div[big=yes] .play_button_icon{ 93 | width: 30px; 94 | height: 30px; 95 | } 96 | div[big=yes] .play_button_label{ 97 | top: -3px; 98 | } 99 | 100 | 101 | 102 | /********** 103 | TOOLBAR 104 | **********/ 105 | 106 | #toolbar{ 107 | position: absolute; 108 | left: 0px; 109 | top: calc(33% - 142.5px); /* 33% - half of toolbar height */ 110 | 111 | width:75px; height:280px; 112 | padding: 5px; 113 | background-color: #ddd; 114 | 115 | -webkit-user-select: none; 116 | -moz-user-select: none; 117 | -ms-user-select: none; 118 | user-select: none; 119 | } 120 | #toolbar[mode=play]{ 121 | display: none; 122 | } 123 | 124 | .toolbar_button{ 125 | width:60px; height:60px; 126 | margin: 5px; 127 | border: 2px solid #ddd; 128 | cursor: pointer; 129 | background-size: 100% 100%; 130 | } 131 | .toolbar_button[selected=yes]{ 132 | border: 2px solid #888; 133 | background-color: #999; 134 | } 135 | 136 | /********** 137 | SIDEBAR 138 | **********/ 139 | 140 | #sidebar{ 141 | position: absolute; 142 | top:0; right:0; 143 | width: 300px; 144 | height: 100%; 145 | background: #ddd; 146 | 147 | font-weight: 100; 148 | font-size: 17px; 149 | 150 | -webkit-user-select: none; 151 | -moz-user-select: none; 152 | -ms-user-select: none; 153 | user-select: none; 154 | } 155 | #sidebar > div{ 156 | margin: 25px; 157 | } 158 | #sidebar > div > div{ 159 | margin-bottom: 20px; 160 | } 161 | #sidebar[mode=play]{ 162 | background: #222; 163 | color: #777; 164 | } 165 | #sidebar .mini_button{ 166 | background: #999; 167 | color: #fff; 168 | padding: 3px 5px; 169 | border-radius: 2px; 170 | font-size: 16px; 171 | 172 | cursor: pointer; 173 | } 174 | #sidebar .mini_button:hover{ 175 | background: #aaa; 176 | } 177 | #sidebar[mode=play] .mini_button{ 178 | background: #555; 179 | color: #111; 180 | } 181 | #sidebar[mode=play] .mini_button:hover{ 182 | background: #666; 183 | } 184 | #sidebar a{ color: #777; } 185 | #sidebar a:hover{ color: #999; } 186 | #sidebar hr{ 187 | border: none; 188 | border-bottom: 2px solid rgba(150,150,150,0.5); 189 | width: 300px; 190 | position: relative; 191 | left:-25px; 192 | margin: 10px 0; 193 | } 194 | .component_input{ 195 | border: none; 196 | 197 | width:calc(100% - 10px); 198 | height:22px; 199 | padding: 5px; 200 | 201 | font-size: 20px; 202 | font-weight: 100; 203 | } 204 | .component_textarea{ 205 | border: none; 206 | width:calc(100% - 10px); 207 | height: 100px; 208 | padding: 5px; 209 | font-size: 16px; 210 | font-weight: 100; 211 | } 212 | .component_output{ 213 | border: 1px solid #aaa; 214 | width:100%; 215 | background: #ccc; 216 | color: #666; 217 | font-size: 15px; 218 | font-weight: 100; 219 | } 220 | .component_slider{ 221 | position: relative; 222 | width: 250px; 223 | height: 52px; 224 | } 225 | .component_slider_graphic{ 226 | position: absolute; 227 | width: 250px; 228 | height: 40px; 229 | cursor: pointer; 230 | } 231 | .component_slider_pointer{ 232 | position: absolute; 233 | top: 42px; 234 | width: 15px; 235 | height: 10px; 236 | } 237 | .component_label{ 238 | margin-bottom: 5px; 239 | } 240 | .component_button{ 241 | 242 | width: calc(100% - 20px); 243 | background: #888; 244 | color: #fff; 245 | font-size: 20px; 246 | font-weight: 100; 247 | text-align: center; 248 | padding: 10px; 249 | border-radius: 5px; 250 | 251 | cursor: pointer; 252 | } 253 | .component_button:hover{ 254 | background: #999; 255 | } 256 | .component_button[header=yes]{ 257 | position: absolute; 258 | top:0; left:0; 259 | width: 280px; 260 | background: #222; 261 | border-radius: 0px; 262 | color: #888; 263 | } 264 | .component_button[header=yes]:hover{ 265 | background: #333; 266 | } 267 | 268 | 269 | 270 | /********** 271 | 272 | MODAL 273 | 274 | **********/ 275 | 276 | #modal_container{ 277 | display: none; 278 | position: absolute; 279 | width: 100%; height: 100%; 280 | 281 | -webkit-user-select: none; 282 | -moz-user-select: none; 283 | -ms-user-select: none; 284 | user-select: none; 285 | } 286 | #modal_container[show=yes]{ 287 | display: block; 288 | } 289 | #modal_bg{ 290 | position: absolute; 291 | width: 100%; height: 100%; 292 | background: rgba(0,0,0,0.8); 293 | } 294 | #modal{ 295 | 296 | position: absolute; 297 | top:0; left:0; right:0; bottom:0; 298 | margin: auto; 299 | 300 | width: 600px; height: 300px; 301 | padding: 10px; 302 | background: #ddd; 303 | } 304 | #modal_close{ 305 | width: 120px; 306 | font-weight: 100; 307 | color: #777; 308 | cursor: pointer; 309 | } 310 | #modal_close:hover{ 311 | color: #888; 312 | } 313 | #modal_page{ 314 | margin: 15px; 315 | font-size: 25px; 316 | font-weight: 100; 317 | color: #333; 318 | } 319 | #modal iframe{ 320 | border: none; 321 | } 322 | -------------------------------------------------------------------------------- /v1.1/css/sliders/color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/sliders/color.png -------------------------------------------------------------------------------- /v1.1/css/sliders/initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/sliders/initial.png -------------------------------------------------------------------------------- /v1.1/css/sliders/slider_pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/sliders/slider_pointer.png -------------------------------------------------------------------------------- /v1.1/css/sliders/strength.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/sliders/strength.png -------------------------------------------------------------------------------- /v1.1/css/sliders/strength_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/css/sliders/strength_original.png -------------------------------------------------------------------------------- /v1.1/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/favicon.png -------------------------------------------------------------------------------- /v1.1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LOOPY (v1.1) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 | 43 |
44 |
45 | 46 | 47 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /v1.1/js/Dragger.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | DRAGGER 4 | 5 | **********************************/ 6 | 7 | function Dragger(loopy){ 8 | 9 | var self = this; 10 | self.loopy = loopy; 11 | 12 | // Dragging anything? 13 | self.dragging = null; 14 | self.offsetX = 0; 15 | self.offsetY = 0; 16 | 17 | subscribe("mousedown",function(){ 18 | 19 | // ONLY WHEN EDITING w DRAG 20 | if(self.loopy.mode!=Loopy.MODE_EDIT) return; 21 | if(self.loopy.tool!=Loopy.TOOL_DRAG) return; 22 | 23 | // Any node under here? If so, start dragging! 24 | var dragNode = loopy.model.getNodeByPoint(Mouse.x, Mouse.y); 25 | if(dragNode){ 26 | self.dragging = dragNode; 27 | self.offsetX = Mouse.x - dragNode.x; 28 | self.offsetY = Mouse.y - dragNode.y; 29 | loopy.sidebar.edit(dragNode); // and edit! 30 | return; 31 | } 32 | 33 | // Any label under here? If so, start dragging! 34 | var dragLabel = loopy.model.getLabelByPoint(Mouse.x, Mouse.y); 35 | if(dragLabel){ 36 | self.dragging = dragLabel; 37 | self.offsetX = Mouse.x - dragLabel.x; 38 | self.offsetY = Mouse.y - dragLabel.y; 39 | loopy.sidebar.edit(dragLabel); // and edit! 40 | return; 41 | } 42 | 43 | // Any edge under here? If so, start dragging! 44 | var dragEdge = loopy.model.getEdgeByPoint(Mouse.x, Mouse.y); 45 | if(dragEdge){ 46 | self.dragging = dragEdge; 47 | self.offsetX = Mouse.x - dragEdge.labelX; 48 | self.offsetY = Mouse.y - dragEdge.labelY; 49 | loopy.sidebar.edit(dragEdge); // and edit! 50 | return; 51 | } 52 | 53 | }); 54 | subscribe("mousemove",function(){ 55 | 56 | // ONLY WHEN EDITING w DRAG 57 | if(self.loopy.mode!=Loopy.MODE_EDIT) return; 58 | if(self.loopy.tool!=Loopy.TOOL_DRAG) return; 59 | 60 | // If you're dragging a NODE, move it around! 61 | if(self.dragging && self.dragging._CLASS_=="Node"){ 62 | 63 | // Model's been changed! 64 | publish("model/changed"); 65 | 66 | var node = self.dragging; 67 | node.x = Mouse.x - self.offsetX; 68 | node.y = Mouse.y - self.offsetY; 69 | 70 | // update coz visual glitches 71 | loopy.model.update(); 72 | 73 | } 74 | 75 | // If you're dragging an EDGE, move it around! 76 | if(self.dragging && self.dragging._CLASS_=="Edge"){ 77 | 78 | // Model's been changed! 79 | publish("model/changed"); 80 | 81 | var edge = self.dragging; 82 | var labelX = Mouse.x - self.offsetX; 83 | var labelY = Mouse.y - self.offsetY; 84 | 85 | if(edge.from!=edge.to){ 86 | 87 | // The Arc: whatever label *Y* is, relative to angle & first node's pos 88 | var fx=edge.from.x, fy=edge.from.y, tx=edge.to.x, ty=edge.to.y; 89 | var dx=tx-fx, dy=ty-fy; 90 | var a = Math.atan2(dy,dx); 91 | 92 | // Calculate arc 93 | var points = [[labelX,labelY]]; 94 | var translated = _translatePoints(points, -fx, -fy); 95 | var rotated = _rotatePoints(translated, -a); 96 | var newLabelPoint = rotated[0]; 97 | 98 | // ooookay. 99 | edge.arc = -newLabelPoint[1]; // WHY NEGATIVE? I DON'T KNOW. 100 | 101 | }else{ 102 | 103 | // For SELF-ARROWS: just get angle & mag for label. 104 | var dx = labelX - edge.from.x, 105 | dy = labelY - edge.from.y; 106 | var a = Math.atan2(dy,dx); 107 | var mag = Math.sqrt(dx*dx + dy*dy); 108 | 109 | // Minimum mag 110 | var minimum = edge.from.radius+25; 111 | if(magMath.abs(bounds.bottom)) edgeConfig.arc = -bounds.top; 161 | else edgeConfig.arc = -bounds.bottom; 162 | 163 | } 164 | 165 | // Add the edge! 166 | if(edgeConfig){ 167 | var newEdge = loopy.model.addEdge(edgeConfig); 168 | loopy.sidebar.edit(newEdge); 169 | } 170 | 171 | } 172 | 173 | // NODE: did NOT start in a node. 174 | if(!startNode){ 175 | 176 | // Just roughly make a circle the size of the bounds of the circle 177 | var bounds = _getBounds(self.strokeData); 178 | var x = (bounds.left+bounds.right)/2; 179 | var y = (bounds.top+bounds.bottom)/2; 180 | var r = ((bounds.width/2)+(bounds.height/2))/2; 181 | 182 | // Circle can't be TOO smol 183 | if(r>15){ 184 | 185 | // Snap to radius 186 | /*r = Math.round(r/Ink.SNAP_TO_RADIUS)*Ink.SNAP_TO_RADIUS; 187 | if(r " 131 | + "
"+config.label+"
"; 132 | 133 | self.dom = _createButton(label, function(){ 134 | config.onclick(); 135 | }); 136 | 137 | // Tooltip! 138 | if(config.tooltip){ 139 | self.dom.setAttribute("data-balloon", config.tooltip); 140 | self.dom.setAttribute("data-balloon-pos", "top"); 141 | } 142 | 143 | } 144 | function PlaySlider(config){ 145 | 146 | var self = this; 147 | self.dom = document.createElement("div"); 148 | self.dom.style.bottom = "0px"; 149 | self.dom.style.position = "absolute"; 150 | self.dom.style.width = "100%"; 151 | self.dom.style.height = "20px"; 152 | 153 | // Input 154 | var input = document.createElement("input"); 155 | input.setAttribute("class","play_slider"); 156 | self.dom.appendChild(input); 157 | 158 | // Slow & Fast Icons 159 | var img = new Image(); 160 | img.src = "css/icons/speed_slow.png"; 161 | img.width = 20; 162 | img.height = 15; 163 | img.style.position = "absolute"; 164 | img.style.left = "5px"; 165 | img.style.top = "-2px"; 166 | self.dom.appendChild(img); 167 | var img = new Image(); 168 | img.src = "css/icons/speed_fast.png"; 169 | img.width = 20; 170 | img.height = 15; 171 | img.style.position = "absolute"; 172 | img.style.right = "5px"; 173 | img.style.top = "-2px"; 174 | self.dom.appendChild(img); 175 | 176 | // Properties 177 | input.type = "range"; 178 | input.value = config.value; 179 | input.step = config.step; 180 | input.min = config.min; 181 | input.max = config.max; 182 | input.oninput = function(event){ 183 | config.oninput(input.value); 184 | }; 185 | 186 | } -------------------------------------------------------------------------------- /v1.1/js/Toolbar.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | TOOLBAR CODE 4 | 5 | **********************************/ 6 | 7 | function Toolbar(loopy){ 8 | 9 | var self = this; 10 | 11 | // Tools & Buttons 12 | var buttons = []; 13 | var buttonsByID = {}; 14 | self.dom = document.getElementById("toolbar"); 15 | self.addButton = function(options){ 16 | 17 | var id = options.id; 18 | var tooltip = options.tooltip; 19 | var callback = options.callback; 20 | 21 | // Add the button 22 | var button = new ToolbarButton(self,{ 23 | id: id, 24 | icon: "css/icons/"+id+".png", 25 | tooltip: tooltip, 26 | callback: callback 27 | }); 28 | self.dom.appendChild(button.dom); 29 | buttons.push(button); 30 | buttonsByID[id] = button; 31 | 32 | // Keyboard shortcut! 33 | (function(id){ 34 | subscribe("key/"+id,function(){ 35 | loopy.ink.reset(); // also CLEAR INK CANVAS 36 | buttonsByID[id].callback(); 37 | }); 38 | })(id); 39 | 40 | }; 41 | 42 | // Select button 43 | self.selectButton = function(button){ 44 | for(var i=0;i 4 | * MIT Licensed 5 | */ 6 | (function (context) { 7 | var MinPubSub = {}; 8 | 9 | // the topic/subscription hash 10 | var cache = context.c_ || {}; //check for 'c_' cache for unit testing 11 | 12 | MinPubSub.publish = function ( /* String */ topic, /* Array? */ args) { 13 | // summary: 14 | // Publish some data on a named topic. 15 | // topic: String 16 | // The channel to publish on 17 | // args: Array? 18 | // The data to publish. Each array item is converted into an ordered 19 | // arguments on the subscribed functions. 20 | // 21 | // example: 22 | // Publish stuff on '/some/topic'. Anything subscribed will be called 23 | // with a function signature like: function(a,b,c){ ... } 24 | // 25 | // publish('/some/topic', ['a','b','c']); 26 | 27 | var subs = cache[topic], 28 | len = subs ? subs.length : 0; 29 | 30 | //can change loop or reverse array if the order matters 31 | while (len--) { 32 | subs[len].apply(context, args || []); 33 | } 34 | }; 35 | 36 | MinPubSub.subscribe = function ( /* String */ topic, /* Function */ callback) { 37 | // summary: 38 | // Register a callback on a named topic. 39 | // topic: String 40 | // The channel to subscribe to 41 | // callback: Function 42 | // The handler event. Anytime something is publish'ed on a 43 | // subscribed channel, the callback will be called with the 44 | // published array as ordered arguments. 45 | // 46 | // returns: Array 47 | // A handle which can be used to unsubscribe this particular subscription. 48 | // 49 | // example: 50 | // subscribe('/some/topic', function(a, b, c){ /* handle data */ }); 51 | 52 | if (!cache[topic]) { 53 | cache[topic] = []; 54 | } 55 | cache[topic].push(callback); 56 | return [topic, callback]; // Array 57 | }; 58 | 59 | MinPubSub.unsubscribe = function ( /* Array */ handle, /* Function? */ callback) { 60 | // summary: 61 | // Disconnect a subscribed function for a topic. 62 | // handle: Array 63 | // The return value from a subscribe call. 64 | // example: 65 | // var handle = subscribe('/some/topic', function(){}); 66 | // unsubscribe(handle); 67 | 68 | var subs = cache[callback ? handle : handle[0]], 69 | callback = callback || handle[1], 70 | len = subs ? subs.length : 0; 71 | 72 | while (len--) { 73 | if (subs[len] === callback) { 74 | subs.splice(len, 1); 75 | } 76 | } 77 | }; 78 | 79 | // UMD definition to allow for CommonJS, AMD and legacy window 80 | if (typeof module === 'object' && module.exports) { 81 | // CommonJS, just export 82 | module.exports = exports = MinPubSub; 83 | } else if (typeof define === 'function' && define.amd) { 84 | // AMD support 85 | define(function () { 86 | return MinPubSub; 87 | }); 88 | } else if (typeof context === 'object') { 89 | // If no AMD and we are in the browser, attach to window 90 | context.publish = MinPubSub.publish; 91 | context.subscribe = MinPubSub.subscribe; 92 | context.unsubscribe = MinPubSub.unsubscribe; 93 | } 94 | 95 | })(this.window); -------------------------------------------------------------------------------- /v1.1/pages/credits/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/favicon.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/aimee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/aimee.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/buster.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/chad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/chad.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/jared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/jared.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/ljt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/ljt.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/mark.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/matt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/matt.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/michael_duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/michael_duke.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/michael_huff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/michael_huff.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/natalie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/natalie.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/nicholas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/nicholas.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/noel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/noel.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/phil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/phil.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/philippe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/philippe.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/thomas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/thomas.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/travis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/travis.png -------------------------------------------------------------------------------- /v1.1/pages/credits/peep/yu-han.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/peep/yu-han.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/aimee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/aimee.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/buster.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/cedric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/cedric.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/chad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/chad.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/dylan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/dylan.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/dylan_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/dylan_s.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/feiya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/feiya.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/glen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/glen.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/iago.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/iago.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/jared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/jared.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/karen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/karen.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/kate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/kate.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/kevin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/kevin.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/klemen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/klemen.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/kuerqing1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/kuerqing1024.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/ljt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/ljt.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/mark.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/matt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/matt.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/michael_duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/michael_duke.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/michael_huff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/michael_huff.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/michelle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/michelle.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/natalie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/natalie.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/nicholas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/nicholas.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/nimrod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/nimrod.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/noel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/noel.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/phil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/phil.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/philippe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/philippe.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/rob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/rob.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/thomas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/thomas.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/travis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/travis.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/william.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/william.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/yu-han.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/yu-han.png -------------------------------------------------------------------------------- /v1.1/pages/credits/polygon/zach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/credits/polygon/zach.png -------------------------------------------------------------------------------- /v1.1/pages/examples/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/examples/favicon.png -------------------------------------------------------------------------------- /v1.1/pages/gif.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Step 1: download LICEcap, 10 | a free open-source tool to record GIFs (Windows/Mac only. Linux users, try 11 | Peek) 12 |

13 | Step 2: record a GIF while playing around in LOOPY 14 |

15 | Step 3: ta-dah 16 |

17 |
18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /v1.1/pages/gifs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/gifs.gif -------------------------------------------------------------------------------- /v1.1/pages/howto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /v1.1/pages/howto/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/howto/1.png -------------------------------------------------------------------------------- /v1.1/pages/howto/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/howto/2.png -------------------------------------------------------------------------------- /v1.1/pages/howto/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/howto/3.png -------------------------------------------------------------------------------- /v1.1/pages/howto/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/howto/4.png -------------------------------------------------------------------------------- /v1.1/pages/howto/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1.1/pages/howto/5.png -------------------------------------------------------------------------------- /v1.1/pages/page.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background: #ddd; 3 | font-family: Helvetica, Arial, sans-serif; 4 | font-weight: 100; 5 | font-size: 19px; 6 | color: #222; 7 | margin: 0; 8 | } 9 | .full{ 10 | width:100%; 11 | margin: 0; 12 | display: block; 13 | } 14 | .shadow{ 15 | width:100%; height: 100%; 16 | position: fixed; 17 | top:0; left:0; 18 | box-shadow: inset 0 0 20px rgba(0,0,0,0.75); 19 | } 20 | 21 | /********************************/ 22 | /********************************/ 23 | 24 | #examples{ 25 | width: 620px; 26 | margin:0 auto; 27 | overflow: hidden; 28 | } 29 | 30 | #examples hr{ 31 | border:none; 32 | border-bottom: 2px dashed #aaa; 33 | width: 560px; 34 | margin: 0 auto; 35 | margin-top: 15px; 36 | } 37 | 38 | #more_examples{ 39 | color: #333; 40 | width: 500px; 41 | margin: 30px auto; 42 | } 43 | #more_examples li{ 44 | color: #666; 45 | margin-bottom: 1em; 46 | position: relative; 47 | left: -0.8em; 48 | } 49 | #more_examples li a{ 50 | color: #dd4040; 51 | } 52 | #more_examples li a:hover{ 53 | color: #ee6060; 54 | } 55 | #more_examples li a.twitter{ 56 | color: inherit; 57 | } 58 | 59 | .example{ 60 | display: block; 61 | float: left; 62 | width: 180px; 63 | height: 180px; 64 | 65 | cursor: pointer; 66 | transform: scale(1); 67 | transition: all 0.2s ease-in-out; 68 | } 69 | .example:hover{ 70 | transform: scale(1.1); 71 | } 72 | .example > div{ 73 | width: 180px; 74 | height: 180px; 75 | background: #888; 76 | border-radius: 100px; 77 | float: left; 78 | position: relative; 79 | } 80 | .example > div > div{ 81 | font-size: 25px; 82 | color: #fff; 83 | width: 150px; 84 | height: 55px; 85 | position: absolute; 86 | top:0; left:0; right:0; bottom:0; 87 | margin: auto; 88 | text-align: center; 89 | } 90 | .example:nth-child(n+2){ 91 | margin-left: 19px; 92 | } 93 | 94 | /********************************/ 95 | /********************************/ 96 | 97 | #credits{ 98 | width: 600px; 99 | margin: 50px auto; 100 | font-weight: 100; 101 | color: #fff; 102 | font-size: 20px; 103 | } 104 | 105 | .credit_intro{ 106 | font-size: 26px; 107 | } 108 | .credit_intro a{ 109 | color: #dd3939; 110 | } 111 | .credit_intro a:hover{ 112 | color: #ee6060; 113 | } 114 | 115 | #credits hr{ 116 | border:none; 117 | border-bottom: 4px dashed #444; 118 | margin-top: 30px; 119 | } 120 | 121 | .credits_peeps{ 122 | overflow: hidden; 123 | padding-bottom: 20px; 124 | text-align: center; 125 | } 126 | .credits_peeps > div{ 127 | position: relative; 128 | width: 150px; 129 | height: 210px; 130 | text-align: center; 131 | display: inline-block; 132 | margin-right: -6px; 133 | } 134 | .credits_peeps > div > img:nth-child(1){ 135 | position: absolute; 136 | left: 0; 137 | width: 150px; 138 | bottom: 30px; 139 | } 140 | .credits_peeps > div > img:nth-child(2){ 141 | position: absolute; 142 | width: 50px; 143 | right: 5px; 144 | bottom: 30px; 145 | } 146 | .credits_peeps > div > span{ 147 | display: block; 148 | position: absolute; 149 | bottom:0; 150 | width: 150px; 151 | height: 20px; 152 | text-transform: lowercase; 153 | } 154 | 155 | .credits_polygons{ 156 | margin-top: 15px; 157 | overflow: hidden; 158 | color: #ddd; 159 | font-size: 18px; 160 | padding-bottom: 20px; 161 | text-align: center; 162 | } 163 | .credits_polygons > div{ 164 | display: inline-block; 165 | } 166 | .credits_polygons > div > img{ 167 | width: 40px; 168 | position: relative; 169 | top:10px; 170 | } 171 | .credits_polygons > div > span{ 172 | text-transform: lowercase; 173 | } 174 | 175 | .credits_names{ 176 | margin-top: 30px; 177 | overflow: hidden; 178 | color: #bbb; 179 | font-size: 16px; 180 | padding-bottom: 20px; 181 | text-align: center; 182 | -webkit-columns: 150px 3; 183 | -moz-columns: 150px 3; 184 | columns: 150px 3; 185 | } -------------------------------------------------------------------------------- /v1/css/balloon.css: -------------------------------------------------------------------------------- 1 | button[data-balloon] { 2 | overflow: visible; 3 | } 4 | [data-balloon] { 5 | position: relative; 6 | } 7 | [data-balloon]:before, 8 | [data-balloon]:after { 9 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 10 | filter: alpha(opacity=0); 11 | -khtml-opacity: 0; 12 | -moz-opacity: 0; 13 | opacity: 0; 14 | pointer-events: none; 15 | -webkit-transition: all 0.1s ease-out 0.1s; 16 | transition: all 0.1s ease-out 0.1s; 17 | bottom: 100%; 18 | left: 50%; 19 | position: absolute; 20 | z-index: 10; 21 | -webkit-transform: translate(-50%, 10px); 22 | -ms-transform: translate(-50%, 10px); 23 | transform: translate(-50%, 10px); 24 | -webkit-transform-origin: top; 25 | -ms-transform-origin: top; 26 | transform-origin: top; 27 | } 28 | [data-balloon]:after { 29 | background: rgba(17, 17, 17, 0.9); 30 | border-radius: 4px; 31 | color: #fff; 32 | content: attr(data-balloon); 33 | font-size: 18px; 34 | padding: .5em 1em; 35 | white-space: nowrap; 36 | margin-bottom: 11px; 37 | } 38 | [data-balloon]:before { 39 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 40 | background-size: 100% auto; 41 | height: 6px; 42 | width: 18px; 43 | content: ""; 44 | margin-bottom: 5px; 45 | } 46 | [data-balloon]:hover:before, 47 | [data-balloon][data-balloon-visible]:before, 48 | [data-balloon]:hover:after, 49 | [data-balloon][data-balloon-visible]:after { 50 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; 51 | filter: alpha(opacity=100); 52 | -khtml-opacity: 1; 53 | -moz-opacity: 1; 54 | opacity: 1; 55 | pointer-events: auto; 56 | -webkit-transform: translate(-50%, 0); 57 | -ms-transform: translate(-50%, 0); 58 | transform: translate(-50%, 0); 59 | } 60 | [data-balloon].font-awesome:after { 61 | font-family: FontAwesome; 62 | } 63 | [data-balloon][data-balloon-break]:after { 64 | white-space: pre; 65 | } 66 | [data-balloon-pos="down"]:before, 67 | [data-balloon-pos="down"]:after { 68 | bottom: auto; 69 | left: 50%; 70 | top: 100%; 71 | -webkit-transform: translate(-50%, -10px); 72 | -ms-transform: translate(-50%, -10px); 73 | transform: translate(-50%, -10px); 74 | } 75 | [data-balloon-pos="down"]:after { 76 | margin-top: 11px; 77 | } 78 | [data-balloon-pos="down"]:before { 79 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 80 | background-size: 100% auto; 81 | height: 6px; 82 | width: 18px; 83 | margin-top: 5px; 84 | margin-bottom: 0; 85 | } 86 | [data-balloon-pos="down"]:hover:before, 87 | [data-balloon-pos="down"][data-balloon-visible]:before, 88 | [data-balloon-pos="down"]:hover:after, 89 | [data-balloon-pos="down"][data-balloon-visible]:after { 90 | -webkit-transform: translate(-50%, 0); 91 | -ms-transform: translate(-50%, 0); 92 | transform: translate(-50%, 0); 93 | } 94 | [data-balloon-pos="left"]:before, 95 | [data-balloon-pos="left"]:after { 96 | bottom: auto; 97 | left: auto; 98 | right: 100%; 99 | top: 50%; 100 | -webkit-transform: translate(10px, -50%); 101 | -ms-transform: translate(10px, -50%); 102 | transform: translate(10px, -50%); 103 | } 104 | [data-balloon-pos="left"]:after { 105 | margin-right: 11px; 106 | } 107 | [data-balloon-pos="left"]:before { 108 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 109 | background-size: 100% auto; 110 | height: 18px; 111 | width: 6px; 112 | margin-right: 5px; 113 | margin-bottom: 0; 114 | } 115 | [data-balloon-pos="left"]:hover:before, 116 | [data-balloon-pos="left"][data-balloon-visible]:before, 117 | [data-balloon-pos="left"]:hover:after, 118 | [data-balloon-pos="left"][data-balloon-visible]:after { 119 | -webkit-transform: translate(0, -50%); 120 | -ms-transform: translate(0, -50%); 121 | transform: translate(0, -50%); 122 | } 123 | [data-balloon-pos="right"]:before, 124 | [data-balloon-pos="right"]:after { 125 | bottom: auto; 126 | left: 100%; 127 | top: 50%; 128 | -webkit-transform: translate(-10px, -50%); 129 | -ms-transform: translate(-10px, -50%); 130 | transform: translate(-10px, -50%); 131 | } 132 | [data-balloon-pos="right"]:after { 133 | margin-left: 11px; 134 | } 135 | [data-balloon-pos="right"]:before { 136 | background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') no-repeat; 137 | background-size: 100% auto; 138 | height: 18px; 139 | width: 6px; 140 | margin-bottom: 0; 141 | margin-left: 5px; 142 | } 143 | [data-balloon-pos="right"]:hover:before, 144 | [data-balloon-pos="right"][data-balloon-visible]:before, 145 | [data-balloon-pos="right"]:hover:after, 146 | [data-balloon-pos="right"][data-balloon-visible]:after { 147 | -webkit-transform: translate(0, -50%); 148 | -ms-transform: translate(0, -50%); 149 | transform: translate(0, -50%); 150 | } 151 | [data-balloon-length]:after { 152 | white-space: normal; 153 | } 154 | [data-balloon-length="small"]:after { 155 | width: 80px; 156 | } 157 | [data-balloon-length="medium"]:after { 158 | width: 150px; 159 | } 160 | [data-balloon-length="large"]:after { 161 | width: 260px; 162 | } 163 | [data-balloon-length="xlarge"]:after { 164 | width: 90vw; 165 | } 166 | @media screen and (min-width: 768px) { 167 | [data-balloon-length="xlarge"]:after { 168 | width: 380px; 169 | } 170 | } 171 | [data-balloon-length="fit"]:after { 172 | width: 100%; 173 | } 174 | -------------------------------------------------------------------------------- /v1/css/cursors/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/cursors/drag.png -------------------------------------------------------------------------------- /v1/css/cursors/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/cursors/erase.png -------------------------------------------------------------------------------- /v1/css/cursors/ink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/cursors/ink.png -------------------------------------------------------------------------------- /v1/css/cursors/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/cursors/label.png -------------------------------------------------------------------------------- /v1/css/icons/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/controls.png -------------------------------------------------------------------------------- /v1/css/icons/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/drag.png -------------------------------------------------------------------------------- /v1/css/icons/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/erase.png -------------------------------------------------------------------------------- /v1/css/icons/ink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/ink.png -------------------------------------------------------------------------------- /v1/css/icons/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/label.png -------------------------------------------------------------------------------- /v1/css/icons/speed_fast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/speed_fast.png -------------------------------------------------------------------------------- /v1/css/icons/speed_slow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/icons/speed_slow.png -------------------------------------------------------------------------------- /v1/css/loopy.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin:0; 3 | background: #fff; 4 | 5 | font-family: Helvetica, Arial, sans-serif; 6 | font-weight: normal; 7 | font-size: 20px; 8 | 9 | overflow: hidden; 10 | } 11 | canvas{ 12 | position:absolute; 13 | top:0; left:0; 14 | } 15 | 16 | #canvasses{ 17 | position:absolute; 18 | top:0; left:0; 19 | width: calc(100% - 300px); 20 | height: 100%; 21 | } 22 | #canvasses[fullscreen=yes]{ 23 | width: 100%; 24 | } 25 | #canvasses[cursor=ink]{ 26 | cursor: url('cursors/ink.png') 0 30, auto; 27 | } 28 | #canvasses[cursor=drag]{ 29 | cursor: url('cursors/drag.png') 15 15, auto; 30 | } 31 | #canvasses[cursor=erase]{ 32 | cursor: url('cursors/erase.png') 5 25, auto; 33 | } 34 | #canvasses[cursor=label]{ 35 | cursor: url('cursors/label.png') 15 15, auto; 36 | } 37 | 38 | 39 | 40 | /********** 41 | PLAY CONTROLS 42 | **********/ 43 | 44 | #playbar{ 45 | position: absolute; 46 | bottom: 15px; 47 | left: calc(50% - 275px); /* 50% - half of (playbar width + sidebar width)*/ 48 | 49 | width: 250px; 50 | height: 75px; 51 | 52 | -webkit-user-select: none; 53 | -moz-user-select: none; 54 | -ms-user-select: none; 55 | user-select: none; 56 | } 57 | #playbar[fullscreen=yes]{ 58 | left: calc(50% - 125px); /* 50% - half of (playbar width)*/ 59 | } 60 | #playbar .component_button{ 61 | position: absolute; 62 | bottom: 0; 63 | width: 230px; 64 | height: 25px; 65 | background: #444; 66 | } 67 | #playbar .component_button:hover{ 68 | background: #555; 69 | } 70 | #playbar .play_slider{ 71 | width: 190px; 72 | position: absolute; 73 | left: 30px; 74 | margin: 0; 75 | } 76 | .play_button_icon{ 77 | width: 25px; 78 | height: 25px; 79 | background-image: url(icons/controls.png); 80 | display: inline-block; 81 | background-size: 400% 100%; 82 | } 83 | .play_button_icon[icon="0"]{ background-position: 0 0; } 84 | .play_button_icon[icon="1"]{ background-position: -25px 0; } 85 | .play_button_icon[icon="2"]{ background-position: -50px 0; } 86 | .play_button_icon[icon="3"]{ background-position: -75px 0; } 87 | .play_button_label{ 88 | display: inline-block; 89 | position: relative; 90 | top: -5px; 91 | } 92 | div[big=yes] .play_button_icon{ 93 | width: 30px; 94 | height: 30px; 95 | } 96 | div[big=yes] .play_button_label{ 97 | top: -3px; 98 | } 99 | 100 | 101 | 102 | /********** 103 | TOOLBAR 104 | **********/ 105 | 106 | #toolbar{ 107 | position: absolute; 108 | left: 0px; 109 | top: calc(33% - 142.5px); /* 33% - half of toolbar height */ 110 | 111 | width:75px; height:280px; 112 | padding: 5px; 113 | background-color: #ddd; 114 | 115 | -webkit-user-select: none; 116 | -moz-user-select: none; 117 | -ms-user-select: none; 118 | user-select: none; 119 | } 120 | #toolbar[mode=play]{ 121 | display: none; 122 | } 123 | 124 | .toolbar_button{ 125 | width:60px; height:60px; 126 | margin: 5px; 127 | border: 2px solid #ddd; 128 | cursor: pointer; 129 | background-size: 100% 100%; 130 | } 131 | .toolbar_button[selected=yes]{ 132 | border: 2px solid #888; 133 | background-color: #999; 134 | } 135 | 136 | /********** 137 | SIDEBAR 138 | **********/ 139 | 140 | #sidebar{ 141 | position: absolute; 142 | top:0; right:0; 143 | width: 300px; 144 | height: 100%; 145 | background: #ddd; 146 | 147 | font-weight: 100; 148 | font-size: 17px; 149 | 150 | -webkit-user-select: none; 151 | -moz-user-select: none; 152 | -ms-user-select: none; 153 | user-select: none; 154 | } 155 | #sidebar > div{ 156 | margin: 25px; 157 | } 158 | #sidebar > div > div{ 159 | margin-bottom: 20px; 160 | } 161 | #sidebar[mode=play]{ 162 | background: #222; 163 | color: #777; 164 | } 165 | #sidebar .mini_button{ 166 | background: #999; 167 | color: #fff; 168 | padding: 3px 5px; 169 | border-radius: 2px; 170 | font-size: 16px; 171 | 172 | cursor: pointer; 173 | } 174 | #sidebar .mini_button:hover{ 175 | background: #aaa; 176 | } 177 | #sidebar[mode=play] .mini_button{ 178 | background: #555; 179 | color: #111; 180 | } 181 | #sidebar[mode=play] .mini_button:hover{ 182 | background: #666; 183 | } 184 | #sidebar a{ color: #777; } 185 | #sidebar a:hover{ color: #999; } 186 | #sidebar hr{ 187 | border: none; 188 | border-bottom: 2px solid rgba(150,150,150,0.5); 189 | width: 300px; 190 | position: relative; 191 | left:-25px; 192 | margin: 10px 0; 193 | } 194 | .component_input{ 195 | border: none; 196 | 197 | width:calc(100% - 10px); 198 | height:22px; 199 | padding: 5px; 200 | 201 | font-size: 20px; 202 | font-weight: 100; 203 | } 204 | .component_textarea{ 205 | border: none; 206 | width:calc(100% - 10px); 207 | height: 100px; 208 | padding: 5px; 209 | font-size: 16px; 210 | font-weight: 100; 211 | } 212 | .component_output{ 213 | border: 1px solid #aaa; 214 | width:100%; 215 | background: #ccc; 216 | color: #666; 217 | font-size: 15px; 218 | font-weight: 100; 219 | } 220 | .component_slider{ 221 | position: relative; 222 | width: 250px; 223 | height: 52px; 224 | } 225 | .component_slider_graphic{ 226 | position: absolute; 227 | width: 250px; 228 | height: 40px; 229 | cursor: pointer; 230 | } 231 | .component_slider_pointer{ 232 | position: absolute; 233 | top: 42px; 234 | width: 15px; 235 | height: 10px; 236 | } 237 | .component_label{ 238 | margin-bottom: 5px; 239 | } 240 | .component_button{ 241 | 242 | width: calc(100% - 20px); 243 | background: #888; 244 | color: #fff; 245 | font-size: 20px; 246 | font-weight: 100; 247 | text-align: center; 248 | padding: 10px; 249 | border-radius: 5px; 250 | 251 | cursor: pointer; 252 | } 253 | .component_button:hover{ 254 | background: #999; 255 | } 256 | .component_button[header=yes]{ 257 | position: absolute; 258 | top:0; left:0; 259 | width: 280px; 260 | background: #222; 261 | border-radius: 0px; 262 | color: #888; 263 | } 264 | .component_button[header=yes]:hover{ 265 | background: #333; 266 | } 267 | 268 | 269 | 270 | /********** 271 | 272 | MODAL 273 | 274 | **********/ 275 | 276 | #modal_container{ 277 | display: none; 278 | position: absolute; 279 | width: 100%; height: 100%; 280 | 281 | -webkit-user-select: none; 282 | -moz-user-select: none; 283 | -ms-user-select: none; 284 | user-select: none; 285 | } 286 | #modal_container[show=yes]{ 287 | display: block; 288 | } 289 | #modal_bg{ 290 | position: absolute; 291 | width: 100%; height: 100%; 292 | background: rgba(0,0,0,0.8); 293 | } 294 | #modal{ 295 | 296 | position: absolute; 297 | top:0; left:0; right:0; bottom:0; 298 | margin: auto; 299 | 300 | width: 600px; height: 300px; 301 | padding: 10px; 302 | background: #ddd; 303 | } 304 | #modal_close{ 305 | width: 120px; 306 | font-weight: 100; 307 | color: #777; 308 | cursor: pointer; 309 | } 310 | #modal_close:hover{ 311 | color: #888; 312 | } 313 | #modal_page{ 314 | margin: 15px; 315 | font-size: 25px; 316 | font-weight: 100; 317 | color: #333; 318 | } 319 | #modal iframe{ 320 | border: none; 321 | } 322 | -------------------------------------------------------------------------------- /v1/css/sliders/color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/sliders/color.png -------------------------------------------------------------------------------- /v1/css/sliders/initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/sliders/initial.png -------------------------------------------------------------------------------- /v1/css/sliders/slider_pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/sliders/slider_pointer.png -------------------------------------------------------------------------------- /v1/css/sliders/strength.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/sliders/strength.png -------------------------------------------------------------------------------- /v1/css/sliders/strength_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/css/sliders/strength_original.png -------------------------------------------------------------------------------- /v1/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/favicon.png -------------------------------------------------------------------------------- /v1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LOOPY (v1.0) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 | 43 |
44 |
45 | 46 | 47 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /v1/js/Dragger.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | DRAGGER 4 | 5 | **********************************/ 6 | 7 | function Dragger(loopy){ 8 | 9 | var self = this; 10 | self.loopy = loopy; 11 | 12 | // Dragging anything? 13 | self.dragging = null; 14 | self.offsetX = 0; 15 | self.offsetY = 0; 16 | 17 | subscribe("mousedown",function(){ 18 | 19 | // ONLY WHEN EDITING w DRAG 20 | if(self.loopy.mode!=Loopy.MODE_EDIT) return; 21 | if(self.loopy.tool!=Loopy.TOOL_DRAG) return; 22 | 23 | // Any node under here? If so, start dragging! 24 | var dragNode = loopy.model.getNodeByPoint(Mouse.x, Mouse.y); 25 | if(dragNode){ 26 | self.dragging = dragNode; 27 | self.offsetX = Mouse.x - dragNode.x; 28 | self.offsetY = Mouse.y - dragNode.y; 29 | loopy.sidebar.edit(dragNode); // and edit! 30 | return; 31 | } 32 | 33 | // Any label under here? If so, start dragging! 34 | var dragLabel = loopy.model.getLabelByPoint(Mouse.x, Mouse.y); 35 | if(dragLabel){ 36 | self.dragging = dragLabel; 37 | self.offsetX = Mouse.x - dragLabel.x; 38 | self.offsetY = Mouse.y - dragLabel.y; 39 | loopy.sidebar.edit(dragLabel); // and edit! 40 | return; 41 | } 42 | 43 | // Any edge under here? If so, start dragging! 44 | var dragEdge = loopy.model.getEdgeByPoint(Mouse.x, Mouse.y); 45 | if(dragEdge){ 46 | self.dragging = dragEdge; 47 | self.offsetX = Mouse.x - dragEdge.labelX; 48 | self.offsetY = Mouse.y - dragEdge.labelY; 49 | loopy.sidebar.edit(dragEdge); // and edit! 50 | return; 51 | } 52 | 53 | }); 54 | subscribe("mousemove",function(){ 55 | 56 | // ONLY WHEN EDITING w DRAG 57 | if(self.loopy.mode!=Loopy.MODE_EDIT) return; 58 | if(self.loopy.tool!=Loopy.TOOL_DRAG) return; 59 | 60 | // If you're dragging a NODE, move it around! 61 | if(self.dragging && self.dragging._CLASS_=="Node"){ 62 | 63 | // Model's been changed! 64 | publish("model/changed"); 65 | 66 | var node = self.dragging; 67 | node.x = Mouse.x - self.offsetX; 68 | node.y = Mouse.y - self.offsetY; 69 | 70 | // update coz visual glitches 71 | loopy.model.update(); 72 | 73 | } 74 | 75 | // If you're dragging an EDGE, move it around! 76 | if(self.dragging && self.dragging._CLASS_=="Edge"){ 77 | 78 | // Model's been changed! 79 | publish("model/changed"); 80 | 81 | var edge = self.dragging; 82 | var labelX = Mouse.x - self.offsetX; 83 | var labelY = Mouse.y - self.offsetY; 84 | 85 | if(edge.from!=edge.to){ 86 | 87 | // The Arc: whatever label *Y* is, relative to angle & first node's pos 88 | var fx=edge.from.x, fy=edge.from.y, tx=edge.to.x, ty=edge.to.y; 89 | var dx=tx-fx, dy=ty-fy; 90 | var a = Math.atan2(dy,dx); 91 | 92 | // Calculate arc 93 | var points = [[labelX,labelY]]; 94 | var translated = _translatePoints(points, -fx, -fy); 95 | var rotated = _rotatePoints(translated, -a); 96 | var newLabelPoint = rotated[0]; 97 | 98 | // ooookay. 99 | edge.arc = -newLabelPoint[1]; // WHY NEGATIVE? I DON'T KNOW. 100 | 101 | }else{ 102 | 103 | // For SELF-ARROWS: just get angle & mag for label. 104 | var dx = labelX - edge.from.x, 105 | dy = labelY - edge.from.y; 106 | var a = Math.atan2(dy,dx); 107 | var mag = Math.sqrt(dx*dx + dy*dy); 108 | 109 | // Minimum mag 110 | var minimum = edge.from.radius+25; 111 | if(magMath.abs(bounds.bottom)) edgeConfig.arc = -bounds.top; 161 | else edgeConfig.arc = -bounds.bottom; 162 | 163 | } 164 | 165 | // Add the edge! 166 | if(edgeConfig){ 167 | var newEdge = loopy.model.addEdge(edgeConfig); 168 | loopy.sidebar.edit(newEdge); 169 | } 170 | 171 | } 172 | 173 | // NODE: did NOT start in a node. 174 | if(!startNode){ 175 | 176 | // Just roughly make a circle the size of the bounds of the circle 177 | var bounds = _getBounds(self.strokeData); 178 | var x = (bounds.left+bounds.right)/2; 179 | var y = (bounds.top+bounds.bottom)/2; 180 | var r = ((bounds.width/2)+(bounds.height/2))/2; 181 | 182 | // Circle can't be TOO smol 183 | if(r>15){ 184 | 185 | // Snap to radius 186 | /*r = Math.round(r/Ink.SNAP_TO_RADIUS)*Ink.SNAP_TO_RADIUS; 187 | if(r " 131 | + "
"+config.label+"
"; 132 | 133 | self.dom = _createButton(label, function(){ 134 | config.onclick(); 135 | }); 136 | 137 | // Tooltip! 138 | if(config.tooltip){ 139 | self.dom.setAttribute("data-balloon", config.tooltip); 140 | self.dom.setAttribute("data-balloon-pos", "top"); 141 | } 142 | 143 | } 144 | function PlaySlider(config){ 145 | 146 | var self = this; 147 | self.dom = document.createElement("div"); 148 | self.dom.style.bottom = "0px"; 149 | self.dom.style.position = "absolute"; 150 | self.dom.style.width = "100%"; 151 | self.dom.style.height = "20px"; 152 | 153 | // Input 154 | var input = document.createElement("input"); 155 | input.setAttribute("class","play_slider"); 156 | self.dom.appendChild(input); 157 | 158 | // Slow & Fast Icons 159 | var img = new Image(); 160 | img.src = "css/icons/speed_slow.png"; 161 | img.width = 20; 162 | img.height = 15; 163 | img.style.position = "absolute"; 164 | img.style.left = "5px"; 165 | img.style.top = "-2px"; 166 | self.dom.appendChild(img); 167 | var img = new Image(); 168 | img.src = "css/icons/speed_fast.png"; 169 | img.width = 20; 170 | img.height = 15; 171 | img.style.position = "absolute"; 172 | img.style.right = "5px"; 173 | img.style.top = "-2px"; 174 | self.dom.appendChild(img); 175 | 176 | // Properties 177 | input.type = "range"; 178 | input.value = config.value; 179 | input.step = config.step; 180 | input.min = config.min; 181 | input.max = config.max; 182 | input.oninput = function(event){ 183 | config.oninput(input.value); 184 | }; 185 | 186 | } -------------------------------------------------------------------------------- /v1/js/Toolbar.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | 3 | TOOLBAR CODE 4 | 5 | **********************************/ 6 | 7 | function Toolbar(loopy){ 8 | 9 | var self = this; 10 | 11 | // Tools & Buttons 12 | var buttons = []; 13 | var buttonsByID = {}; 14 | self.dom = document.getElementById("toolbar"); 15 | self.addButton = function(options){ 16 | 17 | var id = options.id; 18 | var tooltip = options.tooltip; 19 | var callback = options.callback; 20 | 21 | // Add the button 22 | var button = new ToolbarButton(self,{ 23 | id: id, 24 | icon: "css/icons/"+id+".png", 25 | tooltip: tooltip, 26 | callback: callback 27 | }); 28 | self.dom.appendChild(button.dom); 29 | buttons.push(button); 30 | buttonsByID[id] = button; 31 | 32 | // Keyboard shortcut! 33 | (function(id){ 34 | subscribe("key/"+id,function(){ 35 | loopy.ink.reset(); // also CLEAR INK CANVAS 36 | buttonsByID[id].callback(); 37 | }); 38 | })(id); 39 | 40 | }; 41 | 42 | // Select button 43 | self.selectButton = function(button){ 44 | for(var i=0;i 4 | * MIT Licensed 5 | */ 6 | (function (context) { 7 | var MinPubSub = {}; 8 | 9 | // the topic/subscription hash 10 | var cache = context.c_ || {}; //check for 'c_' cache for unit testing 11 | 12 | MinPubSub.publish = function ( /* String */ topic, /* Array? */ args) { 13 | // summary: 14 | // Publish some data on a named topic. 15 | // topic: String 16 | // The channel to publish on 17 | // args: Array? 18 | // The data to publish. Each array item is converted into an ordered 19 | // arguments on the subscribed functions. 20 | // 21 | // example: 22 | // Publish stuff on '/some/topic'. Anything subscribed will be called 23 | // with a function signature like: function(a,b,c){ ... } 24 | // 25 | // publish('/some/topic', ['a','b','c']); 26 | 27 | var subs = cache[topic], 28 | len = subs ? subs.length : 0; 29 | 30 | //can change loop or reverse array if the order matters 31 | while (len--) { 32 | subs[len].apply(context, args || []); 33 | } 34 | }; 35 | 36 | MinPubSub.subscribe = function ( /* String */ topic, /* Function */ callback) { 37 | // summary: 38 | // Register a callback on a named topic. 39 | // topic: String 40 | // The channel to subscribe to 41 | // callback: Function 42 | // The handler event. Anytime something is publish'ed on a 43 | // subscribed channel, the callback will be called with the 44 | // published array as ordered arguments. 45 | // 46 | // returns: Array 47 | // A handle which can be used to unsubscribe this particular subscription. 48 | // 49 | // example: 50 | // subscribe('/some/topic', function(a, b, c){ /* handle data */ }); 51 | 52 | if (!cache[topic]) { 53 | cache[topic] = []; 54 | } 55 | cache[topic].push(callback); 56 | return [topic, callback]; // Array 57 | }; 58 | 59 | MinPubSub.unsubscribe = function ( /* Array */ handle, /* Function? */ callback) { 60 | // summary: 61 | // Disconnect a subscribed function for a topic. 62 | // handle: Array 63 | // The return value from a subscribe call. 64 | // example: 65 | // var handle = subscribe('/some/topic', function(){}); 66 | // unsubscribe(handle); 67 | 68 | var subs = cache[callback ? handle : handle[0]], 69 | callback = callback || handle[1], 70 | len = subs ? subs.length : 0; 71 | 72 | while (len--) { 73 | if (subs[len] === callback) { 74 | subs.splice(len, 1); 75 | } 76 | } 77 | }; 78 | 79 | // UMD definition to allow for CommonJS, AMD and legacy window 80 | if (typeof module === 'object' && module.exports) { 81 | // CommonJS, just export 82 | module.exports = exports = MinPubSub; 83 | } else if (typeof define === 'function' && define.amd) { 84 | // AMD support 85 | define(function () { 86 | return MinPubSub; 87 | }); 88 | } else if (typeof context === 'object') { 89 | // If no AMD and we are in the browser, attach to window 90 | context.publish = MinPubSub.publish; 91 | context.subscribe = MinPubSub.subscribe; 92 | context.unsubscribe = MinPubSub.unsubscribe; 93 | } 94 | 95 | })(this.window); -------------------------------------------------------------------------------- /v1/pages/credits/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/favicon.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/aimee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/aimee.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/buster.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/chad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/chad.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/jared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/jared.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/ljt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/ljt.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/mark.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/matt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/matt.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/michael_duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/michael_duke.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/michael_huff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/michael_huff.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/natalie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/natalie.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/nicholas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/nicholas.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/noel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/noel.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/phil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/phil.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/philippe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/philippe.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/travis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/travis.png -------------------------------------------------------------------------------- /v1/pages/credits/peep/yu-han.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/peep/yu-han.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/aimee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/aimee.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/buster.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/cedric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/cedric.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/chad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/chad.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/dylan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/dylan.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/dylan_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/dylan_s.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/feiya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/feiya.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/glen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/glen.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/iago.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/iago.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/jared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/jared.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/karen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/karen.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/kate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/kate.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/kevin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/kevin.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/klemen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/klemen.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/kuerqing1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/kuerqing1024.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/ljt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/ljt.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/mark.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/matt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/matt.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/michael_duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/michael_duke.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/michael_huff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/michael_huff.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/michelle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/michelle.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/natalie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/natalie.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/nicholas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/nicholas.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/nimrod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/nimrod.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/noel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/noel.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/phil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/phil.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/philippe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/philippe.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/rob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/rob.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/thomas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/thomas.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/travis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/travis.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/william.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/william.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/yu-han.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/yu-han.png -------------------------------------------------------------------------------- /v1/pages/credits/polygon/zach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/credits/polygon/zach.png -------------------------------------------------------------------------------- /v1/pages/examples/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/examples/favicon.png -------------------------------------------------------------------------------- /v1/pages/examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LOOPY: Examples! 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /v1/pages/gif.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Step 1: download LICEcap, 10 | a free open-source tool to record GIFs (Windows/Mac only. Linux users, try 11 | Peek) 12 |

13 | Step 2: record a GIF while playing around in LOOPY 14 |

15 | Step 3: ta-dah 16 |

17 |
18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /v1/pages/gifs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/gifs.gif -------------------------------------------------------------------------------- /v1/pages/howto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /v1/pages/howto/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/howto/1.png -------------------------------------------------------------------------------- /v1/pages/howto/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/howto/2.png -------------------------------------------------------------------------------- /v1/pages/howto/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/howto/3.png -------------------------------------------------------------------------------- /v1/pages/howto/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/howto/4.png -------------------------------------------------------------------------------- /v1/pages/howto/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncase/loopy/2d8e13f0a006f4024f27ad1712d7f9c2c1ad7cd9/v1/pages/howto/5.png -------------------------------------------------------------------------------- /v1/pages/page.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background: #ddd; 3 | font-family: Helvetica, Arial, sans-serif; 4 | font-weight: 100; 5 | font-size: 19px; 6 | color: #222; 7 | margin: 0; 8 | } 9 | .full{ 10 | width:100%; 11 | margin: 0; 12 | display: block; 13 | } 14 | .shadow{ 15 | width:100%; height: 100%; 16 | position: fixed; 17 | top:0; left:0; 18 | box-shadow: inset 0 0 20px rgba(0,0,0,0.75); 19 | } 20 | 21 | /********************************/ 22 | /********************************/ 23 | 24 | #examples{ 25 | width: 620px; 26 | margin:0 auto; 27 | overflow: hidden; 28 | } 29 | 30 | #examples hr{ 31 | border:none; 32 | border-bottom: 2px dashed #aaa; 33 | width: 560px; 34 | margin: 0 auto; 35 | margin-top: 15px; 36 | } 37 | 38 | #more_examples{ 39 | color: #333; 40 | width: 500px; 41 | margin: 30px auto; 42 | } 43 | #more_examples li{ 44 | color: #666; 45 | margin-bottom: 1em; 46 | position: relative; 47 | left: -0.8em; 48 | } 49 | #more_examples li a{ 50 | color: #dd4040; 51 | } 52 | #more_examples li a:hover{ 53 | color: #ee6060; 54 | } 55 | #more_examples li a.twitter{ 56 | color: inherit; 57 | } 58 | 59 | .example{ 60 | display: block; 61 | float: left; 62 | width: 180px; 63 | height: 180px; 64 | 65 | cursor: pointer; 66 | transform: scale(1); 67 | transition: all 0.2s ease-in-out; 68 | } 69 | .example:hover{ 70 | transform: scale(1.1); 71 | } 72 | .example > div{ 73 | width: 180px; 74 | height: 180px; 75 | background: #888; 76 | border-radius: 100px; 77 | float: left; 78 | position: relative; 79 | } 80 | .example > div > div{ 81 | font-size: 25px; 82 | color: #fff; 83 | width: 150px; 84 | height: 55px; 85 | position: absolute; 86 | top:0; left:0; right:0; bottom:0; 87 | margin: auto; 88 | text-align: center; 89 | } 90 | .example:nth-child(n+2){ 91 | margin-left: 19px; 92 | } 93 | 94 | /********************************/ 95 | /********************************/ 96 | 97 | #credits{ 98 | width: 600px; 99 | margin: 50px auto; 100 | font-weight: 100; 101 | color: #fff; 102 | font-size: 20px; 103 | } 104 | 105 | .credit_intro{ 106 | font-size: 26px; 107 | } 108 | .credit_intro a{ 109 | color: #dd3939; 110 | } 111 | .credit_intro a:hover{ 112 | color: #ee6060; 113 | } 114 | 115 | #credits hr{ 116 | border:none; 117 | border-bottom: 4px dashed #444; 118 | margin-top: 30px; 119 | } 120 | 121 | .credits_peeps{ 122 | overflow: hidden; 123 | padding-bottom: 20px; 124 | } 125 | .credits_peeps > div{ 126 | position: relative; 127 | width: 150px; 128 | height: 210px; 129 | float: left; 130 | text-align: center; 131 | } 132 | .credits_peeps > div > img:nth-child(1){ 133 | position: absolute; 134 | left: 0; 135 | width: 150px; 136 | bottom: 30px; 137 | } 138 | .credits_peeps > div > img:nth-child(2){ 139 | position: absolute; 140 | width: 50px; 141 | right: 5px; 142 | bottom: 30px; 143 | } 144 | .credits_peeps > div > span{ 145 | display: block; 146 | position: absolute; 147 | bottom:0; 148 | width: 150px; 149 | height: 20px; 150 | text-transform: lowercase; 151 | } 152 | 153 | .credits_polygons{ 154 | margin-top: 15px; 155 | overflow: hidden; 156 | color: #ddd; 157 | font-size: 18px; 158 | padding-bottom: 20px; 159 | text-align: center; 160 | } 161 | .credits_polygons > div{ 162 | display: inline-block; 163 | } 164 | .credits_polygons > div > img{ 165 | width: 40px; 166 | position: relative; 167 | top:10px; 168 | } 169 | .credits_polygons > div > span{ 170 | text-transform: lowercase; 171 | } 172 | 173 | .credits_names{ 174 | margin-top: 30px; 175 | overflow: hidden; 176 | color: #bbb; 177 | font-size: 16px; 178 | padding-bottom: 20px; 179 | text-align: center; 180 | -webkit-columns: 150px 3; 181 | -moz-columns: 150px 3; 182 | columns: 150px 3; 183 | } --------------------------------------------------------------------------------