diff --git a/README.md b/README.md index c6c5cf6..0925a05 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,10 @@ Alternatively, instead of loading livereload.js from the LiveReload server, you ``` +### Animated transitions + +LiveReload can animate changes. To enable animated transitions pass `animate=true` to `livereload.js` when including in the script tag. The default transition duration is 280ms and configurable when an integer is passed as value to `animate`, e.g. `animate=400` (in milliseconds). + Issues & Limitations -------------------- diff --git a/src/livereload.coffee b/src/livereload.coffee index dbfd025..ee03f30 100644 --- a/src/livereload.coffee +++ b/src/livereload.coffee @@ -82,10 +82,19 @@ exports.LiveReload = class LiveReload originalPath: message.originalPath || '' overrideURL: message.overrideURL || '' serverURL: "http://#{@options.host}:#{@options.port}" + @performTransition() if @options.animate performAlert: (message) -> alert message.message + performTransition: -> + html = document.body.parentNode + reloadedClass = ' livereload-reloaded ' + existingHtmlClass = html.getAttribute('class') ? '' + html.setAttribute('class', "#{existingHtmlClass.replace(reloadedClass, '')} #{reloadedClass}") + setTimeout (-> html.setAttribute('class', existingHtmlClass.replace(reloadedClass, ''))), + parseInt(@options.animate, 10) + shutDown: -> @connector.disconnect() @log "LiveReload disconnected." @@ -143,3 +152,19 @@ exports.LiveReload = class LiveReload @connector.sendCommand { command: 'info', plugins: pluginsData, url: @window.location.href } return + + setUpCSSTransitions: -> + prefixer = (declaration) -> + (['-webkit-', '-moz-', ''].map (item) -> ("#{item}#{declaration}")).join(' ') + + head = document.getElementsByTagName('head')[0] + styleNode = document.createElement("style") + cssText = ".livereload-reloaded * { #{prefixer('transition: all ' + + @options.animate + 'ms ease-out;')} }" + + if styleNode.styleSheet + styleNode.styleSheet.cssText = cssText + else + styleNode.appendChild(document.createTextNode(cssText)) + + head.appendChild(styleNode) diff --git a/src/options.coffee b/src/options.coffee index 1175e51..965321e 100644 --- a/src/options.coffee +++ b/src/options.coffee @@ -11,6 +11,8 @@ exports.Options = class Options @maxdelay = 60000 @handshake_timeout = 5000 + @animate = false # true or value in milliseconds, e.g. 420 + set: (name, value) -> if typeof value is 'undefined' return @@ -18,6 +20,10 @@ exports.Options = class Options if not isNaN(+value) value = +value + if name == 'animate' + value = 280 if value is 'true' # default animation duration + return if !/true|^\d+$/.test(value) + @[name] = value Options.extract = (document) -> diff --git a/src/startup.coffee b/src/startup.coffee index e8882c4..744cc6f 100644 --- a/src/startup.coffee +++ b/src/startup.coffee @@ -8,6 +8,7 @@ LiveReload.addPlugin require('./less') LiveReload.on 'shutdown', -> delete window.LiveReload LiveReload.on 'connect', -> + LiveReload.setUpCSSTransitions() if LiveReload.options.animate CustomEvents.fire document, 'LiveReloadConnect' LiveReload.on 'disconnect', -> CustomEvents.fire document, 'LiveReloadDisconnect' diff --git a/test/html/animation/test.css b/test/html/animation/test.css new file mode 100644 index 0000000..e541a38 --- /dev/null +++ b/test/html/animation/test.css @@ -0,0 +1,3 @@ +body { + background: green; +} diff --git a/test/html/animation/test.html b/test/html/animation/test.html new file mode 100644 index 0000000..a250652 --- /dev/null +++ b/test/html/animation/test.html @@ -0,0 +1,11 @@ + + + + LiveReload Test + + + +

Test animated transitions

+ + +