diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'a419cf4b', + 'core.pkg.css' => 'ac9bbf2a', 'core.pkg.js' => '400453e4', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '2de124c9', @@ -111,7 +111,7 @@ 'rsrc/css/font/font-aleo.css' => '8bdb2835', 'rsrc/css/font/font-awesome.css' => 'c43323c5', 'rsrc/css/font/font-lato.css' => 'c7ccd872', - 'rsrc/css/font/phui-font-icon-base.css' => 'ecbbb4c2', + 'rsrc/css/font/phui-font-icon-base.css' => 'c0fc32fa', 'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82', 'rsrc/css/layout/phabricator-hovercard-view.css' => '1239cd52', 'rsrc/css/layout/phabricator-side-menu-view.css' => 'bec2458e', @@ -509,6 +509,7 @@ 'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca', 'rsrc/js/phuix/PHUIXFormControl.js' => '8fba1997', 'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b', + 'rsrc/js/special/behavior-trail.js' => '740fe844', ), 'symbols' => array( 'almanac-css' => 'dbb9b3af', @@ -645,6 +646,7 @@ 'javelin-behavior-phabricator-search-typeahead' => '048330fa', 'javelin-behavior-phabricator-show-older-transactions' => 'dbbf48b6', 'javelin-behavior-phabricator-tooltips' => '3ee3408b', + 'javelin-behavior-phabricator-trail' => '740fe844', 'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6', 'javelin-behavior-phabricator-transaction-list' => '13c739ea', 'javelin-behavior-phabricator-watch-anchor' => '9f36c42d', @@ -804,7 +806,7 @@ 'phui-document-view-css' => 'a4a1c3b9', 'phui-document-view-pro-css' => 'e0fad431', 'phui-feed-story-css' => 'b7b26d23', - 'phui-font-icon-base-css' => 'ecbbb4c2', + 'phui-font-icon-base-css' => 'c0fc32fa', 'phui-fontkit-css' => '9cda225e', 'phui-form-css' => '0b98e572', 'phui-form-view-css' => '4a1a0f5e', @@ -1360,6 +1362,12 @@ 'javelin-vector', 'javelin-dom', ), + '740fe844' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-vector', + ), '76b9fc3e' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -215,6 +215,7 @@ require_celerity_resource('font-aleo'); Javelin::initBehavior('workflow', array()); + Javelin::initBehavior('phabricator-trail'); $request = $this->getRequest(); $user = null; diff --git a/webroot/rsrc/css/font/phui-font-icon-base.css b/webroot/rsrc/css/font/phui-font-icon-base.css --- a/webroot/rsrc/css/font/phui-font-icon-base.css +++ b/webroot/rsrc/css/font/phui-font-icon-base.css @@ -161,3 +161,21 @@ .device-desktop a.phui-icon-view.bluegrey:hover { color: {$darkbluetext}; } + + +.ph-bounceout { + animation: bounceout 0.5s linear forwards; +} + +@keyframes bounceout { + 0% { + transform: scale(1.0) rotate(0deg); + } + 10% { + transform: scale(2.0) rotate(0deg); + } + 100% { + transform: scale(0) rotate(359deg); + opacity: 0; + } +} diff --git a/webroot/rsrc/js/special/behavior-trail.js b/webroot/rsrc/js/special/behavior-trail.js new file mode 100644 --- /dev/null +++ b/webroot/rsrc/js/special/behavior-trail.js @@ -0,0 +1,81 @@ +/** + * @provides javelin-behavior-phabricator-trail + * @requires javelin-behavior + * javelin-dom + * javelin-stratcom + * javelin-vector + * @javelin + */ + +JX.behavior('phabricator-trail', function() { + var last = null; + var trail = []; + + var n = 0; + JX.Stratcom.listen('mousemove', null, function(e) { + var v = JX.$V(e); + + if (!last) { + last = v; + return; + } + + var dx = v.x - last.x; + var dy = v.y - last.y; + var spacing = 24; + + if ((dx * dx) + (dy * dy) < (spacing * spacing)) { + // Mouse hasn't moved far enough, just bail. + return; + } + + var node; + // If the trail is too long, throw away the end. + while (trail.length > 8) { + node = trail[0]; + JX.DOM.remove(node); + trail.splice(0, 1); + } + + var color; + if (n % 2) { + color = '#c0392b'; + } else { + color = '#139543'; + } + + n++; + + var icon; + if (Math.random() > 0.5) { + icon = 'fa-star'; + } else { + icon = 'fa-tree'; + } + + node = JX.$N( + 'span', + { + className: 'phui-icon-view phui-font-fa ph-bounceout ' + icon, + style: { + position: 'absolute', + color: color, + zIndex: 20151225 + } + }, + null); + + var size = JX.Vector.getDim(node); + + last.x -= size.x / 2; + last.y -= size.y / 2; + + last.setPos(node); + + trail.push(node); + document.body.appendChild(node); + + last = v; + }); + +});