Merge branch '100Rabbits'
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,3 @@ | ||||
| *.swp | ||||
| *.swo | ||||
| assets/ | ||||
							
								
								
									
										174
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										174
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,91 +1,91 @@ | ||||
| #Ronin | ||||
|  | ||||
| <img src="media/demo.jpg" width="700"> | ||||
|  | ||||
| #Starting | ||||
|  | ||||
| Ronin is a web based drawing application and visual language. Launch index.html and press **:**(colon) to display the command prompt. Input the commands below to interface with the different tools. Headings with a star are features in development. | ||||
|  | ||||
| # Ronin | ||||
| ## Basics | ||||
| Ronin is a web based drawing application and visual language. Launch index.html and press **:**(colon) to display the command prompt. Input the commands below to interface with the different tools.  | ||||
| ``` | ||||
| : | ||||
| ``` | ||||
| ### Loading/Saving | ||||
| Requires you to run Ronin through localhost. Navigate to the Ronin folder, and run the simple http server. | ||||
| ``` | ||||
| cd /path/to/ronin/                ; Navigate to Ronin through the terminal | ||||
| python -m SimpleHTTPServer 8000   ; Start localhost | ||||
| http://localhost:8000/            ; Enjoy Ronin | ||||
| ``` | ||||
| ### Controls | ||||
| ``` | ||||
| ctrl                              ; Draw Overlays | ||||
| alt                               ; Drag Surface | ||||
| shift                             ; Erase | ||||
| shift+ctrl                        ; Eyedrop | ||||
| shift+alt                         ; Move Layer | ||||
| ``` | ||||
| ## Modules | ||||
| ### # Surface | ||||
| Missing documentation. | ||||
| - Parameters: `Rect` `Color` `Bang`  | ||||
| - Variables: `layer`  | ||||
|  | ||||
| #Modules | ||||
| ##Canvas | ||||
| ``` | ||||
| @ 600x400                         ; New canvas of size 600w and 400h | ||||
| @ 100x100 #ff0000                 ; New canvas of size 100w and 100h with red background | ||||
| @ !                               ; Clear canvas | ||||
| ``` | ||||
| ### / FileLoad | ||||
| Missing documentation. | ||||
| - Parameters: `Filepath` `Position` `Rect`  | ||||
| - Variables:  | ||||
|  | ||||
| ##Save File | ||||
| ``` | ||||
| $ new_name                        ; Create a new file with name | ||||
| $ 3                               ; Save to temporary storage, accessible with Load | ||||
| $ !                               ; Clear temporary storage | ||||
| ``` | ||||
| ### $ FileSave | ||||
| Missing documentation. | ||||
| - Parameters: `Any`  | ||||
| - Variables:  | ||||
|  | ||||
| ##Load File | ||||
| ``` | ||||
| / dir/file_name.jpg 10,10 100x100 ; Load image, at 10,10 with size 100x100 | ||||
| / dir/file_name.jpg 10,10 100x    ; Load image, at 10,10 with size 100w and auto height | ||||
| / 3                               ; Load temporary storage id | ||||
| ``` | ||||
| ### ^ History | ||||
| Missing documentation. | ||||
| - Parameters:  | ||||
| - Variables:  | ||||
|  | ||||
| ##Brush(Pointers) | ||||
| ``` | ||||
| > 10                              ; Size 10 | ||||
| > -4                              ; Eraser, Size 4 | ||||
| > 10,0                            ; Add pointer at pos | ||||
| > 400x0                           ; Add mirror pointer, at 400x | ||||
| > 4 #ff0000                       ; Red brush, Size 4 | ||||
| > 100,100 45'                     ; Radial brush from position x,y and 45 degrees | ||||
| > !                               ; Remove all pointers | ||||
| ``` | ||||
| ### | Overlay | ||||
| Missing documentation. | ||||
| - Parameters: `Position` `Rect`  | ||||
| - Variables:  | ||||
|  | ||||
| ##Guides | ||||
| ``` | ||||
| | 10,10 100x100                   ; Draw a guide | ||||
| | -100,0                          ; Draw a grid at every 100px | ||||
| | !                               ; Remove all guides | ||||
| ``` | ||||
| ### % Render | ||||
| Missing documentation. | ||||
| - Parameters: `Any`  | ||||
| - Variables:  | ||||
|  | ||||
| ##Vector(SVG) | ||||
| ``` | ||||
| + M10 10 h 80 v 80 h -80 Z                                     ; Draw a square outline | ||||
| + M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80               ; Draw a bezier | ||||
| + M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 ; Draw a circle | ||||
| ``` | ||||
| ### > Brush | ||||
| Missing documentation. | ||||
| - Parameters: `Position` `Rect` `Angle` `Color` `Value` `Bang`  | ||||
| - Variables: `natural` `banking`  | ||||
|  | ||||
| ##Stroke* | ||||
| ``` | ||||
| - 0,0 0,10 10,10 10,0 0,0         ; Draw a square | ||||
| ``` | ||||
| ### . Eraser | ||||
| Missing documentation. | ||||
| - Parameters: `Value`  | ||||
| - Variables:  | ||||
|  | ||||
| ##Filters* | ||||
| ``` | ||||
| : saturation 0.5                  ; Set image saturation to 0.5 | ||||
| : balance red 0.9 0.4 0.7         ; Set color balance red to 0.9 0.4 0.7 | ||||
| : balance white 0.7 0.7 0.7       ; Set color balance white to 0.7 0.7 0.7 | ||||
| : sharpen 0.5                     ; Sharpen image to 50% | ||||
| : chromatic 10                    ; Shifts, from center, pixels red value by 10, green by 5, blue by 0 | ||||
| : chromatic 8 0 16                ; Shifts, from center, pixels red value by 8, green by 0, blue by 16 | ||||
| ``` | ||||
| ### * Eye | ||||
| Missing documentation. | ||||
| - Parameters:  | ||||
| - Variables:  | ||||
|  | ||||
| ##Translate* | ||||
| ``` | ||||
| ^ 0,10                            ; Translate 10px vertically | ||||
| ^ 20,20 100x100 40,40             ; Translate a specific portion to a specific location | ||||
| ^ -1280x800                       ; Flip image horizontally | ||||
| ``` | ||||
| ### & Typographe | ||||
| Missing documentation. | ||||
| - Parameters: `Position` `Color` `Value`  | ||||
| - Variables: `text`  | ||||
|  | ||||
| ##Zoom* | ||||
| ``` | ||||
| = 75                              ; Zoom factor of 75% | ||||
| = !                               ; Zoom 100% | ||||
| ``` | ||||
| ### _ Stroke | ||||
| Missing documentation. | ||||
| - Parameters: `Any`  | ||||
| - Variables:  | ||||
|  | ||||
| #Units | ||||
| ### + Vector | ||||
| Missing documentation. | ||||
| - Parameters: `Any` `Position`  | ||||
| - Variables:  | ||||
|  | ||||
| ### ? Help | ||||
| Missing documentation. | ||||
| - Parameters:  | ||||
| - Variables:  | ||||
|  | ||||
| ## Units | ||||
| ``` | ||||
| 5                                 ; value:    5 | ||||
| 5,7                               ; position: 5x 7y | ||||
| @@ -93,35 +93,24 @@ $ !                               ; Clear temporary storage | ||||
| #ff0000                           ; color:    red | ||||
| 0..5                              ; random:   0.0-5.0 | ||||
| 45'                               ; degree:   45/365 | ||||
| rate:10                           ; variable: rate = 10 | ||||
| "foo"                             ; string:   foo | ||||
| {40w}                             ; constant: 120px, 40% canvas width | ||||
| rate=10                           ; variable: rate = 10 | ||||
| ``` | ||||
|  | ||||
| #Constants | ||||
| ``` | ||||
| w                                 ; percentage of canvas width | ||||
| h                                 ; percentage of canvas height | ||||
| ``` | ||||
|  | ||||
| #Presets | ||||
| ##Radial Brush | ||||
| ## Presets | ||||
| ### Radial Brush | ||||
| ``` | ||||
| # 8 strands | ||||
| > 600,400 45';> 600,400 90';> 600,400 135';> 600,400 180';> 600,400 225';> 600,400 270';> 600,400 315' | ||||
| # 6 strands | ||||
| > 600,400 60';> 600,400 120';> 600,400 180';> 600,400 240';> 600,400 300' | ||||
| ``` | ||||
|  | ||||
| ##Symmetry Brush | ||||
| ### Symmetry Brush | ||||
| ``` | ||||
| # XY | ||||
| > 400x 3 | ||||
| # Angular brushes | ||||
| > 400x 1,1;> 400x 2,2;> 400x 3,3; > 1,1;> 2,2;> 3,3; | ||||
| ``` | ||||
|  | ||||
| ##Angular Brush | ||||
| ### Angular Brush | ||||
| ``` | ||||
| # Light | ||||
| > 1,1;> 2,2;> 3,3;> 4,4 | ||||
| @@ -130,3 +119,8 @@ h                                 ; percentage of canvas height | ||||
| # Symmetric Light | ||||
| > 1,1 600x;> 2,2 600x;> 3,3 600x;> 4,4 600x | ||||
| ``` | ||||
|  | ||||
| ### Twitter export & Watermark | ||||
| ``` | ||||
| # 1280x800 ; / assets/photo.jpg 1280x 0,0 ; / assets/hundredrabbits.png 60x60 20,720 | ||||
| ``` | ||||
|   | ||||
							
								
								
									
										56
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								index.html
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <script type="text/javascript" src="scripts/unit.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/unit.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/rect.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/color.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/position.js"></script> | ||||
| @@ -9,34 +9,62 @@ | ||||
|     <script type="text/javascript" src="scripts/units/value.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/filepath.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/any.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/variable.js"></script> | ||||
|     <script type="text/javascript" src="scripts/units/range.js"></script> | ||||
|      | ||||
|     <script type="text/javascript" src="scripts/module.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/canvas.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/filter.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/module.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/stroke.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/vector.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/overlay.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/brush.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/brush.pointer.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/file.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/hint.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/file.load.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/file.save.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/help.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/history.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/eraser.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/surface.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/surface.layer.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/eye.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/typographe.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/render.js"></script> | ||||
|      | ||||
|     <script type="text/javascript" src="scripts/keyboard.js"></script> | ||||
|     <script type="text/javascript" src="scripts/command.js"></script> | ||||
|     <script type="text/javascript" src="scripts/commander.js"></script> | ||||
|     <script type="text/javascript" src="scripts/ronin.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/filter.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/stencil.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/rotate.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/invert.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/chromatic.js"></script> | ||||
|  | ||||
|     <!-- Need to migrate  | ||||
|     <script type="text/javascript" src="scripts/filters/saturation.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/offset.js"></script> | ||||
|     <script type="text/javascript" src="scripts/filters/balance.js"></script> | ||||
|     --> | ||||
|      | ||||
|     <script type="text/javascript" src="scripts/core/keyboard.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/cursor.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/command.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/commander.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/commander.hint.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/ronin.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/widget.js"></script> | ||||
|      | ||||
|     <link rel="stylesheet" type="text/css" href="links/reset.css"/> | ||||
|     <link rel="stylesheet" type="text/css" href="links/fonts.css"/> | ||||
|     <link rel="stylesheet" type="text/css" href="links/main.css"/> | ||||
|     <title>Ronin</title> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div id='ronin'> | ||||
|       <canvas id='overlay' width="1480" height="800"></canvas> | ||||
|       <canvas id="workspace" width="1480" height="800" style="background:#efefef"></canvas> | ||||
|       <div id='surface'> | ||||
|         <canvas id='overlay' width="1480" height="800"></canvas> | ||||
|       </div> | ||||
|       <div id='widget'>Loading..</div> | ||||
|       <div id ='commander'> | ||||
|         <div id='commander_hint'></div> | ||||
|         <input id='commander_input'/> | ||||
|       </div> | ||||
|     </div> | ||||
|     <script type="text/javascript" src="scripts/init.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/init.js"></script> | ||||
|   </body> | ||||
| </html> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										15
									
								
								links/fonts.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								links/fonts.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| /* Input Mono */ | ||||
|  | ||||
| @font-face { | ||||
|     font-family: 'input_mono_regular'; | ||||
|     src: url('../media/fonts/input_mono_regular.ttf') format('truetype'); | ||||
|     font-weight: normal; | ||||
|     font-style: normal; | ||||
| } | ||||
|  | ||||
| @font-face { | ||||
|     font-family: 'input_mono_medium'; | ||||
|     src: url('../media/fonts/input_mono_medium.ttf') format('truetype'); | ||||
|     font-weight: normal; | ||||
|     font-style: normal; | ||||
| } | ||||
| @@ -1,20 +1,33 @@ | ||||
| body { margin:0px; padding:0px; overflow:hidden;} | ||||
| body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_medium",courier,monospace;} | ||||
| *:focus {outline: none; } | ||||
|  | ||||
| canvas:hover { cursor: crosshair;} | ||||
|  | ||||
| #overlay { position:fixed; z-index:1000;} | ||||
| #ronin { width:100%; height:100%; overflow:hidden; background:#ccc; background-image:url(../media/grid_20.png); background-position: center center; } | ||||
| #surface { width:50vw; height:50vh; overflow:hidden; position:fixed; left:50%; top:50%; background:#efefef; border-radius:3px;} | ||||
| #surface .layer { position:absolute; top:0px; left:0px; width:100%; height:100%;} | ||||
| #overlay { position:absolute; z-index:1000;} | ||||
| #widget { color:#fff; position:absolute; font-size:10px; padding-top:10px;} | ||||
| #widget .module { float:left; margin-right:10px; } | ||||
| #widget .module .highlight { color:#e7fff8; } | ||||
| #widget .cursor { float:right; text-align: right} | ||||
| #widget .layer:hover { cursor:pointer;} | ||||
|  | ||||
| #commander { display:none; z-index: 2000; position:fixed; } | ||||
| #commander.visible { display:block; } | ||||
| #commander.hidden { display:none; } | ||||
| #commander input { background:black; padding:5px 15px; position:fixed; bottom:0; color:white; font-size:14px; left:0; border:0; width:calc(100vw); font-family:courier; cursor:pointer; display:block;} | ||||
| #commander input { background:none; padding:10px; position:fixed; bottom:0; color:white; font-size:11px; left:0; border:0; width:calc(100vw); cursor:pointer; display:block; height:35px;} | ||||
| #commander input:before { content:"input"; color:e7fff8;} | ||||
|  | ||||
| #commander_hint { background: black;position: fixed;bottom: 27px;padding: 5px 15px 0 15px;line-height: 17px;font-family: courier;font-size: 14px;width: 100vw;color: #999;} | ||||
| #commander_hint .module { color:#ffffff; display:inline-block; margin-right:10px;} | ||||
| #commander_hint { background: #000;position: fixed;bottom: 0px;left:0px;padding: 10px;font-size: 11px;width: calc(100vw - 20px);color: #999; height:15px;} | ||||
| #commander_hint .rune { color:#e7fff8; display:inline-block; margin-right:10px;} | ||||
| #commander_hint .module { color:#ccc; display:inline-block; margin-right:10px;} | ||||
| #commander_hint .command { color:#fff; display:inline-block; margin-right:10px;} | ||||
| #commander_hint .param { font-style: italic;} | ||||
| #commander_hint .param:after { content:", "; } | ||||
| #commander_hint .param:after { content:" "; } | ||||
| #commander_hint .param:last-child:after { content:"";} | ||||
| #commander_hint .value { color:#ff0000;} | ||||
| #commander_hint .value:after { content:", "; color:#999; } | ||||
| #commander_hint .value:last-child:after { content:"";} | ||||
| #commander_hint .value { color:#e7fff8;} | ||||
| #commander_hint .value:after { content:" "; color:#999; } | ||||
| #commander_hint .value:last-child:after { content:"";} | ||||
| #commander_hint .variable_key { color:#aaa; font-weight:bold;} | ||||
| #commander_hint .variable_value { color:#aaa;} | ||||
							
								
								
									
										1
									
								
								links/reset.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								links/reset.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| * { margin:0;padding:0;border:0;outline:0;text-decoration:none;font-weight:inherit;font-style:inherit;color:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;list-style:none;border-collapse:collapse;border-spacing:0; -webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;} | ||||
							
								
								
									
										23
									
								
								main.js
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								main.js
									
									
									
									
									
								
							| @@ -1,23 +0,0 @@ | ||||
| /** | ||||
|  * Listens for the app launching then creates the window | ||||
|  * | ||||
|  * @see http://developer.chrome.com/apps/app.runtime.html | ||||
|  * @see http://developer.chrome.com/apps/app.window.html | ||||
|  */ | ||||
| chrome.app.runtime.onLaunched.addListener(function() { | ||||
|   // Center window on screen. | ||||
|   var screenWidth = screen.availWidth; | ||||
|   var screenHeight = screen.availHeight; | ||||
|   var width = 500; | ||||
|   var height = 300; | ||||
|  | ||||
|   chrome.app.window.create('index.html', { | ||||
|     id: "helloWorldID", | ||||
|     outerBounds: { | ||||
|       width: width, | ||||
|       height: height, | ||||
|       left: Math.round((screenWidth-width)/2), | ||||
|       top: Math.round((screenHeight-height)/2) | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
| @@ -1,15 +0,0 @@ | ||||
| { | ||||
|   "manifest_version": 2, | ||||
|   "name": "Ronin", | ||||
|   "version": "1.1", | ||||
|   "minimum_chrome_version": "23", | ||||
|   "icons": { | ||||
|     "16": "media/icon_16.png", | ||||
|     "128": "media/icon_128.png" | ||||
|   }, | ||||
|   "app": { | ||||
|     "background": { | ||||
|       "scripts": ["main.js"] | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								media/fonts/input_mono_medium.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								media/fonts/input_mono_medium.ttf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								media/fonts/input_mono_regular.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								media/fonts/input_mono_regular.ttf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								media/grid_20.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								media/grid_20.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 105 B | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 4.7 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 886 B | 
| @@ -1,140 +0,0 @@ | ||||
| function Commander(element,element_input) | ||||
| { | ||||
|   this.element = element; | ||||
|   this.element_input = element_input; | ||||
|   this.cmd = null; | ||||
|   this.storage = []; | ||||
|   this.storage_index = 0; | ||||
|   this.always_show = false; | ||||
|    | ||||
|   this.show = function() | ||||
|   { | ||||
|     this.element.setAttribute('class','visible'); | ||||
|     this.element_input.focus(); | ||||
|   } | ||||
|  | ||||
|   this.always = function() { | ||||
|       this.always_show = !this.always_show; | ||||
|   } | ||||
|    | ||||
|   this.hide = function() | ||||
|   { | ||||
|     if (!this.always_show) { | ||||
|         this.element.setAttribute('class','hidden'); | ||||
|     } | ||||
|     this.element_input.value = ""; | ||||
|   } | ||||
|    | ||||
|   this.clear = function() | ||||
|   { | ||||
|     this.element_input.value = ""; | ||||
|   } | ||||
|    | ||||
|   this.next_cmd = function() | ||||
|   { | ||||
|     this.storage_index += this.storage_index < this.storage.length ? 1 : 0; | ||||
|     this.element_input.value = this.storage[this.storage_index] ? this.storage[this.storage_index] : ""; | ||||
|   } | ||||
|    | ||||
|   this.prev_cmd = function() | ||||
|   { | ||||
|     this.storage_index -= this.storage_index < 1 ? 0 : 1; | ||||
|     this.element_input.value = this.storage[this.storage_index]; | ||||
|   } | ||||
|    | ||||
|   this.active = function(content) | ||||
|   { | ||||
|     this.storage.push(content.join(" ")); | ||||
|     this.storage_index = this.storage.length; | ||||
|      | ||||
|     var key = content[0]; | ||||
|     content.shift(); | ||||
|     var cmd = new Command(content); | ||||
|      | ||||
|     switch(key) { | ||||
|       case "~": | ||||
|           this.always(); | ||||
|           break; | ||||
|       case "@": | ||||
|         ronin.canvas.active(cmd); | ||||
|         break; | ||||
|       case "$": | ||||
|         ronin.file.save(cmd); | ||||
|         break; | ||||
|       case "/": | ||||
|         ronin.file.active(cmd); | ||||
|         break; | ||||
|       case ">": | ||||
|         ronin.brush.active(cmd); | ||||
|         break; | ||||
|       case "|": | ||||
|         ronin.overlay.active(cmd); | ||||
|         break; | ||||
|       case "-": | ||||
|         ronin.stroke.active(cmd); | ||||
|         break; | ||||
|       case "^": // TODO | ||||
|         ronin.translate.active(cmd); | ||||
|         break; | ||||
|       case "=": // TODO | ||||
|         ronin.zoom.active(cmd); | ||||
|         break; | ||||
|       case "#": // TODO | ||||
|         ronin.layers.active(cmd); | ||||
|         break; | ||||
|       case ":": | ||||
|         ronin.filter.active(cmd); | ||||
|         break; | ||||
|       case "+": | ||||
|         ronin.vector.active(cmd); | ||||
|         break; | ||||
|     } | ||||
|     this.hide(); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(content) | ||||
|   { | ||||
|     var key = content[0]; | ||||
|     content.shift(); | ||||
|     this.cmd = new Command(content); | ||||
|     ronin.module = null; | ||||
|      | ||||
|     switch(key) { | ||||
|       case "@": | ||||
|         ronin.canvas.passive(this.cmd); | ||||
|         ronin.module = ronin.canvas; | ||||
|         break; | ||||
|       case "/": | ||||
|         ronin.file.passive(this.cmd); | ||||
|         ronin.module = ronin.file; | ||||
|         break; | ||||
|       case ">": | ||||
|         ronin.brush.passive(this.cmd); | ||||
|         ronin.module = ronin.brush; | ||||
|         break; | ||||
|       case "|": | ||||
|         ronin.overlay.passive(this.cmd); | ||||
|         ronin.module = ronin.overlay; | ||||
|         break; | ||||
|       case "^": // TODO | ||||
|         ronin.translate.passive(this.cmd); | ||||
|         ronin.module = ronin.translate; | ||||
|         break; | ||||
|       case "=": // TODO | ||||
|         ronin.zoom.passive(this.cmd); | ||||
|         ronin.module = ronin.zoom; | ||||
|         break; | ||||
|       case "$": | ||||
|         ronin.module = ronin.file; | ||||
|         break; | ||||
|       case ":": | ||||
|         ronin.filter.passive(this.cmd); | ||||
|         ronin.module = ronin.filter; | ||||
|         break; | ||||
|       case "+": | ||||
|         ronin.vector.passive(this.cmd); | ||||
|         ronin.module = ronin.vector; | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -1,39 +1,6 @@ | ||||
| function Command(content) | ||||
| { | ||||
|   this.content = raster(content); | ||||
|    | ||||
|   // Raster
 | ||||
|    | ||||
|   function raster(array) // @ {50w}x100
 | ||||
|   { | ||||
|     var str = array.join(" "); | ||||
|      | ||||
|     var m = str.replace(/(\{(.*)\})/g, function(a) { | ||||
|       var parts = a.split(/[{}]/); | ||||
|       for(var e = 0; e < parts.length; e++) { | ||||
|         if(str.indexOf("{"+parts[e]+"}") == -1){ continue; } | ||||
|         str = str.replace("{"+parts[e]+"}",converter(parts[e])); | ||||
|       } | ||||
|     }); | ||||
|     return str.split(" "); | ||||
|   } | ||||
|    | ||||
|   function converter(str) | ||||
|   { | ||||
|     var unit  = str.charAt(str.length - 1); | ||||
|     var value = parseFloat(str.replace(unit,'')); | ||||
|      | ||||
|     switch(unit) { | ||||
|       case "w": | ||||
|         return ronin.canvas.element.width * (value/100); | ||||
|         break; | ||||
|       case "h": | ||||
|         return ronin.canvas.element.height * (value/100); | ||||
|         break; | ||||
|     } | ||||
|      | ||||
|     return str; | ||||
|   } | ||||
|   this.content = content; | ||||
|    | ||||
|   // Parser
 | ||||
|    | ||||
| @@ -46,7 +13,7 @@ function Command(content) | ||||
|   this.rect = function() | ||||
|   { | ||||
|     for (i = 0; i < this.content.length; i++) { | ||||
|       if(this.content[i].indexOf("x") >= 0){ return new Rect(this.content[i]); } | ||||
|       if(this.content[i].indexOf("x") >= 0 && this.content[i].indexOf("/") < 0){ return new Rect(this.content[i]); } | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| @@ -111,7 +78,12 @@ function Command(content) | ||||
|   this.variable = function(name) | ||||
|   { | ||||
|     for (i = 0; i < this.content.length; i++) { | ||||
|       if(this.content[i].indexOf(name+":") >= 0){ return Variable(this.content[i]); } | ||||
|       if(this.content[i].indexOf("=") >= 0){ | ||||
|         var parts = this.content[i].split("="); | ||||
|         if(parts[0] == name){ | ||||
|           return new Variable(parts[0],parts[1]); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
							
								
								
									
										38
									
								
								scripts/core/commander.hint.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								scripts/core/commander.hint.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| function Hint(element) | ||||
| { | ||||
|   Module.call(this); | ||||
|    | ||||
|   this.element = element; | ||||
|    | ||||
|   this.update = function(module,cmd) | ||||
|   { | ||||
|     if(module){ | ||||
|       this.element.innerHTML = this.message(module,cmd); | ||||
|       this.element.style.display = "block"; | ||||
|     } | ||||
|     else if(commander && commander.element_input.value != ""){ | ||||
|       this.element.innerHTML = commander.element_input.value; | ||||
|       this.element.style.display = "block"; | ||||
|     } | ||||
|     else{ | ||||
|       this.element.innerHTML = this.default(); | ||||
|       this.element.style.display = "block"; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.message = function(module,cmd) | ||||
|   { | ||||
|     return module.hint(cmd); | ||||
|   } | ||||
|    | ||||
|   this.default = function() | ||||
|   { | ||||
|     var s = "<span class='module'>Modules</span>"; | ||||
|      | ||||
|     for (var key in ronin.modules){ | ||||
|       s += "<span> <span class='value'>"+key+"</span> <span class='param'>"+ronin.modules[key].constructor.name.substr(0,2)+" "; | ||||
|     } | ||||
|      | ||||
|     return s; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										99
									
								
								scripts/core/commander.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								scripts/core/commander.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| function Commander(element,element_input) | ||||
| { | ||||
|   this.element = element; | ||||
|   this.element_input = element_input; | ||||
|   this.hint = new Hint(); | ||||
|   this.storage = []; | ||||
|   this.storage_index = 0; | ||||
|   this.always_show = false; | ||||
|  | ||||
|   var queue = []; | ||||
|    | ||||
|   this.query = function(input_str) | ||||
|   { | ||||
|     if(input_str.indexOf(";") > 0){ | ||||
|       queue = input_str.split(";"); | ||||
|     } | ||||
|     else{ | ||||
|       queue.push(input_str) | ||||
|     } | ||||
|     run(); | ||||
|     this.hide(); | ||||
|   } | ||||
|  | ||||
|   function run() | ||||
|   { | ||||
|     console.log("~ "+queue[0].trim()); | ||||
|     active(queue[0].trim()); | ||||
|  | ||||
|     queue.shift(); | ||||
|     if(queue.length > 0){ | ||||
|       setTimeout(function(){ run(); }, 100); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function active(content) | ||||
|   { | ||||
|     var key = content[0]; | ||||
|     var cmd = new Command(content.substring(1).trim().split(" ")); | ||||
|      | ||||
|     if(ronin.modules[key]){ | ||||
|       ronin.modules[key].active(cmd); | ||||
|     } | ||||
|      | ||||
|     ronin.history.add(content); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(content) | ||||
|   { | ||||
|     var key = content[0]; | ||||
|     var cmd = new Command(content.substring(1).split(" ")); | ||||
|      | ||||
|     ronin.module = null; | ||||
|      | ||||
|     if(ronin.modules[key]){ | ||||
|       ronin.modules[key].passive(cmd); | ||||
|       ronin.module = ronin.modules[key]; | ||||
|     } | ||||
|     this.hint.update(ronin.module,cmd); | ||||
|   } | ||||
|    | ||||
|   // | ||||
|    | ||||
|   this.show = function() | ||||
|   { | ||||
|     this.element.setAttribute('class','visible'); | ||||
|     this.element_input.focus(); | ||||
|     this.element_input.value = ""; | ||||
|   } | ||||
|  | ||||
|   this.always = function() { | ||||
|     this.always_show = !this.always_show; | ||||
|   } | ||||
|    | ||||
|   this.hide = function() | ||||
|   { | ||||
|     if (!this.always_show) { | ||||
|       this.element.setAttribute('class','hidden'); | ||||
|     } | ||||
|     this.element_input.value = ""; | ||||
|   } | ||||
|    | ||||
|   this.clear = function() | ||||
|   { | ||||
|     this.element_input.value = ""; | ||||
|   } | ||||
|    | ||||
|   this.next_cmd = function() | ||||
|   { | ||||
|     this.storage_index += this.storage_index < this.storage.length ? 1 : 0; | ||||
|     this.element_input.value = this.storage[this.storage_index] ? this.storage[this.storage_index] : ""; | ||||
|   } | ||||
|    | ||||
|   this.prev_cmd = function() | ||||
|   { | ||||
|     this.storage_index -= this.storage_index < 1 ? 0 : 1; | ||||
|     this.element_input.value = this.storage[this.storage_index]; | ||||
|   } | ||||
|    | ||||
| } | ||||
							
								
								
									
										45
									
								
								scripts/core/cursor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								scripts/core/cursor.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| function Cursor() | ||||
| { | ||||
|   this.mode = null; | ||||
|   this.position = new Position(); | ||||
|    | ||||
|   this.update = function(event) | ||||
|   { | ||||
|     if(event.ctrltKey === true && event.altKey === true && event.shiftKey === true){ /* */  } | ||||
|     else if(event.shiftKey === true && event.ctrlKey === true){ this.set_mode(ronin.eye); } | ||||
|     else if(event.shiftKey === true && event.altKey === true){ this.set_mode(ronin.surface.active_layer); } | ||||
|     else if(event.ctrltKey === true && event.altKey === true){ this.set_mode(ronin.overlay.compositor);  } | ||||
|     else if(event.ctrlKey === true){ this.set_mode(ronin.overlay); } | ||||
|     else if(event.altKey === true){ this.set_mode(ronin.surface); } | ||||
|     else if(event.shiftKey === true){ this.set_mode(ronin.eraser); } | ||||
|     else{ this.set_mode(ronin.brush); } | ||||
|   } | ||||
|    | ||||
|   this.set_mode = function(mode) | ||||
|   { | ||||
|     if(this.mode == mode){ return; } | ||||
|     this.mode = mode; | ||||
|     document.body.setAttribute("class",this.mode.constructor.name); | ||||
|     ronin.widget.update(); | ||||
|   } | ||||
|    | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     this.position = position; | ||||
|     this.mode.mouse_down(position); | ||||
|     ronin.widget.update(); | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     this.position = position; | ||||
|     this.mode.mouse_move(position); | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(position) | ||||
|   { | ||||
|     this.position = position; | ||||
|     this.mode.mouse_up(position); | ||||
|     ronin.widget.update(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										42
									
								
								scripts/core/init.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								scripts/core/init.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| var ronin = new Ronin(); | ||||
| ronin.element = document.getElementById('ronin'); | ||||
| ronin.overlay.element = document.getElementById('overlay'); | ||||
| ronin.surface.element = document.getElementById('surface'); | ||||
| ronin.widget.element = document.getElementById('widget'); | ||||
| ronin.cursor.mode = ronin.brush; | ||||
|  | ||||
| var commander = new Commander(document.getElementById("commander"),document.getElementById("commander_input")); | ||||
| commander.hint.element = document.getElementById('commander_hint'); | ||||
|  | ||||
| // Cursor | ||||
|  | ||||
| document.addEventListener('mousedown', function(e){ ronin.cursor.mouse_down(ronin.position_in_canvas(e));}, false); | ||||
| document.addEventListener('mousemove', function(e){ ronin.cursor.mouse_move(ronin.position_in_canvas(e));}, false); | ||||
| document.addEventListener('mouseup', function(e){ ronin.cursor.mouse_up(ronin.position_in_canvas(e));}, false); | ||||
| document.addEventListener('contextmenu', function(ev){ ev.preventDefault(); return false;}, false); | ||||
| window.addEventListener('resize', function(){ ronin.on_resize(); }, true); | ||||
|  | ||||
| // Keyboard | ||||
|  | ||||
| var keyboard = new Keyboard(); | ||||
| document.onkeyup = function myFunction(){ keyboard.listen_onkeyup(event); }; | ||||
| document.onkeydown = function myFunction(){ keyboard.listen_onkeydown(event); }; | ||||
|  | ||||
| // Canvas | ||||
| var starting_canvas = new Rect(); | ||||
| starting_canvas.width = window.innerWidth - 200; | ||||
| starting_canvas.height = window.innerHeight - 200; | ||||
|  | ||||
| // Clamp | ||||
|  | ||||
| starting_canvas.width = parseInt(starting_canvas.width/40) * 40; | ||||
| starting_canvas.height = parseInt(starting_canvas.height/40) * 40; | ||||
|  | ||||
| commander.query("~ "+ronin.timestamp()); | ||||
| commander.query("# "+starting_canvas.render()); | ||||
| commander.query("# layer=background"); | ||||
| commander.query("# #efefef"); | ||||
| commander.query("# layer=main"); | ||||
| commander.query("> 1 0,0 #000000"); | ||||
| commander.query("> 1 1,0 #000000"); | ||||
| commander.query("> 1 0,1 #000000"); | ||||
							
								
								
									
										80
									
								
								scripts/core/keyboard.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								scripts/core/keyboard.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| function Keyboard() | ||||
| { | ||||
|   this.listen_onkeyup = function(event) | ||||
|   { | ||||
|     switch (event.key) { | ||||
|       case "Enter": this.key_enter(); break; | ||||
|       case "ArrowUp": this.key_arrow_up(); break; | ||||
|       case "ArrowDown": this.key_arrow_down(); break; | ||||
|       case "ArrowLeft": this.key_arrow_left(); break; | ||||
|       case "ArrowRight": this.key_arrow_right(); break; | ||||
|       // case ":": this.key_colon(); break; | ||||
|       case "Escape": this.key_escape(); break; | ||||
|     } | ||||
|  | ||||
|     switch(event.which) | ||||
|     { | ||||
|       case 13:  this.key_enter();  break; | ||||
|       case 186: if(event.shiftKey){this.key_colon();}  break; | ||||
|       case 27:  this.key_escape(); break; | ||||
|       case 219:  ronin.brush.size_up(); break; | ||||
|       case 221:  ronin.brush.size_down(); break; | ||||
|       case 38:  ronin.surface.layer_up(); break; | ||||
|       case 40:  ronin.surface.layer_down(); break; | ||||
|     } | ||||
|  | ||||
|     // Passive | ||||
|     commander.passive(commander.element_input.value); | ||||
|      | ||||
|     ronin.cursor.set_mode(ronin.brush); | ||||
|     ronin.widget.update(); | ||||
|   }; | ||||
|    | ||||
|   this.listen_onkeydown = function(event) | ||||
|   { | ||||
|     ronin.cursor.update(event); | ||||
|   } | ||||
|  | ||||
|   this.key_tab = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_enter = function() | ||||
|   { | ||||
|     commander.query(commander.element_input.value); | ||||
|   } | ||||
|  | ||||
|   this.key_space = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_up = function() | ||||
|   { | ||||
|     commander.prev_cmd(); | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_down = function() | ||||
|   { | ||||
|     commander.next_cmd(); | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_left = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_right = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_colon = function() | ||||
|   { | ||||
|     commander.show(); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   this.key_escape = function() | ||||
|   { | ||||
|     commander.hide(); | ||||
|     ronin.overlay.clear(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										66
									
								
								scripts/core/ronin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								scripts/core/ronin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| function Ronin() | ||||
| { | ||||
|   this.modules  = {}; | ||||
|   this.element  = null;   | ||||
|   this.widget   = new Widget(); | ||||
|    | ||||
|   this.surface  = new Surface("#"); | ||||
|   this.fileload = new FileLoad("/"); | ||||
|   this.filesave = new FileSave("$"); | ||||
|   this.history  = new History("^"); | ||||
|   this.overlay  = new Overlay("|"); | ||||
|   this.brush    = new Brush(">"); | ||||
|   this.eraser   = new Eraser("."); | ||||
|   this.eye      = new Eye("*"); | ||||
|   this.render   = new Render("%"); | ||||
|   this.stroke   = new Stroke("_"); | ||||
|   this.vector   = new Vector("+"); | ||||
|   this.help     = new Help("?"); | ||||
|   this.typo     = new Typographe("&"); | ||||
|    | ||||
|   this.cursor   = new Cursor(); | ||||
|    | ||||
|   this.modules[this.surface.rune]  = this.surface; | ||||
|   this.modules[this.fileload.rune] = this.fileload; | ||||
|   this.modules[this.filesave.rune] = this.filesave; | ||||
|   this.modules[this.history.rune]  = this.history; | ||||
|   this.modules[this.overlay.rune]  = this.overlay; | ||||
|   this.modules[this.render.rune]   = this.render; | ||||
|   this.modules[this.brush.rune]    = this.brush; | ||||
|   this.modules[this.eraser.rune]   = this.eraser; | ||||
|   this.modules[this.eye.rune]      = this.eye; | ||||
|   this.modules[this.typo.rune]     = this.typo; | ||||
|   this.modules[this.stroke.rune]   = this.stroke; | ||||
|   this.modules[this.vector.rune]   = this.vector; | ||||
|   this.modules[this.help.rune]     = this.help; | ||||
|    | ||||
|   this.cursors = []; | ||||
|    | ||||
|   this.position_in_canvas = function(e) | ||||
|   { | ||||
|     var x = e.clientX; | ||||
|     x -= (window.innerWidth - this.surface.size.width)/2; | ||||
|     x -= parseInt(this.surface.element.style.marginLeft) + (this.surface.size.width/2); | ||||
|     var y = e.clientY; | ||||
|     y -= (window.innerHeight - this.surface.size.height)/2; | ||||
|     y -= parseInt(this.surface.element.style.marginTop) + parseInt(this.surface.size.height/2); | ||||
|     return new Position(x,y); | ||||
|   } | ||||
|    | ||||
|   this.position_in_window = function(p) | ||||
|   { | ||||
|     return new Position(p.x + parseInt(this.surface.element.style.marginLeft),p.y + parseInt(this.surface.element.style.marginTop)); | ||||
|   } | ||||
|    | ||||
|   this.timestamp = function() | ||||
|   { | ||||
|     var currentdate = new Date(); | ||||
|     var date = currentdate.getFullYear()+""+(currentdate.getMonth()+1)+""+currentdate.getDate(); | ||||
|     return date+" "+currentdate.getHours()+":"+currentdate.getMinutes()+":"+currentdate.getSeconds(); | ||||
|   } | ||||
|  | ||||
|   this.on_resize = function() | ||||
|   { | ||||
|     this.widget.on_resize(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										26
									
								
								scripts/core/widget.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								scripts/core/widget.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| function Widget() | ||||
| { | ||||
|   this.element = null; | ||||
|    | ||||
|   this.update = function() | ||||
|   { | ||||
|     var s = ""; | ||||
|      | ||||
|     for (var key in ronin.modules){ | ||||
|       s += ronin.modules[key].widget() ? "<div class='module'>"+ronin.modules[key].widget()+"</div>" : ""; | ||||
|     } | ||||
|    | ||||
|     s += "<div class='cursor'>"+ronin.cursor.mode.widget_cursor()+"</div>"; | ||||
|      | ||||
|     this.element.innerHTML = s; | ||||
|   } | ||||
|  | ||||
|   this.on_resize = function() | ||||
|   { | ||||
|     this.element.style.left = (window.innerWidth/2)-(ronin.surface.size.width/2); | ||||
|     this.element.style.top = (window.innerHeight/2)+(ronin.surface.size.height/2); | ||||
|     this.element.style.width = ronin.surface.size.width+"px"; | ||||
|      | ||||
|     this.update(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										46
									
								
								scripts/filters/_balance.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								scripts/filters/_balance.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| Filter.prototype.filter_balance = function(pixels = this.pixels(),p = null) | ||||
| { | ||||
|   // / media/filter.color.jpg | ||||
|   // : balance 0.5 2.4 1.2 | ||||
|    | ||||
|   p[0] = parseFloat(p[0]); | ||||
|   p[1] = p[1] ? parseFloat(p[1]) : parseFloat(p[0]); | ||||
|   p[2] = p[2] ? parseFloat(p[2]) : parseFloat(p[0]); | ||||
|    | ||||
|   var data = pixels.data; | ||||
|    | ||||
|   // Multiply | ||||
|   if(p[0] % 1 !== 0 && p[1] % 1 !== 0 && p[2] % 1 !== 0){ | ||||
|     console.log("Multi"); | ||||
|     for (var i = 0; i < data.length; i += 4) { | ||||
|       data[i]     = data[i] * p[0];                     // red | ||||
|       data[i + 1] = data[i + 1] * p[1]; // green | ||||
|       data[i + 2] = data[i + 2] * p[2]; // blue | ||||
|        | ||||
|       // Clamp | ||||
|       data[i] = data[i] < 255 ? data[i] : 255; | ||||
|       data[i + 1] = data[i + 1] < 255 ? data[i + 1] : 255; | ||||
|       data[i + 2] = data[i + 2] < 255 ? data[i + 2] : 255; | ||||
|     } | ||||
|   } | ||||
|   // Add | ||||
|   else{ | ||||
|     p[0] = parseInt(p[0]); | ||||
|     p[1] = p[1] ? parseInt(p[1]) : parseInt(p[0]); | ||||
|     p[2] = p[2] ? parseInt(p[2]) : parseInt(p[0]); | ||||
|      | ||||
|     for (i = 0; i < data.length; i += 4) { | ||||
|       data[i]     = data[i] + p[0];                     // red | ||||
|       data[i + 1] = data[i + 1] + p[1]; // green | ||||
|       data[i + 2] = data[i + 2] + p[2]; // blue | ||||
|        | ||||
|       // Clamp | ||||
|       data[i] = data[i] < 255 ? data[i] : 255; | ||||
|       data[i + 1] = data[i + 1] < 255 ? data[i + 1] : 255; | ||||
|       data[i + 2] = data[i + 2] < 255 ? data[i + 2] : 255; | ||||
|     } | ||||
|   } | ||||
|    | ||||
| 	ronin.canvas.clear(); | ||||
| 	ronin.surface.context().putImageData(pixels, 0, 0, 0, 0, pixels.width, pixels.height); | ||||
| } | ||||
							
								
								
									
										19
									
								
								scripts/filters/_offset.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								scripts/filters/_offset.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| Filter.prototype.filter_offset = function(pixels = this.pixels(),p = null) | ||||
| { | ||||
|   var v = 255; // defaults to 255 if no parameter specified | ||||
|   if (p.length > 0 && p[0]) { | ||||
|       v = parseInt(p[0]); | ||||
|       // permissible range is 0 <= v <= 255 | ||||
|       if (v > 255) { v = 255;}  | ||||
|       if (v < 0) { v = 0;} | ||||
|   } | ||||
|   var d = pixels.data; | ||||
|  | ||||
|   for (var i=0; i<d.length; i+=4) { | ||||
|       for (var j=0; j<3; j++) { | ||||
|           d[i+j] = v - d[i+j]; | ||||
|       } | ||||
|   } | ||||
| 	ronin.canvas.clear(); | ||||
| 	ronin.surface.context().putImageData(pixels, 0, 0, 0, 0, pixels.width, pixels.height); | ||||
| } | ||||
							
								
								
									
										15
									
								
								scripts/filters/_saturation.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								scripts/filters/_saturation.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| Filter.prototype.filter_saturation = function(pixels = this.pixels(),p = null) | ||||
| { | ||||
|   var d = pixels.data; | ||||
|   for (var i=0; i<d.length; i+=4) { | ||||
|     var r = d[i]; | ||||
|     var g = d[i+1]; | ||||
|     var b = d[i+2]; | ||||
|     // CIE luminance for the RGB | ||||
|     // The human eye is bad at seeing red and blue, so we de-emphasize them. | ||||
|     var v = 0.2126*r + 0.7152*g + 0.0722*b; | ||||
|     d[i] = d[i+1] = d[i+2] = v | ||||
|   } | ||||
| 	ronin.canvas.clear(); | ||||
| 	ronin.surface.context().putImageData(pixels, 0, 0, 0, 0, pixels.width, pixels.height); | ||||
| } | ||||
							
								
								
									
										43
									
								
								scripts/filters/chromatic.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								scripts/filters/chromatic.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| function Filter_Chromatic() | ||||
| { | ||||
|   Filter.call(this); | ||||
|    | ||||
|   this.parameters = []; | ||||
|  | ||||
| 	// var pixels = this.pixels(); | ||||
| 	// var s; | ||||
| 	// if(p.length === 0) | ||||
| 	// 	s = {r:2,g:2,b:2}; | ||||
| 	// else if(p.length < 3) | ||||
| 	// 	s = {r:parseFloat(p[0]), g:parseFloat(p[0])*.5, b:0}; | ||||
| 	// else | ||||
| 	// 	s = {r:parseFloat(p[0]), g:parseFloat(p[1]), b:parseFloat(p[2])}; | ||||
| 	// var hw = pixels.width*.5; | ||||
| 	// var hh = pixels.height*.5; | ||||
| 	// var maxLength = Math.sqrt(hw*hw+hh*hh); | ||||
| 	// var output = new ImageData(pixels.width, pixels.height); | ||||
|  //  for (var i=0; i<pixels.width; i++) { | ||||
| 	// 		for(var j=0; j<pixels.height; j++){ | ||||
| 	// 			var x = i-hw; | ||||
| 	// 			var y = j-hh; | ||||
| 	// 			var a = Math.atan2(y,x); | ||||
| 	// 			var d = Math.sqrt(x*x+y*y); | ||||
| 	// 			var f = (d-s.r*d/maxLength); | ||||
| 	// 			x = Math.cos(a)*f+hw; | ||||
| 	// 			y = Math.sin(a)*f+hh; | ||||
| 	// 			var r = this.get_color_bilinear(pixels, x, y); | ||||
| 	// 			f = (d-s.g*d/maxLength); | ||||
| 	// 			x = Math.cos(a)*f+hw; | ||||
| 	// 			y = Math.sin(a)*f+hh; | ||||
| 	// 			var g = this.get_color_bilinear(pixels, x, y); | ||||
| 	// 			f = (d-s.b*d/maxLength); | ||||
| 	// 			x = Math.cos(a)*f+hw; | ||||
| 	// 			y = Math.sin(a)*f+hh; | ||||
| 	// 			var b = this.get_color_bilinear(pixels, x, y); | ||||
| 	// 			var c = {r:r.r, g:g.g, b:b.b,a:Math.max(r.a, Math.max(g.a,b.a))}; | ||||
| 	// 			this.set_color(output, c, i,j); | ||||
| 	// 		} | ||||
|  //  } | ||||
| 	// ronin.canvas.clear(); | ||||
| 	// ronin.surface.context().putImageData(output, 0, 0, 0, 0, pixels.width, pixels.height); | ||||
| } | ||||
							
								
								
									
										60
									
								
								scripts/filters/filter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								scripts/filters/filter.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| function Filter() | ||||
| { | ||||
|   this.name = "Unknown"; | ||||
|   this.parameters = []; | ||||
|  | ||||
|   this.render = function(cmd) | ||||
|   { | ||||
|     console.log("render: Nothing here."); | ||||
|   } | ||||
|  | ||||
|   this.preview = function(cmd) | ||||
|   { | ||||
|     console.log("render: Nothing here."); | ||||
|   } | ||||
|  | ||||
|   this.set_color = function(pixels, color, x, y) | ||||
|   { | ||||
|     x = Math.max(0,Math.min(x,pixels.width-1)); | ||||
|     y = Math.max(0,Math.min(y,pixels.height-1)); | ||||
|     var index = (x+y*pixels.width)*4; | ||||
|     pixels.data[index] = color.r; | ||||
|     pixels.data[index+1] = color.g; | ||||
|     pixels.data[index+2] = color.b; | ||||
|     pixels.data[index+3] = color.a; | ||||
|   } | ||||
|    | ||||
|   this.get_color = function(pixels,x,y) | ||||
|   { | ||||
|     x = Math.max(0,Math.min(x,pixels.width-1)); | ||||
|     y = Math.max(0,Math.min(y,pixels.height-1)); | ||||
|     var index = (x+y*pixels.width)*4; | ||||
|     return {r:pixels.data[index], g:pixels.data[index+1], b:pixels.data[index+2], a:pixels.data[index+3]}; | ||||
|   } | ||||
|    | ||||
|   this.get_color_bilinear = function(pixels, x, y) | ||||
|   { | ||||
|     var c1 = this.get_color(pixels, Math.floor(x),Math.floor(y)); | ||||
|     var c2 = this.get_color(pixels, Math.ceil(x),Math.floor(y)); | ||||
|     var c3 = this.get_color(pixels, Math.floor(x),Math.ceil(y)); | ||||
|     var c4 = this.get_color(pixels, Math.ceil(x),Math.ceil(y)); | ||||
|     return this.lerp_color(this.lerp_color(c1,c2, x%1),this.lerp_color(c3,c4, x%1), y%1); | ||||
|   } | ||||
|    | ||||
|   this.lerp_color = function(c1, c2, t) | ||||
|   { | ||||
|     return {r:c1.r+t*(c2.r-c1.r), g:c1.g+t*(c2.g-c1.g), b:c1.b+t*(c2.b-c1.b), a:c1.a+t*(c2.a-c1.a)}; | ||||
|   } | ||||
|    | ||||
|   // | ||||
|  | ||||
|   this.context = function() | ||||
|   { | ||||
|     return ronin.surface.active_layer.context(); | ||||
|   } | ||||
|    | ||||
|   this.pixels = function() | ||||
|   { | ||||
|     return ronin.surface.active_layer.context().getImageData(0,0,ronin.surface.size.width * 2,ronin.surface.size.height * 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										25
									
								
								scripts/filters/invert.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								scripts/filters/invert.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| function Filter_Invert() | ||||
| { | ||||
|   Filter.call(this); | ||||
|   this.parameters = [Angle]; | ||||
|  | ||||
|   this.render = function(cmd) | ||||
|   { | ||||
|     var imageObj = new Image(); | ||||
|     imageObj.src = ronin.surface.active_layer.element.toDataURL('image/png'); | ||||
|  | ||||
|     var context = ronin.surface.active_layer.context(); | ||||
|  | ||||
|     var imageData = context.getImageData(0, 0, imageObj.width * 2, imageObj.height* 2); | ||||
|     var data = imageData.data; | ||||
|  | ||||
|     for(var i = 0; i < data.length; i += 4) { | ||||
|       data[i] = 255 - data[i]; | ||||
|       data[i + 1] = 255 - data[i + 1]; | ||||
|       data[i + 2] = 255 - data[i + 2]; | ||||
|     } | ||||
|  | ||||
|     ronin.surface.active_layer.clear(); | ||||
|     context.putImageData(imageData, 0, 0); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										42
									
								
								scripts/filters/rotate.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								scripts/filters/rotate.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| function Filter_Rotate() | ||||
| { | ||||
|   Filter.call(this); | ||||
|   this.parameters = [Angle,Position]; | ||||
|  | ||||
|   this.render = function(cmd) | ||||
|   { | ||||
|     var position = cmd.position() ? cmd.position() : new Position(ronin.surface.size.width/2,ronin.surface.size.height/2); | ||||
|     var angle = cmd.angle() ? cmd.angle().degrees : 90; | ||||
|  | ||||
|     ronin.overlay.clear(); | ||||
|     this.draw(this.context(),angle,position); | ||||
|     ronin.overlay.clear(); | ||||
|   } | ||||
|  | ||||
|   this.preview = function(cmd) | ||||
|   { | ||||
|     if(cmd.position()){ | ||||
|       ronin.overlay.clear(); | ||||
|       ronin.overlay.draw_pointer(cmd.position()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this.draw = function(context = this.context(), angle, position) | ||||
|   { | ||||
|     var w = ronin.surface.size.width; | ||||
|     var h = ronin.surface.size.height; | ||||
|  | ||||
|     ronin.overlay.context().drawImage(context.canvas,0,0,w,h); | ||||
|  | ||||
|     ronin.surface.active_layer.clear(); | ||||
|  | ||||
|     context.save(); | ||||
|     context.translate(position.x,position.y); | ||||
|     context.rotate(angle*Math.PI/180); | ||||
|  | ||||
|     context.drawImage(ronin.overlay.context().canvas, -position.x, -position.y,w,h) | ||||
|  | ||||
|     context.rotate(-angle*Math.PI/180); | ||||
|     context.restore(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										75
									
								
								scripts/filters/stencil.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								scripts/filters/stencil.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| function Filter_Stencil() | ||||
| { | ||||
|   Filter.call(this); | ||||
|   this.parameters = [Angle]; | ||||
|  | ||||
|   this.render = function(cmd) | ||||
|   { | ||||
|     this.draw(this.context(),cmd.angle() ? cmd.angle().degrees : 20); | ||||
|     ronin.overlay.clear(); | ||||
|   } | ||||
|  | ||||
|   this.preview = function(cmd) | ||||
|   { | ||||
|     ronin.overlay.clear(); | ||||
|     this.draw(ronin.overlay.context(),cmd.angle() ? cmd.angle().degrees : 20); | ||||
|   } | ||||
|  | ||||
|   this.draw = function(context = this.context(), angle = 20) | ||||
|   { | ||||
|     var w = ronin.surface.size.width; | ||||
|     var h = ronin.surface.size.height; | ||||
|      | ||||
|     context.translate(w/2,h/2); | ||||
|  | ||||
|     context.rotate(angle*Math.PI/180); | ||||
|  | ||||
|     this.line(context,-w,0,w,0); | ||||
|  | ||||
|     this.line(context,w*0.4,-h,w*0.4,h); | ||||
|     this.line(context,-w*0.4,-h,-w*0.4,h); | ||||
|  | ||||
|     this.line(context,-w,h*0.25,w,h*0.25); | ||||
|     this.line(context,-w,-h*0.25,w,-h*0.25); | ||||
|  | ||||
|     this.line(context,w*0.1,0,w*0.1,h); | ||||
|     this.line(context,-w*0.1,0,-w*0.1,-h); | ||||
|  | ||||
|     this.circle(context,w*0.4,-h*0.25,w*0.05,1,1.5); | ||||
|     this.circle(context,-w*0.4,h*0.25,w*0.05,0,0.5); | ||||
|  | ||||
|     context.font = "5px Arial"; | ||||
|     context.fillStyle = "#000000";  | ||||
|     context.fillText("GRID",(w*0.4)+10,10); | ||||
|  | ||||
|     context.font = "5px Arial"; | ||||
|     context.fillStyle = "#000000";  | ||||
|     context.fillText("GRID",(-w*0.4)-20,-10); | ||||
|  | ||||
|     context.rotate(-angle*Math.PI/180); | ||||
|     context.translate(-w/2,-h/2); | ||||
|   } | ||||
|  | ||||
|   this.line = function(context,x1,x2,y1,y2) | ||||
|   { | ||||
|     context.beginPath(); | ||||
|     context.moveTo(x1,x2); | ||||
|     context.lineTo(y1,y2); | ||||
|     context.lineCap="round"; | ||||
|     context.lineWidth = 0.5; | ||||
|     context.strokeStyle = "#000"; | ||||
|     context.stroke(); | ||||
|     context.closePath(); | ||||
|   } | ||||
|  | ||||
|   this.circle = function(context,x,y,r,c1,c2) | ||||
|   { | ||||
|     context.beginPath(); | ||||
|     context.arc(x,y,r,c1*Math.PI,c2*Math.PI); | ||||
|     context.lineCap="round"; | ||||
|     context.lineWidth = 0.5; | ||||
|     context.strokeStyle = "#000"; | ||||
|     context.stroke(); | ||||
|     context.closePath(); | ||||
|   } | ||||
| } | ||||
| @@ -1,17 +0,0 @@ | ||||
| var ronin = new Ronin(); | ||||
| ronin.canvas.element = document.getElementById('workspace'); | ||||
| ronin.overlay.element = document.getElementById('overlay'); | ||||
| ronin.hint.element = document.getElementById('commander_hint'); | ||||
|  | ||||
| var commander = new Commander(document.getElementById("commander"),document.getElementById("commander_input")); | ||||
|  | ||||
| // Interactive | ||||
|  | ||||
| document.addEventListener('mousemove', function(e)  { ronin.brush.draw(e); ; | ||||
| }, false); | ||||
| document.addEventListener('mousedown', function(e)  { if(e.which != 1){ return; } ronin.brush.draw_start(e); ronin.brush.draw(e) }, false); | ||||
| document.addEventListener('mouseup',   function(e)  { ronin.brush.draw_stop(e); document.getElementById("commander_input").focus();}, false); | ||||
|  | ||||
|  | ||||
| var keyboard = new Keyboard(); | ||||
| document.onkeyup = function myFunction(){ keyboard.listen(event); }; | ||||
| @@ -1,114 +0,0 @@ | ||||
| function Keyboard() | ||||
| { | ||||
|   this.is_locked = false; | ||||
|    | ||||
|   this.cmd = function() | ||||
|   { | ||||
|     var val = commander.element_input.value; | ||||
|      | ||||
|     if(val.indexOf(";") > 0){ | ||||
|       var cmds = val.split(";"); | ||||
|       var vals = []; | ||||
|       for (i = 0; i < cmds.length; i++) { | ||||
|         val = cmds[i].replace(/^\s+|\s+$/g, ''); | ||||
|         vals.push(val.split(" ")); | ||||
|       } | ||||
|       return vals; | ||||
|     } | ||||
|     else{ | ||||
|       return [val.split(" ")]; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.lock = function() | ||||
|   { | ||||
|     this.is_locked = true; | ||||
|     interface.actions_panel.style.color = "red"; | ||||
|   } | ||||
|  | ||||
|   this.unlock = function() | ||||
|   { | ||||
|     this.is_locked = false; | ||||
|     interface.actions_panel.style.color = "black"; | ||||
|   } | ||||
|  | ||||
|   this.listen = function(event) | ||||
|   { | ||||
|     if(this.is_locked === true){ return; } | ||||
|      | ||||
|     switch (event.keyCode) | ||||
|     { | ||||
|       case  9: this.key_tab(); break; | ||||
|       case 13: this.key_enter(); break; | ||||
|       case 32: this.key_space(); break; | ||||
|       case 38: this.key_arrow_up(); break; | ||||
|       case 40: this.key_arrow_down(); break; | ||||
|       case 37: this.key_arrow_left(); break; | ||||
|       case 39: this.key_arrow_right(); break; | ||||
|       case 186: this.key_colon(); break; | ||||
|       case 190: if (event.shiftKey) this.key_colon(); break; | ||||
|       case  27: this.key_escape(); break; | ||||
|     } | ||||
|      | ||||
|     // Passive | ||||
|     var cmd = commander.element_input.value; | ||||
|     commander.passive(cmd.split(" ")); | ||||
|     ronin.hint.update(); | ||||
|   }; | ||||
|  | ||||
|   this.key_tab = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_enter = function() | ||||
|   { | ||||
|     var cmd = commander.element_input.value; | ||||
|      | ||||
|     if(cmd.indexOf(";") > 0){ | ||||
|       var multi = cmd.split(";"); | ||||
|       var i = 0; | ||||
|       while(i < 100){ | ||||
|         if(multi[i]){commander.active(multi[i].split(" "));} | ||||
|         else{ break; } | ||||
|         i += 1; | ||||
|       } | ||||
|     } | ||||
|     else{ | ||||
|       commander.active(cmd.split(" ")); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this.key_space = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_up = function() | ||||
|   { | ||||
|     commander.prev_cmd(); | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_down = function() | ||||
|   { | ||||
|     commander.next_cmd(); | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_left = function() | ||||
|   { | ||||
|   } | ||||
|  | ||||
|   this.key_arrow_right = function() | ||||
|   { | ||||
|   } | ||||
|    | ||||
|   this.key_colon = function() | ||||
|   { | ||||
|     commander.show(); | ||||
|     return false; | ||||
|   } | ||||
|    | ||||
|   this.key_escape = function() | ||||
|   { | ||||
|     commander.hide(); | ||||
|     ronin.overlay.clear(); | ||||
|   } | ||||
| } | ||||
| @@ -1,19 +0,0 @@ | ||||
| function Module() | ||||
| { | ||||
|   this.parameters = []; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     console.log("Nothing to do."); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|     console.log("Nothing to do."); | ||||
|   } | ||||
|    | ||||
|   this.hint = function(cmd) | ||||
|   { | ||||
|     return "unknown"; | ||||
|   } | ||||
| } | ||||
| @@ -1,12 +1,11 @@ | ||||
| function Brush() | ||||
| function Brush(rune) | ||||
| { | ||||
|   Module.call(this); | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Position,Rect,Angle,Color,Value,Bang]; | ||||
|   this.pointers = [new Pointer(new Position())]; | ||||
|   this.variables  = {"natural" : false,"banking" : false}; | ||||
|   this.pointers = []; | ||||
|    | ||||
|   this.position = new Position(); | ||||
|   this.is_drawing = false; | ||||
|   this.size = 1; | ||||
|   this.opacity = 1; | ||||
|   this.color = new Color(); | ||||
| @@ -17,30 +16,20 @@ function Brush() | ||||
|   { | ||||
|     if(cmd.bang()){ this.pointers = []; } | ||||
|      | ||||
|     var pointer = new Pointer(); | ||||
|     // Pointer | ||||
|     if(cmd.rect() || cmd.position() || cmd.angle()){ | ||||
|       this.add_pointer(cmd); | ||||
|     } | ||||
|      | ||||
|     if(cmd.position()){ | ||||
|       pointer.offset = cmd.position(); | ||||
|     } | ||||
|     if(cmd.rect()){ | ||||
|       pointer.mirror = cmd.rect(); | ||||
|     } | ||||
|     if(cmd.variable("osc_scale") && cmd.variable("osc_rate")){ | ||||
|       pointer.osc_rate  = parseFloat(cmd.variable("osc_rate")); | ||||
|       pointer.osc_scale = parseFloat(cmd.variable("osc_scale")); | ||||
|     } | ||||
|     if(cmd.angle()){ | ||||
|       pointer.angle = cmd.angle(); | ||||
|     } | ||||
|     if(cmd.rect() || cmd.position() || cmd.variable("osc_rate") || cmd.angle()){ | ||||
|       this.add_pointer(pointer); | ||||
|     } | ||||
|     // Global | ||||
|     if(cmd.color()){ | ||||
|       this.color = cmd.color(); | ||||
|     } | ||||
|     if(cmd.value()){ | ||||
|       this.size = cmd.value().float; | ||||
|     } | ||||
|      | ||||
|     this.update_variables(cmd); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
| @@ -55,41 +44,83 @@ function Brush() | ||||
|       ronin.overlay.draw(cmd.position()); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.add_pointer = function(pointer) | ||||
|  | ||||
|   this.size_up = function() | ||||
|   { | ||||
|     this.size -= this.size > 1 ? 1 : 0; | ||||
|     ronin.widget.update(); | ||||
|   } | ||||
|  | ||||
|   this.size_down = function() | ||||
|   { | ||||
|      this.size += 1; | ||||
|      ronin.widget.update(); | ||||
|   } | ||||
|    | ||||
|   this.add_pointer = function(cmd) | ||||
|   { | ||||
|     var pointer = new Pointer(); | ||||
|      | ||||
|     if(cmd.position()){ | ||||
|       pointer.offset = cmd.position(); | ||||
|     } | ||||
|     if(cmd.rect()){ | ||||
|       pointer.mirror = cmd.rect(); | ||||
|     } | ||||
|     if(cmd.angle()){ | ||||
|       pointer.angle = cmd.angle(); | ||||
|     } | ||||
|      | ||||
|     this.pointers.push(pointer); | ||||
|   } | ||||
|    | ||||
|   // Draw | ||||
|    | ||||
|   this.draw = function(e) | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     if(this.is_drawing === false){return;} | ||||
|      | ||||
|     this.position = new Position(e.clientX,e.clientY); | ||||
|      | ||||
|     for (i = 0; i < this.pointers.length; i++) { | ||||
|       this.pointers[i].draw(); | ||||
|  | ||||
|     var s = "> "+this.size+"<br />"; | ||||
|  | ||||
|     for (i = 0; i < ronin.brush.pointers.length; i++) { | ||||
|       s += ronin.brush.pointers[i].widget(); | ||||
|     } | ||||
|     return s; | ||||
|  | ||||
|     return this.pointers.length > 0 ? "Brush "+this.size+", "+this.pointers.length+" pointers" : "No Pointers"; | ||||
|   } | ||||
|    | ||||
|   this.draw_start = function(e) | ||||
|   // Cursor | ||||
|  | ||||
|   this.is_drawing = false; | ||||
|    | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     this.is_drawing = true; | ||||
|      | ||||
|     for (i = 0; i < this.pointers.length; i++) { | ||||
|       this.pointers[i].start(); | ||||
|     for (i = 0; i < ronin.brush.pointers.length; i++) { | ||||
|       ronin.brush.pointers[i].start(); | ||||
|     } | ||||
|      | ||||
|     ronin.stroke.new_stroke(); | ||||
|   } | ||||
|    | ||||
|   this.draw_stop = function(e) | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     if(this.is_drawing === false){ return; } | ||||
|    | ||||
|     for (i = 0; i < ronin.brush.pointers.length; i++) { | ||||
|       ronin.brush.pointers[i].draw(); | ||||
|     } | ||||
|      | ||||
|     ronin.stroke.append_stroke(position); | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(position) | ||||
|   { | ||||
|     this.is_drawing = false; | ||||
|      | ||||
|     for (i = 0; i < this.pointers.length; i++) { | ||||
|       this.pointers[i].stop(); | ||||
|     for (i = 0; i < ronin.brush.pointers.length; i++) { | ||||
|       ronin.brush.pointers[i].stop(); | ||||
|     } | ||||
|      | ||||
|     ronin.stroke.save_stroke("brush"); | ||||
|   } | ||||
|    | ||||
| } | ||||
| @@ -6,67 +6,105 @@ function Pointer(offset = new Position(), color = new Color('000000')) | ||||
|   this.angle = null; | ||||
|   this.distance = 0; | ||||
|    | ||||
|   this.osc_scale = null; | ||||
|   this.osc_rate = null; | ||||
|    | ||||
|   this.draw = function() | ||||
|   { | ||||
|     if(!this.position_prev){this.position_prev = this.position(); } | ||||
|     if(ronin.brush.size < 0){ this.erase(); return; } | ||||
|      | ||||
|     var position = this.position(); | ||||
|      | ||||
|     this.distance += position.distance_to(this.position_prev); | ||||
|      | ||||
|     // Osc experiment | ||||
|     if(this.osc_rate && this.osc_scale){ | ||||
|       // position.x += (Math.sin(this.distance/(25 * this.osc_rate)) * this.osc_scale) - (this.osc_scale/2); | ||||
|       position.y += (Math.sin(this.distance/(25 * this.osc_rate)) * this.osc_scale) - (this.osc_scale/2); | ||||
|     } | ||||
|      | ||||
|     ronin.canvas.context().beginPath(); | ||||
|     ronin.canvas.context().moveTo(this.position_prev.x,this.position_prev.y); | ||||
|     ronin.canvas.context().lineTo(position.x,position.y); | ||||
|     ronin.canvas.context().lineCap="round"; | ||||
|     ronin.canvas.context().lineWidth = this.thickness(); | ||||
|     ronin.canvas.context().strokeStyle = ronin.brush.color.rgba(); | ||||
|     ronin.canvas.context().stroke(); | ||||
|     ronin.canvas.context().closePath(); | ||||
|      | ||||
|     this.position_prev = position; | ||||
|   } | ||||
|    | ||||
|   this.erase = function() | ||||
|   { | ||||
|     ronin.canvas.context().clearRect(this.position().x - (ronin.brush.size/2), this.position().y - (ronin.brush.size/2), ronin.brush.size, ronin.brush.size); | ||||
|   } | ||||
|    | ||||
|   // Parameters | ||||
|  | ||||
|   this.thickness = function() | ||||
|   { | ||||
|     var ratio = 10/this.position().distance_to(this.position_prev); | ||||
|     var ratio = 10/this.position().distance_to(this.position_prev[0]); | ||||
|     ratio = ratio > 1 ? 1 : ratio; | ||||
|     return ronin.brush.size * ratio; | ||||
|   } | ||||
|    | ||||
|   // | ||||
|  | ||||
|   this.draw = function() | ||||
|   { | ||||
|     if(!this.position_prev){this.position_prev = [this.position()]; return; } | ||||
|  | ||||
|     var position = this.position(); | ||||
|     var position_prev = this.position_prev[0]; | ||||
|  | ||||
|     //remove stale previous positions | ||||
|     if (this.position_prev.length > 3) this.position_prev.pop(); | ||||
|  | ||||
|     this.distance += position.distance_to(position_prev); | ||||
|  | ||||
|     ronin.surface.context().beginPath(); | ||||
|  | ||||
|     ronin.surface.context().globalCompositeOperation="source-over"; | ||||
|     ronin.surface.context().moveTo(position_prev.x,position_prev.y); | ||||
|  | ||||
|     //Choose direct line or curve line based on how many samples available | ||||
|     if(this.position_prev.length > 1 && position.distance_to(position_prev) > 13){ | ||||
|  | ||||
|       var d = | ||||
|       position.distance_to(position_prev)/ | ||||
|       position_prev.distance_to(this.position_prev[1]); | ||||
|  | ||||
|       //caluclate a control point for the quad curve | ||||
|       var ppx = position_prev.x - (this.position_prev[1].x - position_prev.x); | ||||
|       var ppy = position_prev.y - (this.position_prev[1].y - position_prev.y); | ||||
|       var px = (position.x + position_prev.x)/2; | ||||
|       var py = (position.y + position_prev.y)/2; | ||||
|       var tx = px + (ppx - px) * 0.2 * d; | ||||
|       var ty = py + (ppy - py) * 0.2 * d; | ||||
|  | ||||
|       ronin.surface.context().quadraticCurveTo(tx,ty,position.x,position.y); | ||||
|     } | ||||
|     else { | ||||
|       ronin.surface.context().lineTo(position.x,position.y); | ||||
|     } | ||||
|  | ||||
|     ronin.surface.context().lineCap="round"; | ||||
|     ronin.surface.context().lineWidth = this.thickness(); | ||||
|     ronin.surface.context().strokeStyle = ronin.brush.color.rgba(); | ||||
|     ronin.surface.context().stroke(); | ||||
|     ronin.surface.context().closePath(); | ||||
|  | ||||
|     this.position_prev.unshift(position); | ||||
|   } | ||||
|    | ||||
|   this.position = function() | ||||
|   { | ||||
|     if(this.angle){ | ||||
|       var angle_radian = this.angle.degrees * Math.PI / 180; | ||||
|       var deltaX = ronin.brush.position.x - this.offset.x; | ||||
|       var deltaY = ronin.brush.position.y - this.offset.y; | ||||
|       var t = Math.atan2(deltaY, deltaX) + angle_radian; | ||||
|       var radius = ronin.brush.position.distance_to(this.offset); | ||||
|       var x = Math.cos(t) * radius; | ||||
|       var y = Math.sin(t) * radius; | ||||
|       return new Position(x + this.offset.x,y + this.offset.y); | ||||
|     if(this.angle && this.offset){ | ||||
|       return this.position_rotation(); | ||||
|     } | ||||
|     else if(this.mirror && this.mirror.width > 0){ | ||||
|       return new Position((2 * this.mirror.width) - (ronin.brush.position.x + this.offset.x), 0 + (ronin.brush.position.y + this.offset.y)); | ||||
|       return this.position_mirror_x(); | ||||
|     } | ||||
|     else if(this.mirror && this.mirror.height > 0){ | ||||
|       return new Position((ronin.brush.position.x + this.offset.x), (2 * this.mirror.height) - (ronin.brush.position.y + this.offset.y)); | ||||
|       return this.position_mirror_y(); | ||||
|     } | ||||
|     return new Position(ronin.brush.position.x + this.offset.x, ronin.brush.position.y + this.offset.y); | ||||
|     return this.position_default(); | ||||
|   } | ||||
|    | ||||
|   // Effects | ||||
|    | ||||
|   this.position_default = function() | ||||
|   { | ||||
|     return ronin.cursor.position.add(this.offset); | ||||
|   } | ||||
|    | ||||
|   this.position_mirror_x = function() | ||||
|   { | ||||
|     return new Position((2 * this.mirror.width) - (ronin.cursor.position.x + this.offset.x), 0 + (ronin.cursor.position.y + this.offset.y)); | ||||
|   } | ||||
|    | ||||
|   this.position_mirror_y = function() | ||||
|   { | ||||
|     return new Position((ronin.cursor.position.x + this.offset.x), (2 * this.mirror.height) - (ronin.cursor.position.y + this.offset.y)); | ||||
|   } | ||||
|    | ||||
|   this.position_rotation = function() | ||||
|   { | ||||
|     var angle_radian = this.angle.degrees * Math.PI / 180; | ||||
|     var deltaX = ronin.cursor.position.x - this.offset.x; | ||||
|     var deltaY = ronin.cursor.position.y - this.offset.y; | ||||
|     var t = Math.atan2(deltaY, deltaX) + angle_radian; | ||||
|     var radius = ronin.cursor.position.distance_to(this.offset); | ||||
|     var x = Math.cos(t) * radius; | ||||
|     var y = Math.sin(t) * radius; | ||||
|     return new Position(x + this.offset.x,y + this.offset.y); | ||||
|   } | ||||
|    | ||||
|   this.start = function() | ||||
| @@ -77,4 +115,9 @@ function Pointer(offset = new Position(), color = new Color('000000')) | ||||
|   { | ||||
|     this.position_prev = null; | ||||
|   } | ||||
|  | ||||
|   this.widget = function() | ||||
|   { | ||||
|     return this.offset.render()+"<br />"; | ||||
|   } | ||||
| } | ||||
| @@ -1,49 +0,0 @@ | ||||
| function Canvas(element) | ||||
| { | ||||
|   Module.call(this); | ||||
|  | ||||
|   this.parameters = [Rect,Color,Bang]; | ||||
|   this.element = element; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     if(cmd.bang()){ this.clear(); } | ||||
|      | ||||
|     if(cmd.rect()){ | ||||
|       this.resize(cmd.rect()); | ||||
|       ronin.overlay.resize(cmd.rect()); | ||||
|     } | ||||
|      | ||||
|     if(cmd.color()){ | ||||
|       this.context().beginPath(); | ||||
|       this.context().rect(0, 0, this.element.width, this.element.height); | ||||
|       this.context().fillStyle = cmd.color().hex; | ||||
|       this.context().fill(); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|     if(cmd.rect()){ | ||||
|       ronin.overlay.show_guide(null,cmd.rect()); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   // | ||||
|    | ||||
|   this.resize = function(rect) | ||||
|   { | ||||
|     this.element.setAttribute('width',rect.width+"px"); | ||||
|     this.element.setAttribute('height',rect.height+"px"); | ||||
|   } | ||||
|    | ||||
|   this.context = function() | ||||
|   { | ||||
|     return this.element.getContext('2d'); | ||||
|   } | ||||
|    | ||||
|   this.clear = function() | ||||
|   { | ||||
|     this.context().clearRect(0, 0, this.element.width, this.element.height); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										79
									
								
								scripts/modules/eraser.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								scripts/modules/eraser.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| function Eraser(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Value]; | ||||
|   this.size = 5; | ||||
|    | ||||
|   // Module | ||||
|    | ||||
|   this.position_prev = null; | ||||
|    | ||||
|   this.draw = function() | ||||
|   { | ||||
|     if(!this.position_prev){this.position_prev = ronin.cursor.position; } | ||||
|     if(ronin.brush.size < 0){ this.erase(); return; } | ||||
|      | ||||
|     var position = ronin.cursor.position; | ||||
|      | ||||
|     this.distance += position.distance_to(this.position_prev); | ||||
|      | ||||
|     ronin.surface.context().beginPath(); | ||||
|     ronin.surface.context().globalCompositeOperation="destination-out"; | ||||
|     ronin.surface.context().moveTo(this.position_prev.x,this.position_prev.y); | ||||
|     ronin.surface.context().lineTo(position.x,position.y); | ||||
|     ronin.surface.context().lineCap="round"; | ||||
|     ronin.surface.context().lineWidth = this.size; | ||||
|     ronin.surface.context().strokeStyle = new Color("#ff0000").rgba(); | ||||
|     ronin.surface.context().stroke(); | ||||
|     ronin.surface.context().closePath(); | ||||
|      | ||||
|     this.position_prev = position; | ||||
|   } | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     if(cmd.value()){ | ||||
|       this.size = cmd.value().float; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|      | ||||
|   } | ||||
|  | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     return ". "+this.size; | ||||
|   } | ||||
|    | ||||
|   // Cursor | ||||
|  | ||||
|   this.is_drawing = false; | ||||
|    | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     this.is_drawing = true; | ||||
|     this.position_prev = null; | ||||
|      | ||||
|     ronin.stroke.new_stroke(); | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     if(this.is_drawing === false){ return; } | ||||
|    | ||||
|     this.draw(); | ||||
|      | ||||
|     ronin.stroke.append_stroke(position); | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(position) | ||||
|   { | ||||
|     this.is_drawing = false; | ||||
|     this.position_prev = null; | ||||
|      | ||||
|     ronin.stroke.save_stroke("eraser"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										45
									
								
								scripts/modules/eye.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								scripts/modules/eye.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| function Eye(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   // Module | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|   } | ||||
|    | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     return "Eye"; | ||||
|   } | ||||
|    | ||||
|   this.color_picker = function(position) | ||||
|   { | ||||
|     var imgData = ronin.surface.context().getImageData(position.x, position.y, 1, 1).data; | ||||
|     var c = new Color(); | ||||
|     commander.show(); | ||||
|     commander.element_input.focus(); | ||||
|     commander.element_input.value = "> "+(c.rgb_to_hex(imgData)); | ||||
|   } | ||||
|    | ||||
|   // Cursor | ||||
|    | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     this.color_picker(position); | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     this.color_picker(position); | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(position) | ||||
|   { | ||||
|     this.color_picker(position); | ||||
|   } | ||||
| } | ||||
| @@ -1,14 +1,11 @@ | ||||
| function File() | ||||
| function FileLoad(rune) | ||||
| { | ||||
|   Module.call(this); | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Filepath,Position,Rect,Bang]; | ||||
|   this.storage = []; | ||||
|   this.parameters = [Filepath,Position,Rect]; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     if(cmd.bang()){ this.storage = []; } | ||||
|      | ||||
|     ronin.overlay.clear(); | ||||
|      | ||||
|     if(!cmd.filepath() && !cmd.value()){ return; } | ||||
| @@ -16,7 +13,7 @@ function File() | ||||
|     var position = cmd.position() ? cmd.position() : new Position(); | ||||
|      | ||||
|     base_image = new Image(); | ||||
|     base_image.src = cmd.value() && this.storage[cmd.value().int] ? this.storage[cmd.value().int] : cmd.filepath().path; | ||||
|     base_image.src = cmd.filepath().path; | ||||
|     base_image.src += '?' + new Date().getTime(); | ||||
|     base_image.crossOrigin = "Anonymous"; | ||||
|      | ||||
| @@ -32,7 +29,7 @@ function File() | ||||
|       width  = isNaN(width) && height > 0 ? (height*base_image.naturalWidth)/base_image.naturalHeight : width; | ||||
|       height = isNaN(height) && width > 0 ? (width*base_image.naturalHeight)/base_image.naturalWidth : height; | ||||
|        | ||||
|       ronin.canvas.context().drawImage(base_image, position.x, position.y, width, height); | ||||
|       ronin.surface.context().drawImage(base_image, position.x, position.y, width, height); | ||||
|     } | ||||
|   } | ||||
|    | ||||
| @@ -49,16 +46,4 @@ function File() | ||||
|       ronin.overlay.draw(position); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.save = function(cmd) | ||||
|   { | ||||
|     if(cmd.value() && cmd.value().int > 0){ | ||||
|       this.storage[cmd.value().int] = ronin.canvas.element.toDataURL("image/png"); | ||||
|     } | ||||
|     else{ | ||||
|       var d = ronin.canvas.element.toDataURL("image/png"); | ||||
|       var w = window.open('about:blank','image from canvas'); | ||||
|       w.document.write("<title>"+(cmd.content[0] ? cmd.content[0] : "Untitled")+"</title><img src='"+d+"' alt='from canvas'/>"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										22
									
								
								scripts/modules/file.save.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								scripts/modules/file.save.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| function FileSave(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Any]; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     var n = "Ronin Export"; | ||||
|     var f = cmd.variable("format"); | ||||
|     var d = ronin.surface.merge(); | ||||
|     d = ronin.surface.active_layer.element.toDataURL('image/png'); | ||||
|     // // ronin.surface.layers["render"].clear(); | ||||
|     var w = window.open('about:blank','image from canvas'); | ||||
|     // w.document.write("hello") | ||||
|     w.document.write("<title>"+(n ? n : "Untitled")+"</title><body><img src='"+d+"' width='"+ronin.surface.size.width+"px' height='"+ronin.surface.size.height+"px'/></body>"); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|   } | ||||
| } | ||||
| @@ -1,121 +0,0 @@ | ||||
| function Filter(element) | ||||
| { | ||||
|   Module.call(this); | ||||
|    | ||||
|   this.parameters = [Text,Value]; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     if(cmd.content.length < 1){ return; } | ||||
|      | ||||
|     var p = cmd.content; | ||||
|     var filter_name = p[0]; | ||||
|     p.shift(); | ||||
|      | ||||
|     switch(filter_name) { | ||||
|       case "saturation": | ||||
|         this.filter_saturation(this.pixels(),p); | ||||
|         break; | ||||
|       case "chromatic": | ||||
|         this.filter_chromatic(this.pixels(),p); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|   } | ||||
|    | ||||
|   // Filters | ||||
|    | ||||
|   this.filter_saturation = function(pixels = this.pixels(),p = null) | ||||
|   { | ||||
|     var d = pixels.data; | ||||
|     for (var i=0; i<d.length; i+=4) { | ||||
|       var r = d[i]; | ||||
|       var g = d[i+1]; | ||||
|       var b = d[i+2]; | ||||
|       // CIE luminance for the RGB | ||||
|       // The human eye is bad at seeing red and blue, so we de-emphasize them. | ||||
|       var v = 0.2126*r + 0.7152*g + 0.0722*b; | ||||
|       d[i] = d[i+1] = d[i+2] = v | ||||
|     } | ||||
|   	ronin.canvas.clear(); | ||||
|   	ronin.canvas.context().putImageData(pixels, 0, 0, 0, 0, pixels.width, pixels.height); | ||||
|   } | ||||
|    | ||||
|   this.filter_chromatic = function(pixels = this.pixels(),p = null) | ||||
|   { | ||||
|   	var s; | ||||
| 		if(p.length == 0) | ||||
| 			s = {r:2,g:2,b:2}; | ||||
| 		else if(p.length < 3) | ||||
| 			s = {r:parseFloat(p[0]), g:parseFloat(p[0])*.5, b:0}; | ||||
| 		else | ||||
| 			s = {r:parseFloat(p[0]), g:parseFloat(p[1]), b:parseFloat(p[2])}; | ||||
| 		var hw = pixels.width*.5; | ||||
| 		var hh = pixels.height*.5; | ||||
| 		var maxLength = Math.sqrt(hw*hw+hh*hh); | ||||
| 		var output = new ImageData(pixels.width, pixels.height); | ||||
|     for (var i=0; i<pixels.width; i++) { | ||||
| 				for(var j=0; j<pixels.height; j++){ | ||||
| 					var x = i-hw; | ||||
| 					var y = j-hh; | ||||
| 					var a = Math.atan2(y,x); | ||||
| 					var d = Math.sqrt(x*x+y*y); | ||||
| 					var f = (d-s.r*d/maxLength); | ||||
| 					x = Math.cos(a)*f+hw; | ||||
| 					y = Math.sin(a)*f+hh; | ||||
| 					var r = this.get_color_bilinear(pixels, x, y); | ||||
| 					f = (d-s.g*d/maxLength); | ||||
| 					x = Math.cos(a)*f+hw; | ||||
| 					y = Math.sin(a)*f+hh; | ||||
| 					var g = this.get_color_bilinear(pixels, x, y); | ||||
| 					f = (d-s.b*d/maxLength); | ||||
| 					x = Math.cos(a)*f+hw; | ||||
| 					y = Math.sin(a)*f+hh; | ||||
| 					var b = this.get_color_bilinear(pixels, x, y); | ||||
| 					var c = {r:r.r, g:g.g, b:b.b,a:Math.max(r.a, Math.max(g.a,b.a))}; | ||||
| 					this.set_color(output, c, i,j); | ||||
| 				} | ||||
|     } | ||||
|   	ronin.canvas.clear(); | ||||
|   	ronin.canvas.context().putImageData(output, 0, 0, 0, 0, pixels.width, pixels.height); | ||||
|   } | ||||
| 	 | ||||
| 	this.set_color = function(pixels, color, x, y){ | ||||
| 		x = Math.max(0,Math.min(x,pixels.width-1)); | ||||
| 		y = Math.max(0,Math.min(y,pixels.height-1)); | ||||
| 		var index = (x+y*pixels.width)*4; | ||||
| 		pixels.data[index] = color.r; | ||||
| 		pixels.data[index+1] = color.g; | ||||
| 		pixels.data[index+2] = color.b; | ||||
| 		pixels.data[index+3] = color.a; | ||||
| 	} | ||||
| 	 | ||||
| 	this.get_color = function(pixels,x,y){ | ||||
| 		x = Math.max(0,Math.min(x,pixels.width-1)); | ||||
| 		y = Math.max(0,Math.min(y,pixels.height-1)); | ||||
| 		var index = (x+y*pixels.width)*4; | ||||
| 		return {r:pixels.data[index], g:pixels.data[index+1], b:pixels.data[index+2], a:pixels.data[index+3]}; | ||||
| 	} | ||||
| 	 | ||||
| 	this.get_color_bilinear = function(pixels, x, y){ | ||||
| 		var c1 = this.get_color(pixels, Math.floor(x),Math.floor(y)); | ||||
| 		var c2 = this.get_color(pixels, Math.ceil(x),Math.floor(y)); | ||||
| 		var c3 = this.get_color(pixels, Math.floor(x),Math.ceil(y)); | ||||
| 		var c4 = this.get_color(pixels, Math.ceil(x),Math.ceil(y)); | ||||
| 		return this.lerp_color(this.lerp_color(c1,c2, x%1),this.lerp_color(c3,c4, x%1), y%1); | ||||
| 	} | ||||
| 	 | ||||
| 	this.lerp_color = function(c1, c2, t){ | ||||
| 		return {r:c1.r+t*(c2.r-c1.r), g:c1.g+t*(c2.g-c1.g), b:c1.b+t*(c2.b-c1.b), a:c1.a+t*(c2.a-c1.a)}; | ||||
| 	} | ||||
|    | ||||
|   // | ||||
|    | ||||
|   this.pixels = function() | ||||
|   { | ||||
|     return ronin.canvas.context().getImageData(0,0,ronin.canvas.element.width,ronin.canvas.element.height); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										80
									
								
								scripts/modules/help.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								scripts/modules/help.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| function Help(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     var w = window.open('about:blank','image from canvas'); | ||||
|     var html = ""; | ||||
|     html += this.view_intro(); | ||||
|     html += this.view_modules(); | ||||
|     html += this.view_units(); | ||||
|     html += this.view_presets(); | ||||
|     w.document.write("<title>Help</title><style>body { font-size:11px;background:#fff; color:#000; padding:10px} pre {}</style><pre>"+html+"</pre>"); | ||||
|   } | ||||
|    | ||||
|   // | ||||
|  | ||||
|   this.view_intro = function() | ||||
|   { | ||||
|     var html = "# Ronin\n## Basics\nRonin is a web based drawing application and visual language. Launch index.html and press **:**(colon) to display the command prompt. Input the commands below to interface with the different tools. \n```\n:\n```\n"; | ||||
|  | ||||
|     html += "### Loading/Saving\nRequires you to run Ronin through localhost. Navigate to the Ronin folder, and run the simple http server.\n"; | ||||
|     html += "```\ncd /path/to/ronin/                ; Navigate to Ronin through the terminal\npython -m SimpleHTTPServer 8000   ; Start localhost\nhttp://localhost:8000/            ; Enjoy Ronin\n```\n"; | ||||
|     html += "### Controls\n"; | ||||
|     html += "```\nctrl                              ; Draw Overlays\nalt                               ; Drag Surface\nshift                             ; Erase\nshift+ctrl                        ; Eyedrop\nshift+alt                         ; Move Layer\n```\n"; | ||||
|     return html; | ||||
|   } | ||||
|    | ||||
|   this.view_modules = function() | ||||
|   { | ||||
|     html = "## Modules\n"; | ||||
|     Object.keys(ronin.modules).forEach(function (key) { | ||||
|       html += "### "+key+" "+ronin.modules[key].constructor.name+"\n"; | ||||
|       html += ronin.modules[key].docs+"\n"; | ||||
|       html += "- Parameters: "; | ||||
|       for (i = 0; i < ronin.modules[key].parameters.length; i++) { | ||||
|         html += "`"+ronin.modules[key].parameters[i].name+"` "; | ||||
|       } | ||||
|       html += "\n"; | ||||
|       html += "- Variables: "; | ||||
|       for (var key in ronin.modules[key].variables){ | ||||
|         html += "`"+key+"` "; | ||||
|       } | ||||
|       html += "\n\n"; | ||||
|     }); | ||||
|      | ||||
|     return html; | ||||
|   } | ||||
|  | ||||
|   this.view_units = function() | ||||
|   { | ||||
|     html = "## Units\n"; | ||||
|     html += "```\n5                                 ; value:    5\n5,7                               ; position: 5x 7y\n7x9                               ; rect:     7w 9h\n#ff0000                           ; color:    red\n0..5                              ; random:   0.0-5.0\n45'                               ; degree:   45/365\nrate=10                           ; variable: rate = 10\n```\n"; | ||||
|     return html; | ||||
|   } | ||||
|  | ||||
|   this.view_presets = function() | ||||
|   { | ||||
|     html = "## Presets\n"; | ||||
|     html += "### Radial Brush\n"; | ||||
|     html += "```\n# 8 strands\n> 600,400 45';> 600,400 90';> 600,400 135';> 600,400 180';> 600,400 225';> 600,400 270';> 600,400 315'\n# 6 strands\n> 600,400 60';> 600,400 120';> 600,400 180';> 600,400 240';> 600,400 300'\n```\n" | ||||
|     html += "### Symmetry Brush\n"; | ||||
|     html += "```\n# XY\n> 400x 3\n# Angular brushes\n> 400x 1,1;> 400x 2,2;> 400x 3,3; > 1,1;> 2,2;> 3,3;\n```\n" | ||||
|     html += "### Angular Brush\n"; | ||||
|     html += "```\n# Light\n> 1,1;> 2,2;> 3,3;> 4,4\n# Hard\n> 2,2;> 4,4;> 6,6;> 8,8\n# Symmetric Light\n> 1,1 600x;> 2,2 600x;> 3,3 600x;> 4,4 600x\n```\n"; | ||||
|  | ||||
|     return html; | ||||
|   } | ||||
|    | ||||
|   function pad(s,length) | ||||
|   { | ||||
|     if(!s){ return s; } | ||||
|      | ||||
|     var new_string = s; | ||||
|     while(new_string.length < length){ | ||||
|       new_string += " "; | ||||
|     } | ||||
|     return new_string; | ||||
|   } | ||||
| } | ||||
| @@ -1,32 +0,0 @@ | ||||
| function Hint(element) | ||||
| { | ||||
|   Module.call(this); | ||||
|    | ||||
|   this.element = element; | ||||
|    | ||||
|   this.update = function() | ||||
|   { | ||||
|     if(ronin.module){ | ||||
|       this.element.innerHTML = this.message(ronin.module,commander.cmd); | ||||
|       this.element.style.display = "block"; | ||||
|     } | ||||
|     else{ | ||||
|       this.element.style.display = "none"; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.message = function(module,cmd) | ||||
|   { | ||||
|     var s = "<span class='module'>"+module.constructor.name+"</span>"; | ||||
|      | ||||
|     var e = 0; | ||||
|     while(e < 10){ | ||||
|       if(!module.parameters[e]){ break; } | ||||
|       var param_name = module.parameters[e].name; | ||||
|       s += cmd[param_name.toLowerCase()]() ? "<span class='value'>"+cmd[param_name.toLowerCase()]().render()+"</span>" : "<span class='param'>"+param_name+"</span>"; | ||||
|       e += 1; | ||||
|     } | ||||
|      | ||||
|     return s; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										30
									
								
								scripts/modules/history.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								scripts/modules/history.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| function History(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.cmds = []; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     var w = window.open('about:blank','source'); | ||||
|     var html = ""; | ||||
|      | ||||
|     for (i = 0; i < this.cmds.length; i++) { | ||||
|       if(this.cmds[i][0] == this.rune){ continue; } | ||||
|       html += this.cmds[i]+";<br />"; | ||||
|     } | ||||
|     w.document.write("<title>Source</title><style>body { font-family:courier}</style>"+html+""); | ||||
|   } | ||||
|    | ||||
|   this.add = function(content) | ||||
|   { | ||||
|     this.cmds.push(content); | ||||
|   } | ||||
|    | ||||
|   this.widget = function() | ||||
|   { | ||||
|     if(this.cmds.length === 0){ return "";} | ||||
|    | ||||
|     return "^ "+this.cmds.length+" "; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										86
									
								
								scripts/modules/module.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								scripts/modules/module.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| function Module(rune) | ||||
| { | ||||
|   this.rune = rune; | ||||
|   this.element = null; | ||||
|   this.parameters = []; | ||||
|   this.variables  = {}; | ||||
|  | ||||
|   this.docs = "Missing documentation."; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     console.log("Nothing to do."); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|     console.log("Nothing to do."); | ||||
|   } | ||||
|    | ||||
|   this.update_variables = function(cmd) | ||||
|   { | ||||
|     for (var key in this.variables){ | ||||
|       if(!cmd.variable(key)){ continue; } | ||||
|       this.variables[key] = cmd.variable(key).value; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.hint = function(cmd) | ||||
|   { | ||||
|     var s = this.pad(cmd.content.join(" ")); | ||||
|  | ||||
|     s += cmd.content.join(" ").length == 0 ? "<span class='module'>"+this.constructor.name+"</span>" : ""; | ||||
|  | ||||
|     // Params | ||||
|  | ||||
|     var e = 0; | ||||
|     while(e < 10){ | ||||
|       if(!this.parameters[e]){ break; } | ||||
|       var param_name = this.parameters[e].name; | ||||
|       s += cmd[param_name.toLowerCase()]() ? "" : "<span class='param'>"+param_name+"</span>"; | ||||
|       e += 1; | ||||
|     } | ||||
|  | ||||
|     // Variables | ||||
|     if(this.variables){ | ||||
|       for (var key in this.variables){ | ||||
|         if(cmd.variable(key)){continue;} | ||||
|         s += "<span class='variable_key'>"+key+"</span>=<span class='variable_value'>"+this.variables[key]+"</span> "; | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     return s; | ||||
|   } | ||||
|  | ||||
|   this.pad = function(input) | ||||
|   { | ||||
|     var s = ""; | ||||
|     for (i = 0; i < input.length+2; i++){ | ||||
|       s += "_"; | ||||
|     } | ||||
|  | ||||
|     return "<span style='color:#000'>"+s+"</span>"; | ||||
|   } | ||||
|    | ||||
|   this.widget = function() | ||||
|   { | ||||
|     return ""; | ||||
|   } | ||||
|    | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     return "Missing"; | ||||
|   } | ||||
|    | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(position) | ||||
|   { | ||||
|   } | ||||
| } | ||||
| @@ -1,9 +1,8 @@ | ||||
| function Overlay(element) | ||||
| function Overlay(rune) | ||||
| { | ||||
|   Module.call(this); | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Position,Rect]; | ||||
|   this.element = element; | ||||
|    | ||||
|   // Module | ||||
|    | ||||
| @@ -23,7 +22,7 @@ function Overlay(element) | ||||
|   { | ||||
|     this.clear(); | ||||
|      | ||||
|     if(!position){ return; } | ||||
|     if(!position){ position = new Position("0,0"); } | ||||
|      | ||||
|     if(rect){ | ||||
|       this.draw_rect(position,rect); | ||||
| @@ -104,26 +103,11 @@ function Overlay(element) | ||||
|    | ||||
|   this.resize = function(rect) | ||||
|   { | ||||
|     this.element.setAttribute('width',rect.width+"px"); | ||||
|     this.element.setAttribute('height',rect.height+"px"); | ||||
|   } | ||||
|    | ||||
|   this.show_guide = function(position,rect) | ||||
|   { | ||||
|     this.clear(); | ||||
|     this.context().beginPath(); | ||||
|      | ||||
|     this.context().moveTo(0,0); | ||||
|     this.context().lineTo(rect.width,0); | ||||
|     this.context().lineTo(rect.width,rect.height); | ||||
|     this.context().lineTo(0,rect.height); | ||||
|     this.context().lineTo(0,0); | ||||
|      | ||||
|     this.context().lineCap="round"; | ||||
|     this.context().lineWidth = 1; | ||||
|     this.context().strokeStyle = "#ff0000"; | ||||
|     this.context().stroke(); | ||||
|     this.context().closePath(); | ||||
|     this.element.width = rect.width * 2; | ||||
|     this.element.height = rect.height * 2; | ||||
|     this.element.style.width = rect.width+"px"; | ||||
|     this.element.style.height = rect.height+"px"; | ||||
|     this.context().scale(2,2); | ||||
|   } | ||||
|    | ||||
|   this.context = function() | ||||
| @@ -133,6 +117,47 @@ function Overlay(element) | ||||
|    | ||||
|   this.clear = function() | ||||
|   { | ||||
|     this.context().clearRect(0, 0, ronin.canvas.element.width, ronin.canvas.element.height); | ||||
|     this.context().clearRect(0, 0, ronin.surface.size.width, ronin.surface.size.height); | ||||
|   } | ||||
|    | ||||
|   // Cursor | ||||
|    | ||||
|   this.live_draw_from = null; | ||||
|  | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     ronin.overlay.clear(); | ||||
|     ronin.overlay.draw_pointer(position); | ||||
|     this.live_draw_from = position; | ||||
|     commander.show(); | ||||
|     commander.element_input.focus(); | ||||
|     commander.element_input.value = "| "+this.live_draw_from.render(); | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     if(this.live_draw_from === null){ return; } | ||||
|      | ||||
|     ronin.overlay.clear(); | ||||
|      | ||||
|     var rect = new Rect(); | ||||
|     rect.width = position.x - this.live_draw_from.x; | ||||
|     rect.height = position.y - this.live_draw_from.y; | ||||
|    | ||||
|     ronin.overlay.draw_rect(this.live_draw_from,rect); | ||||
|     commander.element_input.value = "| "+this.live_draw_from.render()+" "+rect.render(); | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(position) | ||||
|   { | ||||
|     this.live_draw_from = null; | ||||
|     commander.element_input.focus(); | ||||
|   } | ||||
|    | ||||
|   // Widget | ||||
|    | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     return "Guide"; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										30
									
								
								scripts/modules/render.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								scripts/modules/render.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| function Render(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Any]; | ||||
|   this.collection = {}; | ||||
|  | ||||
|   this.collection["stencil"] = new Filter_Stencil(); | ||||
|   this.collection["rotate"] = new Filter_Rotate(); | ||||
|   this.collection["invert"] = new Filter_Invert(); | ||||
|   this.collection["chromatic"] = new Filter_Chromatic(); | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     var name = cmd.content[0]; | ||||
|  | ||||
|     if(!this.collection[name]){ return; } | ||||
|      | ||||
|     return this.collection[name].render(cmd); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|     var name = cmd.content[0]; | ||||
|     if(!this.collection[name]){ return; } | ||||
|  | ||||
|     return this.collection[name].preview(cmd); | ||||
|   } | ||||
| 	 | ||||
| } | ||||
| @@ -1,9 +1,33 @@ | ||||
| function Stroke(element) | ||||
| function Stroke(rune) | ||||
| { | ||||
|   Module.call(this); | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Any]; | ||||
|    | ||||
|   // Create a stroke | ||||
|    | ||||
|   this.positions = null; | ||||
|    | ||||
|   this.new_stroke = function() | ||||
|   { | ||||
|     this.positions = []; | ||||
|   } | ||||
|    | ||||
|   this.append_stroke = function(p) | ||||
|   { | ||||
|     this.positions.push(p); | ||||
|   } | ||||
|    | ||||
|   this.save_stroke = function(mode) | ||||
|   { | ||||
|     s = "_ module="+mode+" "; | ||||
|     for (i = 0; i < this.positions.length; i++) { | ||||
|       s += this.positions[i].render()+" "; | ||||
|     } | ||||
|     if(this.positions.length > 0){ ronin.history.add(s); } | ||||
|     this.positions = null; | ||||
|   } | ||||
|    | ||||
|   // Module | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
| @@ -12,23 +36,26 @@ function Stroke(element) | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     // TODO | ||||
|      | ||||
|     var origin = new Position(cmd.content[0]); | ||||
|     var destination = new Position(cmd.content[1]); | ||||
|      | ||||
|     var e = {}; | ||||
|     e.clientX = origin.x; | ||||
|     e.clientY = origin.y; | ||||
|      | ||||
|     ronin.brush.is_drawing = true; | ||||
|     ronin.brush.draw(e); | ||||
|      | ||||
|     e.clientX = destination.x; | ||||
|     e.clientY = destination.y; | ||||
|      | ||||
|     ronin.brush.draw(e); | ||||
|     ronin.brush.is_drawing = false; | ||||
|     var prev = null | ||||
|     for (i = 1; i < cmd.content.length; i++) { | ||||
|       var p = new Position(cmd.content[i]); | ||||
|       if(prev){ | ||||
|         this.draw(prev,p); | ||||
|       } | ||||
|       prev = p; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   this.draw = function(pos1,pos2) | ||||
|   { | ||||
|     ronin.surface.context().beginPath(); | ||||
|     ronin.surface.context().moveTo(pos1.x,pos1.y); | ||||
|     ronin.surface.context().lineTo(pos2.x,pos2.y); | ||||
|     ronin.surface.context().lineCap="round"; | ||||
|     ronin.surface.context().lineWidth = 10; | ||||
|     ronin.surface.context().strokeStyle = ronin.brush.color.rgba(); | ||||
|     ronin.surface.context().stroke(); | ||||
|     ronin.surface.context().closePath(); | ||||
|   } | ||||
|    | ||||
| } | ||||
							
								
								
									
										187
									
								
								scripts/modules/surface.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								scripts/modules/surface.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| function Surface(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.element = null; | ||||
|   this.parameters = [Rect,Color,Bang]; | ||||
|   this.variables  = {"layer" : "main"}; | ||||
|  | ||||
|   this.layers = {}; | ||||
|   this.active_layer = null; | ||||
|   this.render_layer = null; | ||||
|  | ||||
|   this.size = null; | ||||
|    | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     if(cmd.rect()){ | ||||
|       this.resize(cmd.rect(),cmd.position()); | ||||
|       ronin.overlay.resize(cmd.rect()); | ||||
|     } | ||||
|      | ||||
|     if(cmd.color()){ | ||||
|       this.context().beginPath(); | ||||
|       this.context().rect(0, 0, this.active_layer.element.width, this.active_layer.element.height); | ||||
|       this.context().fillStyle = cmd.color().hex; | ||||
|       this.context().fill(); | ||||
|     } | ||||
|  | ||||
|     if(cmd.bang() && Object.keys(ronin.surface.layers).length > 1){ | ||||
|       delete this.layers[this.active_layer.name]; | ||||
|       this.select_any_layer(); | ||||
|       ronin.widget.update(); | ||||
|     } | ||||
|  | ||||
|     if(cmd.variable("layer")){ | ||||
|       var name = cmd.variable("layer").value; | ||||
|       if(!this.layers[name]){ | ||||
|         this.add_layer(new Layer(name,this.size)); | ||||
|       } | ||||
|       this.select_layer(this.layers[name]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this.select_layer = function(layer) | ||||
|   { | ||||
|     console.log("Selecting layer:"+layer.name); | ||||
|     this.active_layer = layer; | ||||
|   } | ||||
|  | ||||
|   this.select_any_layer = function() | ||||
|   { | ||||
|     var layer_name = Object.keys(ronin.surface.layers)[0]; | ||||
|     this.select_layer(ronin.surface.layers[layer_name]);     | ||||
|   } | ||||
|  | ||||
|   this.add_layer = function(layer) | ||||
|   { | ||||
|     console.log("Creating layer:"+layer.name);  | ||||
|  | ||||
|     this.layers[layer.name] = layer; | ||||
|     this.active_layer = layer; | ||||
|     this.element.appendChild(layer.element); | ||||
|     this.active_layer.resize(this.size); | ||||
|   } | ||||
|    | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|     if(cmd.rect()){ | ||||
|       ronin.overlay.draw(cmd.position(),cmd.rect()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this.resize = function(rect, position = null) | ||||
|   { | ||||
|     this.size = rect; | ||||
|  | ||||
|     Object.keys(ronin.surface.layers).forEach(function (key) { | ||||
|       ronin.surface.layers[key].resize(rect); | ||||
|     }); | ||||
|      | ||||
|     ronin.surface.element.width = rect.width * 2; | ||||
|     ronin.surface.element.height = rect.height * 2; | ||||
|     ronin.surface.element.style.width = rect.width+"px"; | ||||
|     ronin.surface.element.style.height = rect.height+"px"; | ||||
|     ronin.surface.element.style.marginLeft = -(rect.width/2); | ||||
|     ronin.surface.element.style.marginTop = -(rect.height/2); | ||||
|  | ||||
|     ronin.on_resize(); | ||||
|   } | ||||
|  | ||||
|   this.widget = function() | ||||
|   { | ||||
|     if(!this.active_layer){ return ""; } | ||||
|  | ||||
|     var s = ""; | ||||
|  | ||||
|     Object.keys(ronin.surface.layers).forEach(function (key) { | ||||
|       s = ronin.surface.layers[key].widget()+s; | ||||
|     }); | ||||
|     return "# "+this.size.render()+"<br />"+s; | ||||
|   } | ||||
|    | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     return "Drag"; | ||||
|   } | ||||
|  | ||||
|   // Commands | ||||
|  | ||||
|   this.layer_up = function() | ||||
|   { | ||||
|     var keys = Object.keys(ronin.surface.layers); | ||||
|     var loc = keys.indexOf(this.active_layer.name); | ||||
|  | ||||
|     if(loc >= keys.length-1){ console.log("Reached end"); return false; } | ||||
|  | ||||
|     if(keys[loc+1] != null){this.select_layer(ronin.surface.layers[keys[loc+1]]);} | ||||
|   } | ||||
|  | ||||
|   this.layer_down = function() | ||||
|   { | ||||
|     var keys = Object.keys(ronin.surface.layers); | ||||
|     var loc = keys.indexOf(this.active_layer.name); | ||||
|  | ||||
|     if(keys[loc-1] != null){this.select_layer(ronin.surface.layers[keys[loc-1]]);} | ||||
|   } | ||||
|  | ||||
|   // Layers | ||||
|  | ||||
|   this.context = function() | ||||
|   { | ||||
|     return this.active_layer.context(); | ||||
|   } | ||||
|  | ||||
|   this.merge = function() | ||||
|   { | ||||
|     // this.render_layer = this.layers["render"]; | ||||
|      | ||||
|     // var a = []; | ||||
|     // Object.keys(ronin.surface.layers).forEach(function (key) { | ||||
|     //   if(key != "render"){ | ||||
|     //     a.push(ronin.surface.layers[key]); | ||||
|     //   } | ||||
|     // }); | ||||
|     // for (i = a.length; i > 0 ; i--) { | ||||
|     //   ronin.surface.render_layer.context().drawImage(a[i-1].context().canvas,0,0,this.size.width,this.size.height); | ||||
|     // } | ||||
|     return this.context(); | ||||
|   } | ||||
|    | ||||
|   // Cursor | ||||
|    | ||||
|   this.drag_from = null; | ||||
|   this.drag_offset_x = 0; | ||||
|   this.drag_offset_y = 0; | ||||
|  | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     this.drag_from = ronin.position_in_window(position); | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     if(this.drag_from === null){ return; } | ||||
|      | ||||
|     position = ronin.position_in_window(position); | ||||
|      | ||||
|     var offset_x = this.drag_from.x - position.x; | ||||
|     var offset_y = this.drag_from.y - position.y; | ||||
|     this.drag_offset_x -= offset_x; | ||||
|     this.drag_offset_y -= offset_y; | ||||
|      | ||||
|     ronin.surface.element.style.marginLeft = -(this.size.width/2) + this.drag_offset_x; | ||||
|     ronin.surface.element.style.marginTop = -(this.size.height/2) + this.drag_offset_y; | ||||
|  | ||||
|     ronin.element.style.backgroundPosition = ((this.drag_offset_x/8))-(window.innerWidth % 20)+"px "+((this.drag_offset_y/8)-(window.innerWidth % 20))+"px"; | ||||
|     ronin.widget.element.style.marginLeft = this.drag_offset_x; | ||||
|     ronin.widget.element.style.marginTop = this.drag_offset_y; | ||||
|  | ||||
|     this.drag_from = new Position(position.x,position.y); | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(event) | ||||
|   { | ||||
|     this.drag_from = null; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										82
									
								
								scripts/modules/surface.layer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								scripts/modules/surface.layer.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| function Layer(name,host = "user") | ||||
| { | ||||
|   this.name = name; | ||||
|   this.host = host; | ||||
|   this.element = document.createElement("canvas"); | ||||
|   this.element.setAttribute("id","_"+name); | ||||
|   this.element.setAttribute("class","layer"); | ||||
|  | ||||
|   this.resize = function(rect) | ||||
|   { | ||||
|     console.log("Resize "+this.name+" to "+rect.render()); | ||||
|  | ||||
|     var pixels_rect   = new Rect(this.element.width+"x"+this.element.height); | ||||
|      | ||||
|     this.element.width = rect.width * 2; | ||||
|     this.element.height = rect.height * 2; | ||||
|     this.element.style.width = rect.width+"px"; | ||||
|     this.element.style.height = rect.height+"px"; | ||||
|  | ||||
|     this.context().scale(2,2); | ||||
|   } | ||||
|  | ||||
|   this.clear = function() | ||||
|   { | ||||
|     this.context().clearRect(0, 0, this.element.width, this.element.height); | ||||
|   } | ||||
|  | ||||
|   this.context = function() | ||||
|   { | ||||
|     return this.element.getContext('2d'); | ||||
|   } | ||||
|  | ||||
|   this.image = function() | ||||
|   { | ||||
|     return this.element.toDataURL('image/png'); | ||||
|   } | ||||
|  | ||||
|   // | ||||
|  | ||||
|   this.widget_cursor = function() | ||||
|   { | ||||
|     return "Move"; | ||||
|   } | ||||
|  | ||||
|   this.widget = function() | ||||
|   { | ||||
|     return (ronin.surface.active_layer.name == this.name) ? "<span class='highlight'>- ("+this.name+")</span><br />" : "- "+this.name+"<br />"; | ||||
|   } | ||||
|  | ||||
|   this.move_from = null; | ||||
|  | ||||
|   this.mouse_down = function(position) | ||||
|   { | ||||
|     this.move_from = ronin.position_in_window(position); | ||||
|     ronin.stroke.new_stroke(); | ||||
|   } | ||||
|    | ||||
|   this.mouse_move = function(position) | ||||
|   { | ||||
|     if(this.move_from === null){ return; } | ||||
|      | ||||
|     ronin.stroke.append_stroke(position); // Save to stroke | ||||
|  | ||||
|     position = ronin.position_in_window(position); | ||||
|      | ||||
|     var offset_x = this.move_from.x - position.x; | ||||
|     var offset_y = this.move_from.y - position.y; | ||||
|  | ||||
|     var imageData = this.context().getImageData(0, 0, ronin.surface.size.width * 2, ronin.surface.size.height * 2); | ||||
|     this.clear(); | ||||
|     this.context().putImageData(imageData, -offset_x * 2, -offset_y * 2); | ||||
|  | ||||
|     this.move_from = new Position(position.x,position.y); | ||||
|      | ||||
|   } | ||||
|    | ||||
|   this.mouse_up = function(event) | ||||
|   { | ||||
|     this.move_from = null; | ||||
|     ronin.stroke.save_stroke("move"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										39
									
								
								scripts/modules/typographe.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								scripts/modules/typographe.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| function Typographe(rune) | ||||
| { | ||||
|   Module.call(this,rune); | ||||
|  | ||||
|   this.parameters = [Position,Color,Value]; | ||||
|   this.variables  = {"text" : null}; | ||||
|  | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     var target = ronin.surface.active_layer; | ||||
|     target.clear(); | ||||
|     if(cmd.variable("text")){ | ||||
|       this.add_text(target.context(),cmd); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this.passive = function(cmd) | ||||
|   { | ||||
|     var target = ronin.overlay; | ||||
|     target.clear(); | ||||
|     if(cmd.variable("text")){ | ||||
|       this.add_text(target.context(),cmd); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this.add_text = function(context,cmd) | ||||
|   { | ||||
|     var ctx = context; | ||||
|  | ||||
|     var text = cmd.variable("text").value; | ||||
|     var position = cmd.position() ? cmd.position() : new Position(20,40); | ||||
|     var color = cmd.color() ? cmd.color() : new Color("#000000"); | ||||
|     var size = cmd.value() ? cmd.value().int : 20; | ||||
|  | ||||
|     ctx.font = size+"px Georgia"; | ||||
|     ctx.fillStyle = color.hex;  | ||||
|     ctx.fillText(text,position.x,position.y); | ||||
|   } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| function Vector() | ||||
| function Vector(rune) | ||||
| { | ||||
|   Module.call(this); | ||||
|   Module.call(this,rune); | ||||
|    | ||||
|   this.parameters = [Any,Position]; | ||||
|    | ||||
| @@ -18,10 +18,10 @@ function Vector() | ||||
|   this.active = function(cmd) | ||||
|   { | ||||
|     ronin.overlay.clear(); | ||||
|     ronin.canvas.context().lineCap="round"; | ||||
|     ronin.canvas.context().lineWidth = ronin.brush.size; | ||||
|     ronin.canvas.context().strokeStyle = ronin.brush.color.rgba(); | ||||
|     ronin.canvas.context().stroke(new Path2D(cmd.content.join(" "))); | ||||
|     ronin.surface.context().lineCap="round"; | ||||
|     ronin.surface.context().lineWidth = ronin.brush.size; | ||||
|     ronin.surface.context().strokeStyle = ronin.brush.color.rgba(); | ||||
|     ronin.surface.context().stroke(new Path2D(cmd.content.join(" "))); | ||||
|   } | ||||
|    | ||||
|   // + M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 ; Draw a circle | ||||
|   | ||||
| @@ -1,11 +0,0 @@ | ||||
| function Ronin() | ||||
| { | ||||
|   this.canvas   = new Canvas(); | ||||
|   this.overlay  = new Overlay(); | ||||
|   this.brush    = new Brush(); | ||||
|   this.file     = new File(); | ||||
|   this.hint     = new Hint(); | ||||
|   this.filter   = new Filter(); | ||||
|   this.stroke   = new Stroke(); | ||||
|   this.vector   = new Vector(); | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| function Unit() | ||||
| { | ||||
|   this.render = function() | ||||
|   { | ||||
|     return "HEY!"; | ||||
|   } | ||||
| } | ||||
| @@ -1,7 +1,9 @@ | ||||
| function Angle(angle_str) | ||||
| function Angle(angle_str = "0'") | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "45'"; | ||||
|    | ||||
|   this.degrees = parseFloat(angle_str.replace('\'','')); | ||||
|    | ||||
|   this.render = function() | ||||
|   | ||||
| @@ -2,6 +2,7 @@ function Any(str) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = ""; | ||||
|   this.string = str; | ||||
|    | ||||
|   this.render = function() | ||||
|   | ||||
| @@ -2,6 +2,8 @@ function Bang() | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = ""; | ||||
|    | ||||
|   this.render = function() | ||||
|   { | ||||
|     return "BANG"; | ||||
|   | ||||
| @@ -2,6 +2,7 @@ function Color(hex = '#000000') | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "#ff0000"; | ||||
|   this.hex = hex; | ||||
|  | ||||
|   this.rgb = function() | ||||
| @@ -23,4 +24,9 @@ function Color(hex = '#000000') | ||||
|   { | ||||
|     return this.hex; | ||||
|   } | ||||
|    | ||||
|   this.rgb_to_hex = function(rgb) | ||||
|   { | ||||
|     return "#"+("0" + parseInt(rgb[0],10).toString(16)).slice(-2)+("0" + parseInt(rgb[1],10).toString(16)).slice(-2)+("0" + parseInt(rgb[2],10).toString(16)).slice(-2); | ||||
|   } | ||||
| } | ||||
| @@ -2,6 +2,7 @@ function Filepath(path_str) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "assets/demo.png"; | ||||
|   this.path = path_str; | ||||
|    | ||||
|   this.render = function() | ||||
|   | ||||
| @@ -2,10 +2,16 @@ function Position(position_str = "0,0",y = null) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "100,150"; | ||||
|   this.position_str = position_str; | ||||
|    | ||||
|   this.x = y ? position_str : parseFloat(this.position_str.split(",")[0]); | ||||
|   this.y = y ? y : parseFloat(this.position_str.split(",")[1]); | ||||
|   this.x = y != null ? position_str : parseFloat(this.position_str.split(",")[0]); | ||||
|   this.y = y != null ? y : parseFloat(this.position_str.split(",")[1]); | ||||
|    | ||||
|   this.add = function(position) | ||||
|   { | ||||
|     return new Position(this.x + position.x, this.y + position.y); | ||||
|   } | ||||
|    | ||||
|   this.is_equal = function(target) | ||||
|   { | ||||
|   | ||||
							
								
								
									
										15
									
								
								scripts/units/range.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								scripts/units/range.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| function Range(range_str) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "10..50"; | ||||
|   this.range_str = range_str; | ||||
|    | ||||
|   this.from = parseFloat(this.range_str.split("..")[0]); | ||||
|   this.to = parseFloat(this.range_str.split("..")[1]); | ||||
|    | ||||
|   this.render = function() | ||||
|   { | ||||
|     return this.from+".."+this.to; | ||||
|   } | ||||
| } | ||||
| @@ -2,10 +2,11 @@ function Rect(rect_str) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "200x300"; | ||||
|   this.rect_str = rect_str; | ||||
|    | ||||
|   this.width = parseFloat(this.rect_str.split("x")[0]); | ||||
|   this.height = parseFloat(this.rect_str.split("x")[1]); | ||||
|   this.width = rect_str ? parseFloat(this.rect_str.split("x")[0]) : 0; | ||||
|   this.height = rect_str ? parseFloat(this.rect_str.split("x")[1]) : 0; | ||||
|    | ||||
|   this.render = function() | ||||
|   { | ||||
|   | ||||
							
								
								
									
										9
									
								
								scripts/units/unit.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								scripts/units/unit.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| function Unit() | ||||
| { | ||||
|   this.example = "unknown"; | ||||
|    | ||||
|   this.render = function() | ||||
|   { | ||||
|     return "[MISSING]"; | ||||
|   } | ||||
| } | ||||
| @@ -2,6 +2,7 @@ function Value(value_str) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.example = "20"; | ||||
|   this.value = value_str; | ||||
|   this.float = parseFloat(this.value); | ||||
|   this.int = parseInt(this.value); | ||||
|   | ||||
							
								
								
									
										16
									
								
								scripts/units/variable.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								scripts/units/variable.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| function Variable(key,value) | ||||
| { | ||||
|   Unit.call(this); | ||||
|    | ||||
|   this.candidates = []; | ||||
|   this.key = key; | ||||
|    | ||||
|   if(value == "true"){ this.value = true; } | ||||
|   else if(value == "false"){ this.value = false; } | ||||
|   else{ this.value = value; } | ||||
|    | ||||
|   this.render = function() | ||||
|   { | ||||
|     return this.key+"="+this.value; | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user