<html>
<head lang="en">
<meta charset="UTF-8">
<title>RxJS</title>
<link rel="stylesheet" href="css/index.css"/>
</head>
<body>
<div class="container">
<div class="header">
<button id="btn" class="left">Try!</button>
<div class="right">
<p><svg height="12" width="12"> <circle cx="6" cy="6" r="6" fill="#69c2d8"></circle> </svg>click</p>
<p><svg height="12" width="12"> <circle cx="6" cy="6" r="6" fill="#ed145b"></circle> </svg>alt+click</p>
</div>
</div>
<div id="marbles">
<div class="timeline"><div class="progressbar"></div></div>
<div class="filter">filter()</div>
<div class="timeline"><div class="progressbar"></div></div>
</div>
</div>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.11.7/TweenMax.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/rxjs/2.3.22/rx.all.js"></script>
</body>
</html>
/* line 3, ../sass/index.scss */
body {
font-family: sans-serif;
color: #31332e;
}
/* line 8, ../sass/index.scss */
.right {
float: right;
}
/* line 12, ../sass/index.scss */
.left {
float: left;
}
/* line 16, ../sass/index.scss */
#btn {
width: 138px;
text-align: center;
border: 1px solid #52b0c7;
box-shadow: 0 3px #308fa7;
color: white;
font-family: Helvetica, Verdana, sans-serif;
font-weight: lighter;
font-style: italic;
font-size: 13px;
letter-spacing: 1px;
padding: 7px 35px;
padding-top: 9px;
border-radius: 5px;
position: relative;
background: #68c2d8;
/* Old browsers */
background: linear-gradient(top, #68c2d8 0%, #41b2cd 100%);
/* FF3.6+ */
background: gradient(linear, left top, left bottom, color-stop(0%, #68c2d8), color-stop(100%, #41b2cd));
/* Chrome,Safari4+ */
background: linear-gradient(top, #68c2d8 0%, #41b2cd 100%);
/* Chrome10+,Safari5.1+ */
background: linear-gradient(top, #68c2d8 0%, #41b2cd 100%);
/* Opera 11.10+ */
background: linear-gradient(top, #68c2d8 0%, #41b2cd 100%);
/* IE10+ */
background: linear-gradient(to bottom, #68c2d8 0%, #41b2cd 100%);
/* W3C */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#68c2d8', endColorstr='#41b2cd', GradientType=0);
/* IE6-9 */
}
/* line 40, ../sass/index.scss */
#btn:active {
box-shadow: 0 1px #308fa7;
top: 2px;
}
/* line 45, ../sass/index.scss */
#btn:focus {
outline: 0;
}
/* line 50, ../sass/index.scss */
.container {
position: relative;
width: 605px;
padding: 60px 10px;
}
/* line 54, ../sass/index.scss */
.container .header {
overflow: hidden;
}
/* line 57, ../sass/index.scss */
.container .header .right p {
display: inline-block;
margin-left: 2em;
}
/* line 61, ../sass/index.scss */
.container .header .right svg {
margin-right: 0.5em;
}
/* line 68, ../sass/index.scss */
.event-marker {
position: absolute;
top: -5px;
}
/* line 71, ../sass/index.scss */
.event-marker.scale-up {
transform: scale(0);
transform: scale(0);
transform: scale(0);
transform: scale(0);
animation-name: scaleUp;
animation-name: scaleUp;
animation-name: scaleUp;
animation-duration: 0.3s;
animation-duration: 0.3s;
animation-duration: 0.3s;
animation-fill-mode: both;
animation-fill-mode: both;
animation-fill-mode: both;
}
/* line 77, ../sass/index.scss */
.event-marker.fadeOut {
animation-name: fadeOut;
animation-name: fadeOut;
animation-name: fadeOut;
animation-delay: 0.3s;
animation-delay: 0.3s;
animation-delay: 0.3s;
animation-duration: 0.5s;
animation-duration: 0.5s;
animation-duration: 0.5s;
animation-fill-mode: both;
animation-fill-mode: both;
animation-fill-mode: both;
}
/* line 83, ../sass/index.scss */
.event-marker.go-down {
animation-name: go-down;
animation-name: go-down;
animation-name: go-down;
animation-delay: 0.3s;
animation-delay: 0.3s;
animation-delay: 0.3s;
animation-duration: 1.2s;
animation-duration: 1.2s;
animation-duration: 1.2s;
animation-fill-mode: both;
animation-fill-mode: both;
animation-fill-mode: both;
}
/* line 93, ../sass/index.scss */
.filter {
border: 1px dashed #9e9f9d;
text-align: center;
padding: 18px;
margin: 30px 0;
font-style: italic;
letter-spacing: 1px;
color: #313131;
}
/* line 103, ../sass/index.scss */
.timeline {
height: 2px;
background: #d0d0d0;
position: relative;
}
/* line 107, ../sass/index.scss */
.timeline::after {
content: "";
display: block;
width: 6px;
height: 6px;
border-top: 2px solid #D0D0D0;
border-right: 2px solid #D0D0D0;
transform: rotate(45deg);
transform: rotate(45deg);
position: absolute;
right: 0;
top: 4px;
margin-top: -7px;
}
/* line 121, ../sass/index.scss */
.timeline .progressbar {
width: 0;
height: 100%;
background: #4C4C4C;
}
/* line 126, ../sass/index.scss */
.timeline.end::after {
border-color: #4C4C4C;
}
/* line 131, ../sass/index.scss */
#marbles {
position: relative;
margin-top: 60px;
}
@-moz-keyframes scaleUp {
100% {
transform: scale(1);
}
}
@-webkit-keyframes scaleUp {
100% {
transform: scale(1);
}
}
@keyframes scaleUp {
100% {
transform: scale(1);
}
}
@-moz-keyframes fadeOut {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
100% {
transform: translateY(70px);
transform: translateY(70px);
opacity: 0;
}
}
@-webkit-keyframes fadeOut {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
100% {
transform: translateY(70px);
transform: translateY(70px);
opacity: 0;
}
}
@keyframes fadeOut {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
100% {
transform: translateY(70px);
transform: translateY(70px);
transform: translateY(70px);
transform: translateY(70px);
opacity: 0;
}
}
@-moz-keyframes go-down {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
100% {
transform: scale(1);
transform: scale(1);
transform: translateY(116px);
transform: translateY(116px);
}
}
@-webkit-keyframes go-down {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
100% {
transform: scale(1);
transform: scale(1);
transform: translateY(116px);
transform: translateY(116px);
}
}
@keyframes go-down {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
100% {
transform: scale(1);
transform: scale(1);
transform: scale(1);
transform: scale(1);
transform: translateY(116px);
transform: translateY(116px);
transform: translateY(116px);
transform: translateY(116px);
}
}
# global var
$btn = $('#btn')
$timeline = $('.timeline')
$progressbar = $timeline.find('.progressbar')
$marbles = $('#marbles')
btnClicks = Rx.Observable.fromEvent($btn, "click")
shockwave = '<svg height="150" width="150" style="position: absolute;pointer-events:none;"> <circle cx="50%" cy="50%" r="0" fill-opacity="1"></circle> </svg>'
click_event_marker = '<svg class="event-marker" height="12" width="12"> <circle cx="50%" cy="50%" r="50%" fill="#69c2d8"></circle> </svg>'
click_alt_event_marker = '<svg class="event-marker" height="12" width="12"> <circle cx="50%" cy="50%" r="50%" fill="#ed145b"></circle> </svg>'
$all_event_markers = $()
# ====================== 事前準備 ======================
# ===== `text()`を拡張して、リセットできるようにする =====
do ->
original_text_fn = $.fn.text
$.fn.text = ()->
@each ->
$this = $(@)
if $this.data('original_text') then return
$this.data('original_text', original_text_fn.apply(@))
return original_text_fn.apply(@, arguments)
$.fn.reset_text = ()->
@each ()->
$this = $(@)
original_text = $this.data('original_text')
if(original_text) then $this.text(original_text)
# ===== タイムラインのアニメーションの開始とリセットメソッド =====
$timeline.play = (duration, promise)->
(new TimelineLite())
.to($progressbar, duration / 1000, width: '100%', ease: Linear.easeNone)
.add ()->
$timeline.addClass('end')
promise.resolve()
$timeline.rewind = ->
$progressbar.css(width: 0)
$timeline.removeClass('end')
$all_event_markers.remove()
# ====================== メインプログラム ======================
set_program = ->
btnClicks = Rx.Observable.fromEvent($btn, "click")
d = new $.Deferred
animation = {
duration: 5000
start_time: null
get_percentage: ->
time = (new Date()).getTime()
return ((time - @start_time) / @duration) * 100
click_alt: ()->
@drop_event_marker(click_alt_event_marker, 'go-down')
click: ()->
@drop_event_marker(click_event_marker, 'fadeOut')
shockwave: (coordinate)->
$shockwave = $(shockwave).appendTo('body')
$shockwave_circle = $shockwave.find('circle').attr('fill', coordinate.color)
(new TimelineLite())
.set($shockwave, left: coordinate.x - 75, top: coordinate.y - 75)
.to($shockwave_circle, 0.5, attr: {'fill-opacity': 0, r: 75}, ease: Quad.easeOut)
.add ->$shockwave.remove()
drop_event_marker: (pointer, class_name)->
left = @get_percentage() + '%'
$click_event = $(pointer).css('left': left)
$click_event[0].classList.add('scale-up')
$click_event_down = $(pointer).css('left': left)
$click_event_down[0].classList.add(class_name)
$marbles.append($click_event)
$marbles.append($click_event_down)
$all_event_markers = $all_event_markers.add($click_event).add($click_event_down)
start: ->
@start_time = (new Date()).getTime()
$timeline.play(@duration, d)
$btn.text('click me')
}
btnClicks
.take(1)# take the first event only
.subscribe -> # when user click the button then ...
$timeline.rewind() # init the animation of `time-line`
animation.start() # start animation
btnClicks
.filter (event)->
return event.altKey
.takeUntil(d.promise())
.subscribe($.proxy(animation.click_alt, animation))
btnClicks
.filter (event)->
return !event.altKey
.takeUntil(d.promise())
.subscribe($.proxy(animation.click, animation))
btnClicks
.map (event)->
return {x: event.pageX, y: event.pageY, color: if event.altKey then '#ed145b' else '#69c2d8'}
.subscribe($.proxy(animation.shockwave, animation))
return d.promise()
reset_program = ->
$btn.reset_text()
run_program()
run_program = -> set_program().then(reset_program)
run_program()
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |