-
-
Save leefish/4052043 to your computer and use it in GitHub Desktop.
<marquee> element lives! - Emulating the behavior of the old marquee element with CoffeeScript/JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class @Marquee | |
constructor: (@element, @options={}) -> | |
# Set defaults | |
@options['duration'] or= 30 | |
@options['wrapAround'] = true unless 'wrapAround' of @options | |
@options['direction'] or= 'forward' | |
# If everything fits don't bother with all this mess | |
return if this.element.scrollWidth == this.element.clientWidth | |
# Create wrapping container to scroll the marquee in. | |
# Adapted from Prototype's wrap method. | |
@container = document.createElement 'div' | |
@container.className = 'marquee-wrapper' | |
@element.parentNode.replaceChild @container, @element if @element.parentNode | |
@container.appendChild @element | |
# Move some of the relevant marquee styles to this wrapper. | |
@container.style.width = @element.clientWidth+'px' | |
@container.style.height = @element.clientHeight+'px' | |
@container.style.overflow = 'hidden' | |
# Keep in mind how big it was so we know when to reset | |
@originalWidth = @element.scrollWidth | |
# Make it look like it is wrapping around by duping content | |
if @options.wrapAround | |
trimmed = element.innerHTML.trim() | |
@element.innerHTML = trimmed + trimmed + trimmed | |
# Size restrictions/clipping moved to wrapper, remove from element | |
@element.style.width = @element.scrollWidth+'px' | |
@element.style.height = @element.scrollHeight+'px' | |
@element.style.overflow = 'auto' | |
@container.scrollLeft = @originalWidth if @options.wrapAround | |
# Will start the marquee moving. | |
# | |
# If no argument is given it will move until it gets to the end of the | |
# content. If wrapAround is enabled it will reset and do another move to the | |
# end of the content creating a never-ending scrolling of the content. | |
# | |
# If a distance is given then it will only move that far then stop. | |
move: (distance=null, onFinish=->) -> | |
ending_position = if distance | |
if @options.direction is 'forward' | |
@container.scrollLeft + distance | |
else | |
@container.scrollLeft - distance | |
else | |
if @options.direction is 'forward' | |
@container.scrollLeft + @originalWidth | |
else | |
@container.scrollLeft - @originalWidth | |
callback = if @options.wrapAround && !distance | |
=> | |
@container.scrollLeft = @originalWidth | |
onFinish() | |
Marquee.tween @container, @options.duration, ending_position, callback | |
else | |
onFinish | |
Marquee.tween @container, @options.duration, ending_position, callback | |
# To actually do the moving we farm this out to a callback. This way the actual | |
# movement can be handled by a library like morpheus which is designed as a | |
# single high-performance loop using constant speed animation and the | |
# requestAnimationFrame standard. | |
# | |
# This should be replaced by a function that actually does the work. | |
Marquee = @Marquee | |
Marquee.tween = (element, duration, target_scroll, oncomplete) -> | |
# By default implement a stupid "animation" that just move it without | |
# any in-between stages. | |
element.scrollLeft = target_scroll | |
oncomplete() | |
# Adapted from | |
# http://stackoverflow.com/questions/498970/#answer-8522376 | |
unless String::trim | |
String::trim = -> @replace /^\s+|\s+$/g,'' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
#test { | |
font-size: 3em; | |
width: 10em; | |
height: 1.5em; | |
overflow: hidden; | |
white-space: nowrap; | |
} | |
</style> | |
</head> | |
<div id="test"> | |
The quick brown fox jumps over the lazy dog | |
</div> | |
<script src="marquee.js"></script> | |
<script src="morpheus.js"></script> | |
<script> | |
Marquee.tween = function(element, duration, end, onComplete) { | |
morpheus.tween(duration*1000, function(position) { | |
element.scrollLeft = position | |
}, onComplete, function(p) {return p}, element.scrollLeft, end) | |
} | |
marquee = new Marquee(document.getElementById('test')); | |
marquee.move(); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment