diff --git a/.gitignore b/.gitignore index 4c04fcb..a885486 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +.* +*~ +\#* node_modules test.css .idea diff --git a/coffee/compilation.coffee b/coffee/compilation.coffee index fb86cff..b1831c3 100644 --- a/coffee/compilation.coffee +++ b/coffee/compilation.coffee @@ -1,8 +1,24 @@ -NullSystem = new LSystem({},{},{},"",1,"no system") -DefaultSystem = new LSystem({ - size: {value:12.27} - angle: {value:4187.5} -},{},{ size: {value:9} } ,"L : SS\nS : F->[F-Y[S(L]]\nY : [-|F-F+)Y]\n" ,12 ,"click-and-drag-me!" ) +NullSystem = new LSystem({},{},{},0,"","",1,"no system") +DefaultSystem = new LSystem( + { size: {value: 20}, angle: {value: 9840} }, + { x: 0, y: 50, rot: 0}, + null, + "L : SS\nS : F-[F-Y[S>(L]]\nY : [-|F-F+)Y]" + 12, + 0.218, + [ "black", "white", "cyan", "#e8cc00", "#007272", "#ff4c00" ], + false, + "return {\n + angle: t/100,\n + angleG: t/100,\n + size: null,\n + sizeG: null,\n + offsetX: null,\n + offsetY: null,\n + rotation: null\n + }", + "click-and-drag-me!" +) # ========================================= class CompiledSystem @@ -92,4 +108,3 @@ class SystemManager ) getInstructions: -> @compiledElements - diff --git a/coffee/controls.coffee b/coffee/controls.coffee index a828631..b912160 100644 --- a/coffee/controls.coffee +++ b/coffee/controls.coffee @@ -87,6 +87,65 @@ class Joystick # =============================== +class Animation + active: false + now: 0 + f: (t) -> {} + + constructor: (f) -> + @setF(f) + + setF: (f, el) -> + if el + $(el).removeClass('error') + $(el).attr('title', '') + try + f = Function ['t'], f + r = f.call {}, 0 + unless r instanceof Object + throw 'Return value is not Object' + @f = f + catch err + if el + $(el).addClass 'error' + $(el).attr 'title', err.toString() + + enable: -> + @active = true + @onActivate() + disable: -> + @active = false + @onRelease() + toggle: (active = not @active) -> + if active + @enable() + else + @disable() + + onActivate: -> # noop unless overriden + onRelease: -> # noop unless overriden + + state: () -> + d = + try + @f(@now) + catch e + {} + if d instanceof Object + d + else + {} + + clear: -> #noop for now + draw: -> + if @active + @now++ + + center: -> + @now = 0 + +# =============================== + # ui binding for a single system variable class Control constructor: (@controlkey) -> diff --git a/coffee/lsystem.coffee b/coffee/lsystem.coffee index 287f69e..3bf9fc6 100644 --- a/coffee/lsystem.coffee +++ b/coffee/lsystem.coffee @@ -36,13 +36,44 @@ class Defaults @_sensitivites: -> size: {value: 7.7, growth:7.53} angle: {value: 7.6, growth:4} + @lineWidth: 0.218 + @colors: [ "black", "white", "cyan", "#e8cc00", "#007272", "#ff4c00" ] + @play: 0 + @animation: " + return {\n + angle: t/100,\n + angleG: t/100,\n + size: null,\n + sizeG: null,\n + offsetX: null,\n + offsetY: null,\n + rotation: null\n + }" # ========================================= class LSystem - constructor: (params, offsets, sensitivities, @rules, @iterations, @name) -> + constructor: (params, offsets, sensitivities, @rules, @iterations, lineWidth, colors, play, animation, @name) -> @params = Util.map(Defaults.params(params), (c) -> Param.fromJson(c)) @offsets = Defaults.offsets(offsets) @sensitivities = Util.map(Defaults.sensitivities(sensitivities), (s) -> Sensitivity.fromJson(s)) + @play = + if (typeof play == 'number' && Number.isFinite play) || (typeof play == 'boolean') + if play then 1 else 0 + else + Defaults.play + @animation = + if typeof animation == 'string' and 0 < animation.length + animation + else + Defaults.animation + @lineWidth = + if typeof lineWidth == 'number' && Number.isFinite lineWidth + then lineWidth + else Defaults.lineWidth + @colors = + if typeof colors == 'object' + then colors + else Defaults.colors # this is not the most efficient of methods... clone: -> return LSystem.fromUrl(@toUrl()) @@ -51,10 +82,14 @@ class LSystem base = "#?i=#{@iterations}&r=#{encodeURIComponent(@rules)}" mkQueryString = (params) -> _.reduce(params, ((acc,v) -> "#{acc}{v.toUrlComponent()}"), "") params = mkQueryString(@params) - sensitivities = mkQueryString(@sensitivities) offsets = "&offsets=#{@offsets.x},#{@offsets.y},#{@offsets.rot}" + sensitivities = mkQueryString(@sensitivities) + lineWidth = "&l="+@lineWidth + colors = "&c="+@colors.join(',') + play = "&play="+@play + animation = "&anim="+encodeURIComponent(@animation) name = "&name=#{encodeURIComponent(@name)}" - return base+params+sensitivities+offsets+name + return base+params+offsets+sensitivities+lineWidth+colors+play+animation+name merge: (system) -> _.extend(@, system) if system @@ -81,7 +116,21 @@ class LSystem y: parseFloat(o[1]) rot: parseFloat(o[2]) - return new LSystem(params, offsets, sensitivities, decodeURIComponent(config.r), config.i, decodeURIComponent(config.name) or "unnamed") + anim = + if 'anim' of config + decodeURIComponent(config.anim) + else + null + + colors = undefined + if (config.c) + colors = config.c.split(',') + + return new LSystem(params, offsets, sensitivities, + decodeURIComponent(config.r), parseInt(config.i), + parseFloat(config.l), colors, + parseInt(config.play), anim, + decodeURIComponent(config.name) or "unnamed") isIsomorphicTo: (system) -> if (!system) then false else @rules == system.rules and @iterations == system.iterations diff --git a/coffee/manager.coffee b/coffee/manager.coffee index 7d2dd99..4ba1a09 100644 --- a/coffee/manager.coffee +++ b/coffee/manager.coffee @@ -13,22 +13,51 @@ class InputHandler system.params.angle.value = Util.round(system.params.angle.value + @joystick.dx(system.sensitivities.angle.value), 4) system.params.angle.growth = Util.round(system.params.angle.growth + @joystick.dy(system.sensitivities.angle.growth),9) +class AnimationHandler + snapshot: null # lsystem params as they were was when joystick activated + constructor: (@animation) -> + + sensitivity: (value) -> + if (value) then Math.pow(10,value-10) else 1 + + update: (system) => + return if not @animation.active + d = @animation.state() + if (typeof d.angle == 'number' && Number.isFinite d.angle) + system.params.angle.value = Util.round(system.params.angle.value + d.angle * @sensitivity(system.sensitivities.angle.value), 4) + if (typeof d.angleG == 'number' && Number.isFinite d.angleG) + system.params.angle.growth = Util.round(system.params.angle.growth + d.angleG * @sensitivity(system.sensitivities.angle.growth), 9) + if (typeof d.size == 'number' && Number.isFinite d.size) + system.params.size.value = Util.round(@snapshot.params.size.value + d.size * @sensitivity(system.sensitivities.size.value), 2) + if (typeof d.sizeG == 'number' && Number.isFinite d.sizeG) + system.params.size.growth = Util.round(@snapshot.params.size.growth + d.sizeG * @sensitivity(system.sensitivities.size.growth), 6) + if (typeof d.offsetX == 'number' && Number.isFinite d.offsetX) + system.offsets.x = @snapshot.offsets.x + d.offsetX + if (typeof d.offsetY == 'number' && Number.isFinite d.offsetY) + system.offsets.y = @snapshot.offsets.y + d.offsetY + if (typeof d.rotation == 'number' && Number.isFinite d.rotation) + system.offsets.rot = @snapshot.offsets.rot + d.rotation class AppManager joystick:null + animation:null keystate: null inputHandler: null renderer:null systemManager: null - constructor: (@container, @controls) -> - @joystick = new Joystick(container) + constructor: (@container, @controls, @animation) -> + @joystick = new Joystick(@container) @keystate = new KeyState @inputHandler = new InputHandler(@keystate, @joystick) + @animationHandler = new AnimationHandler(@animation) @joystick.onRelease = => @syncLocationQuiet() @joystick.onActivate = => @inputHandler.snapshot = @systemManager.activeSystem.clone() + @animation.onRelease = => @syncLocationQuiet() + @animation.onActivate = => @animationHandler.snapshot = @systemManager.activeSystem.clone() + @renderer = new Renderer(@container) @systemManager = new SystemManager @@ -56,6 +85,8 @@ class AppManager @recalculationPromise = @systemManager.activate(system).progress(@onRecalculateProgress) @recalculationPromise.done( => @joystick.enable() + @animation.setF(system.animation, @controls.animation) + @animation.toggle(system.play) @renderer.prepare(system) @syncAll(); @draw() @@ -65,12 +96,20 @@ class AppManager @recalculationPromise lsystemFromControls: -> + play = $(@controls.play).hasClass('play') + animation = $(@controls.animation).val() + Defaults.play = play + Defaults.animation = animation return new LSystem( @paramControls.toJson(), @offsetControls.toJson(), @sensitivityControls.toJson(), $(@controls.rules).val(), parseInt($(@controls.iterations).val()), + parseFloat($(@controls.lineWidth).val()), + Util.mapArray(@controls.colors, (el) -> el.value), + play, + animation, $(@controls.name).val() ) @@ -94,7 +133,7 @@ class AppManager r.context.state.y = (y-b.y1+15) @draw(r) - filename = "lsys_"+system.name.replace(/[\ \/]/g,"_") + filename = "lsys_"+system.name.replace(/[\ \/]/g,"_")+".png" rootCanvas = container.children[0] rootContext = rootCanvas.getContext('2d') [].slice.call(container.children, 1).forEach( (c) -> @@ -110,12 +149,17 @@ class AppManager .always(@run) run: => - requestAnimationFrame(@run, @container) - @inputHandler.update(@systemManager.activeSystem) if @joystick.active and not @renderer.isDrawing - @draw() @joystick.draw() + @inputHandler.update(@systemManager.activeSystem) @syncControls() + @draw() + if @animation.active and not @renderer.isDrawing + @animation.draw() + @animationHandler.update(@systemManager.activeSystem) + @syncControls() + @draw() + requestAnimationFrame(@run, @container) draw: (renderer = @renderer) => elems = @systemManager.getInstructions() @@ -134,10 +178,28 @@ class AppManager $(@controls.name).val(system.name) @syncControls(system) @syncRulesAndIterations(system) + @syncLineStyle(system) syncRulesAndIterations: (system = @systemManager.activeSystem) -> $(@controls.iterations).val(system.iterations) $(@controls.rules).val(system.rules) + $(@controls.animation).val(system.animation) + if (system.play) + $(@controls.play).addClass('play') + else + $(@controls.play).removeClass('play') + + syncFloat: (input, value) -> + if (parseFloat(input.val()) != value and not isNaN(parseFloat(value))) then input.val(value) + + syncColor: (input, value) -> + $(input).val(value) + input.style.backgroundColor = value + + syncLineStyle: (system = @systemManager.activeSystem) -> + @syncFloat($(@controls.lineWidth), system.lineWidth) + @syncColor(@controls.colors[i], col) for col, i in system.colors + @container.style.backgroundColor = @controls.colors[0].value syncControls: (system = @systemManager.activeSystem) -> @paramControls.sync(system.params) diff --git a/coffee/rendering.coffee b/coffee/rendering.coffee index d035815..78c8e38 100644 --- a/coffee/rendering.coffee +++ b/coffee/rendering.coffee @@ -38,7 +38,8 @@ class Bounding #================================================================ getG = (c) -> c.getContext('2d') -getColors = (system) -> ["#ffffff","#0044DD","#00DD44","#DD4400"] +getColors = (system) -> system.colors.slice(1) +getLineWidth = (system) -> system.lineWidth class Renderer context:null @@ -46,7 +47,7 @@ class Renderer stack:[] isDrawing:false constructor: (@container) -> - @context = new RenderingContext(container) + @context = new RenderingContext(@container) prepare: (system) => colors = getColors(system) @@ -78,7 +79,7 @@ class Renderer this.reset(system) @context.gs.forEach (g,i) => - g.lineWidth = 0.218 + g.lineWidth = getLineWidth(system) g.beginPath() g.moveTo(@context.state.x, @context.state.y) @@ -147,5 +148,11 @@ class Renderer "1": (state, params, context, a) -> state.color = a; if (context.g != context.gs[1]) then ( context.g = context.gs[1]; context.g.moveTo(state.x,state.y)) "2": (state, params, context, a) -> state.color = a; if (context.g != context.gs[2]) then ( context.g = context.gs[2]; context.g.moveTo(state.x,state.y)) "3": (state, params, context, a) -> state.color = a; if (context.g != context.gs[3]) then ( context.g = context.gs[3]; context.g.moveTo(state.x,state.y)) + "4": (state, params, context, a) -> state.color = a; if (context.g != context.gs[4]) then ( context.g = context.gs[4]; context.g.moveTo(state.x,state.y)) + "5": (state, params, context, a) -> state.color = a; if (context.g != context.gs[5]) then ( context.g = context.gs[5]; context.g.moveTo(state.x,state.y)) + "6": (state, params, context, a) -> state.color = a; if (context.g != context.gs[6]) then ( context.g = context.gs[6]; context.g.moveTo(state.x,state.y)) + "7": (state, params, context, a) -> state.color = a; if (context.g != context.gs[7]) then ( context.g = context.gs[7]; context.g.moveTo(state.x,state.y)) + "8": (state, params, context, a) -> state.color = a; if (context.g != context.gs[8]) then ( context.g = context.gs[8]; context.g.moveTo(state.x,state.y)) + "9": (state, params, context, a) -> state.color = a; if (context.g != context.gs[9]) then ( context.g = context.gs[9]; context.g.moveTo(state.x,state.y)) } )() diff --git a/coffee/util.coffee b/coffee/util.coffee index 166ef67..08de09c 100644 --- a/coffee/util.coffee +++ b/coffee/util.coffee @@ -1,8 +1,10 @@ class Util @log:(x) -> console.log(x) - @control:(name) -> document.getElementById(name) + @control: (name) -> + document.getElementById(name) || document.getElementsByClassName(name) @value: (name) => parseFloat(Util.stringvalue(name)) @stringvalue: (name) -> Util.control(name).value + @arrayvalue: (name) -> Util.mapArray(Util.control(name), (el) -> el.value) @clone:(x) -> JSON.parse(JSON.stringify(x)) @toObj:(kvPairs) -> obj = {} @@ -10,9 +12,14 @@ class Util return obj @map: (obj, fn) -> result = {} - for key of obj then do -> + for own key of obj then do -> result[key] = fn(obj[key], key) return result + @mapArray: (obj, fn) -> + result = [] + for own key of obj then do -> + result.push(fn(obj[key], key)) + return result @merge: (a,b,c) -> $.extend(true, a,b,c) @round: (n,d) -> pow = Math.pow(10,d) @@ -24,8 +31,7 @@ class Util a = document.createElement("a") a.href = data a.download=filename - evt = document.createEvent("MouseEvents") - evt.initMouseEvent("click", true, true,window,0,0,0,0,0,true,false,false,false,0,null) + evt = new MouseEvent('click', { view: window }) a.dispatchEvent(evt) # thanks Brian Nickel http://stackoverflow.com/questions/11163344/update-non-retina-canvas-app-to-retina-display diff --git a/css/forkme.css b/css/forkme.css deleted file mode 100644 index b544963..0000000 --- a/css/forkme.css +++ /dev/null @@ -1,133 +0,0 @@ -/* Left will inherit from right (so we don't need to duplicate code */ -.github-fork-ribbon { - /* The right and left lasses determine the side we attach our banner to */ - position: absolute; - - /* Add a bit of padding to give some substance outside the "stitching" */ - padding: 2px 0; - - /* Set the base colour */ - background-color: #a00; - - /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */ - background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.00)), to(rgba(0, 0, 0, 0.15))); - background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); - background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); - background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); - background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); - background-image: linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000'); - - /* Add a drop shadow */ - -webkit-box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); - box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); - - z-index: 9999; -} - -.github-fork-ribbon a, -.github-fork-ribbon a:hover { - /* Set the font */ - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: 700; - color: white; - - /* Set the text properties */ - text-decoration: none; - text-shadow: 0 -1px rgba(0,0,0,0.5); - text-align: center; - - /* Set the geometry. If you fiddle with these you'll also need to tweak the top and right values in #github-fork-ribbon. */ - width: 200px; - line-height: 20px; - - /* Set the layout properties */ - display: inline-block; - padding: 2px 0; - - /* Add "stitching" effect */ - border-width: 1px 0; - border-style: dotted; - border-color: rgba(255,255,255,0.7); -} - -.github-fork-ribbon-wrapper { - width: 150px; - height: 150px; - position: absolute; - overflow: hidden; - top: 0; - z-index: 9999; -} - -.github-fork-ribbon-wrapper.fixed { - position: fixed; -} - -.github-fork-ribbon-wrapper.fm-left { - left: 0; -} - -.github-fork-ribbon-wrapper.right { - right: 0; -} - -.github-fork-ribbon-wrapper.left-bottom { - position: fixed; - top: inherit; - bottom: 0; - left: 0; -} - -.github-fork-ribbon-wrapper.right-bottom { - position: fixed; - top: inherit; - bottom: 0; - right: 0; -} - -.github-fork-ribbon-wrapper.right .github-fork-ribbon { - top: 42px; - right: -43px; - - /* Rotate the banner 45 degrees */ - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); -} - -.github-fork-ribbon-wrapper.fm-left .github-fork-ribbon { - top: 42px; - left: -43px; - - /* Rotate the banner -45 degrees */ - -webkit-transform: rotate(-45deg); - -moz-transform: rotate(-45deg); - -o-transform: rotate(-45deg); - transform: rotate(-45deg); -} - - -.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { - top: 80px; - left: -43px; - - /* Rotate the banner -45 degrees */ - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); -} - -.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { - top: 80px; - right: -43px; - - /* Rotate the banner -45 degrees */ - -webkit-transform: rotate(-45deg); - -moz-transform: rotate(-45deg); - -o-transform: rotate(-45deg); - transform: rotate(-45deg); -} diff --git a/sass/test.scss b/css/ui.scss similarity index 75% rename from sass/test.scss rename to css/ui.scss index 346baec..74b2eaa 100644 --- a/sass/test.scss +++ b/css/ui.scss @@ -1,15 +1,5 @@ -$menu-color: #333; -$top:0; -$left:228px; -$bottom:240px; - -@mixin scrollbar{ -&::-webkit-scrollbar{width:4px;height:4px;} -&::-webkit-scrollbar-button:start:decrement, &::-webkit-scrollbar-button:end:increment{ display:block;height:2px;background-color: #232323; } -&::-webkit-scrollbar-track-piece{ background-color: #282828;-webkit-border-radius:0;-webkit-border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px; } -&::-webkit-scrollbar-thumb:vertical{ height:5px;background-color: #6d6d6d;-webkit-border-radius:4px; } -&::-webkit-scrollbar-thumb:horizontal{ width:5px;background-color:#999;-webkit-border-radius:4px; } -} +$opacity: 0.7; +$sideWidth: 230px; div { -webkit-touch-callout: none; @@ -19,15 +9,22 @@ div { -ms-user-select: none; user-select: none; } - +/* #helpTrigger{ background-color: rgb(163, 7, 7); color: rgb(236, 236, 236); - border-color: rgb(202, 202, 202); text-shadow: 1px 1px black; } - -.introjs-tooltip{ max-width: 350px; } +#helpTrigger:hover { + border-color: rgb(202, 202, 202); +} +*/ +.introjs-tooltip{ + max-height: 150px; + max-width: 350px; + overflow-x: hidden; + overflow-y: auto; +} .introjs-tooltip, .introjs-helperLayer{ color: #e8e8e8; background-color: rgb(70, 71, 77); @@ -40,7 +37,7 @@ div { color: #e8e8e8; background-color: rgba(94, 97, 111, 0.51) } -.introjs-overlay.hidden { +.hidden { display: none; } .introjs-overlay{ @@ -92,31 +89,31 @@ li{ } .header{ - height:50px; - background-color: #1b1b1b; + height:40px; + background-color: rgba(27,27,27,$opacity); border-bottom:1px solid #545454; background-image:-webkit-linear-gradient(top, #222222, #111111); box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); .actions{ padding-top:13px; - padding-right:11px; - a{ padding:2px 1px 1px 1px; } + padding-right:0px; + } + img{ + float:left; + width:40px; + height:40px; + padding-top:4px; } a.site{ font-family:monospace; - padding-left:10px; + padding-left:0px; padding-top:4px; color: #dbdbdb; font-size:12pt; font-weight:bold; text-decoration: none; display:block; - img{ - width:40px; - height:40px; - float:left; - } span{ margin-left:10px; line-height:42px; @@ -124,37 +121,52 @@ li{ } } -.container-left{ +.show-side.actions{ + padding-top: 13px; +} +.show-side.actions a { + border: 0; + color: white; + text-shadow: 1px 1px black; +} + +.container-side{ + position: absolute; + top: 0; + right: 0; bottom: 0; + width: $sideWidth; cursor: default; - background-color:$menu-color; - left: 0; + background-color: rgba(0,0,0,$opacity); + text-shadow: 1px 1px black; padding: 0 0 0 0px; - position: absolute; - border-right:1px solid #555; - top: $top; - width: $left; + border-left:1px solid #555; + scrollbar-width: thin; + overflow-x: hidden; + overflow-y: auto; + /* + &::-webkit-scrollbar{width:4px;height:4px;} + &::-webkit-scrollbar-button:start:decrement, &::-webkit-scrollbar-button:end:increment{ display:block;height:2px;background-color: #232323; } + &::-webkit-scrollbar-track-piece{ background-color: #282828;-webkit-border-radius:0;-webkit-border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px; } + &::-webkit-scrollbar-thumb:vertical{ height:5px;background-color: #6d6d6d;-webkit-border-radius:4px; } + &::-webkit-scrollbar-thumb:horizontal{ width:5px;background-color:#999;-webkit-border-radius:4px; } + */ } -.container-right{ - bottom: $bottom; - left: $left+1; +.container-main{ + bottom: 0; + left: 0; margin: 0; padding: 0; position: absolute; right: 0; - top: $top; - background-color: #1d1f20; + top: 0; + background-color: black; } -.container-bottom{ - position:absolute; +.container-ticker{ padding:0; - bottom:0; - left:$left+1; - right:0; - height:$bottom - 1; border-top:1px solid #666; - background-color:#222; + background-color: rgba(34,34,34,$opacity); .fade{ position:absolute; right:0; bottom:0; left:0; @@ -162,23 +174,9 @@ li{ background: linear-gradient(to bottom, rgba(34, 34, 34, 0) 0%, rgb(34,34,34) 70%) } } -.top{ - position:absolute; - top:0; - right:0; - left:0; - height:$top - 1; - background-color: #111115; - border-bottom:1px solid #3f3f3f; -} .controls{ - @include scrollbar; font-size:9pt; - position:absolute; - top:51px; - bottom:0; - right:1px; overflow:hidden; overflow-y:auto; @@ -187,14 +185,24 @@ li{ color:#bbb; border-radius:2px; border:1px solid #1d1d1d; - background-color: #42474a; + background-color: rgba(66,71,74,$opacity); + text-shadow: 1px 1px black; font-size:9pt; padding:3px 5px; } input[type=text]{ text-align: right; } - + input[type=text].color{ + text-shadow: 1px 1px black; + } + textarea.error{ + border-color: rgb(219, 43, 43); + } + pre{ + padding: 0; + margin: 0; + } &.validation-enabled{ input:invalid{ @@ -207,7 +215,8 @@ li{ li{ display:inline-block; &.section{ - background-color: #27292c; + position: relative; + background-color: rgba(39,41,44,$opacity); width:100%; padding:4px 0px; margin-top:6px; @@ -215,7 +224,7 @@ li{ border-bottom:1px solid #464646; border-top:1px solid #191919; text-align: center; - i{ + i.icon-right{ position:absolute; right:0; &:hover{ @@ -244,7 +253,7 @@ li{ margin:0; } textarea{ - width:132px; + width:204px; } &.half input{ margin-left:72px; @@ -256,6 +265,16 @@ li{ width:64px; padding-left:8px; } + li.label pre { + margin-left:-8px; + } + .right { + text-align:right; + } + li .label { + display:inline-block; + width:68px; + } } ul.labels{ li{ @@ -311,13 +330,8 @@ li{ } .system-info { - position: absolute; - top:7px; - left:0; - right:0; text-align: center; background-color:rgba(0,0,0,0.3); - color: #d6d6d6; border:1px solid #363636; border-left:none; @@ -355,12 +369,14 @@ li{ padding-top:7px; height:30px; a{ - font-size:8pt; - padding:2px 0px 1px 1px; - margin-right:5px; - display:inline-block; position: relative; - background-color: #1f1f20; + display:inline-block; + width: 16px; + height: 16px; + padding: 2px 1px 1px 1px; + margin-right:5px; + text-align:center; + font-size:8pt; &.facebook,&.twitter,&.gplus{ color:rgb(219, 219, 219); @@ -391,6 +407,21 @@ li{ font-size:12px; padding:0px 0px 0px 0px; } + i.icon-side{ + font-weight: bold; + letter-spacing: -2px; + padding: 0 3px; + } + i.icon-animation{ + padding: 2px; + letter-spacing: -1px; + } + i.icon-animation::after{ + content: "▶"; + } + i.icon-animation.play::after{ + content: "▮▮"; + } text-decoration: none; line-height:14px; color: #808080; @@ -419,6 +450,9 @@ li{ } } +li.section .actions { + padding: 2px 0 0 0; +} .drawing-pad{ position: absolute; @@ -439,30 +473,30 @@ li{ &.resizing{ cursor: ne-resize; } } } +.help-pad { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: $sideWidth+10; +} .ticker{ - @include scrollbar; - overflow-y: scroll; - position:absolute; - top:0; bottom:0;left:0;right:0; margin:1px; padding:0px; - text-align:center; .elem{ border:1px solid #6f6f6f; padding:2px; margin:1px; border-radius:1px; position:relative; - background-color: #2c2e33; - - width:130px; + background-color: rgba(44,46,51,$opacity); + width:103px; height:125px; - //position:relative; font-size:8pt; &:hover{ - background-color: #3f444a; + background-color: rgba(63,68,74,$opacity); } .img-holder{ text-align: center; @@ -492,6 +526,3 @@ li{ } } } - - - diff --git a/index.html b/index.html index 4bd49b7..64ed92c 100644 --- a/index.html +++ b/index.html @@ -5,26 +5,10 @@
Click and drag!
As you drag your mouse, you change the parameters of the system, which then gets redrawn.
The system's parameters are also sync'd automatically with the url - meaning you can share systems by pasting the url somewhere.
Also - since systems are just urls, your browsers back button works the way you would expect it to :)
Take a look at some of the examples here (you can scroll down!)
rules =
function (t) =+