Skip to content

Instantly share code, notes, and snippets.

@rlmcneary2
Created November 26, 2011 22:22
Show Gist options
  • Save rlmcneary2/1396405 to your computer and use it in GitHub Desktop.
Save rlmcneary2/1396405 to your computer and use it in GitHub Desktop.
Javascript menu with animated pointer and flag
@CHARSET "ISO-8859-1";
#menu {color:black;background-color:white;}
#menuBar {position:relative;top:-10px;left:0px;width:100%;height:30px;}
#pointer {position:relative;top:-18px;width:20px;height:20px;margin-left:auto;margin-right:auto;background-color:#8BBAE5;-o-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg);}
#menuBarLower {position:relative;top:-10px;left:0px;width:100%;height:10px;background-color:#8BBAE5;}
#selectorOuter {position:relative;top:4px;width:20px;height:20px;margin-left:auto;margin-right:auto;background-color:#8BBAE5;-o-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg);}
#selectorInner {position:relative;top:-12px;width:20px;height:20px;margin-left:auto;margin-right:auto;background-color:#FFFFFF;-o-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg);}
#selectorBar {position:relative;top:-32px;width:100%;height:2px;background-color:#FFFFFF;}
#menuBarLowerThin {position:relative;width:100%;height:3px;background-color:#8BBAE5;}
#menuBarLowerWhite {position:relative;width:100%;height:2px;background-color:#FFFFFF;}
.menu_item {position:relative;width:100px;height:30px;float:left;background-color:transparent;cursor:pointer;}
.menu_item_text {position:relative;display:block;float:left;margin:0px;width:100px;line-height:30px;text-align:center;vertical-align:middle;cursor:pointer;}
.marker {position:relative;left:0px;top:0px;height:10px;width:100px;overflow:hidden;visibility:hidden;}
.markerSelector{top:-10px;height:10px;visibility:visible;}
.marker_move_right, .marker_move_left {-moz-animation-duration: 150ms;-moz-animation-name: moveRightKeyFrames;-moz-animation-timing-function:ease-in;-webkit-animation-duration: 150ms;-webkit-animation-name: moveRightKeyFrames;-webkit-animation-timing-function:ease-in;animation-duration: 150ms;animation-name: moveRightKeyFrames;animation-timing-function:ease-in;}
.marker_move_left {-moz-animation-name: moveLeftKeyFrames;-webkit-animation-name: moveLeftKeyFrames;animation-name: moveLeftKeyFrames;}
@-moz-keyframes moveRightKeyFrames { 0% {margin-left:0%;} 100% {margin-left:100px;}}
@-moz-keyframes moveLeftKeyFrames { 0% {margin-left: 0%;} 100% {margin-left: -100px;}}
@-webkit-keyframes moveRightKeyFrames { 0% {margin-left:0%;} 100% {margin-left:100px;}}
@-webkit-keyframes moveLeftKeyFrames { 0% {margin-left: 0%;} 100% {margin-left: -100px;}}
@keyframes moveRightKeyFrames { 0% {margin-left:0%;} 100% {margin-left:100px;}}
@keyframes moveLeftKeyFrames { 0% {margin-left: 0%;} 100% {margin-left: -100px;}}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="menu.css" />
</head>
<body>
<div id="menu">
<div id="pointerMarker" class="marker hidden">
<div id="pointer"></div>
</div>
<div id="menuBar">
<div class="menu_item">
<p class="menu_item_text">Main</p>
</div>
<div class="menu_item">
<p class="menu_item_text">Search</p>
</div>
<div class="menu_item">
<p class="menu_item_text">Contact</p>
</div>
</div>
<div id="menuBarLower">
<div id="menuBarLowerThin"></div>
<div id="menuBarLowerWhite"></div>
<div id="selectedMarker" class="marker markerSelector">
<div id="selectorOuter"></div>
<div id="selectorInner"></div>
<div id="selectorBar"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script src="menu.js"></script>
<script type="text/javascript">
var pointerMarker = null;
var selectorMarker = null;
$(document).ready (function () {
pointerMarker = new MenuMarker ();
pointerMarker.setMarker ($("#pointerMarker")[0]);
selectorMarker = new MenuMarker ();
selectorMarker.setMarker ($("#selectedMarker")[0]);
selectorMarker.setAnimateEndedCallback (function (marker) {
//alert ($(marker.getActiveElement ()).children ()[0].innerHTML);
});
$("#menuBar").mouseleave (function () {
pointerMarker.hide ();
});
var buttons = $(".menu_item");
for (var i = 0; i < buttons.length; i++)
{
$(buttons[i]).mouseover (function (evt) {
pointerMarker.show (true, evt.delegateTarget, "marker_move_left", "marker_move_right");
});
$(buttons[i]).click (function (evt) {
selectorMarker.show (true, evt.delegateTarget, "marker_move_left", "marker_move_right");
});
}
});
</script>
</body>
</html>
function MenuMarker ()
{
this.isShown = false;
this.marker = null;
this.animateEndedCallback = null;
this.activeElement = null;
}
MenuMarker.prototype.setMarker = function (marker)
{
this.marker = marker;
this.isShown = "visible" == $(marker).css ("visibility");
}
MenuMarker.prototype.setAnimateEndedCallback = function (callback)
{
this.animateEndedCallback = callback;
}
MenuMarker.prototype.getActiveElement = function ()
{
return this.activeElement;
}
MenuMarker.prototype.isCssAnimationSupported = function (element)
{
if (element.style.animationName)
return true;
var domPrefixes = "Webkit Moz O ms Khtml".split(" ");
for (var i = 0; i < domPrefixes.length; i++)
{
if (element.style[domPrefixes[i] + "AnimationName"] !== undefined)
return true;
}
return false;
}
MenuMarker.prototype.show = function (isAnimated, destElement, moveLeftClassName, moveRightClassName)
{
this.activeElement = destElement;
var destLeftSide = $(destElement).position ().left;
if (this.isShown === true)
{
if (isAnimated)
{
var that = this;
// If CSS animation is available use that.
if (moveLeftClassName && moveRightClassName && this.isCssAnimationSupported (this.marker))
{
var cssLeft = parseFloat($(this.marker).css ("left"));
var aniClassName = cssLeft <= destLeftSide ? moveRightClassName : moveLeftClassName;
$("body").on("mozAnimationEnd webkitAnimationEnd animationend", "#" + this.marker.id, function (event){
$(this).css ("left", destLeftSide);
$(this).removeClass (aniClassName);
$("body").off ("mozAnimationEnd webkitAnimationEnd animationend", "#" + this.id);
if (that.animateEndedCallback)
that.animateEndedCallback (that);
return false;
});
$(this.marker).addClass (aniClassName);
}
else
{
// No CSS animation go ahead and use jQuery.
$(this.marker).animate ({left:destLeftSide}, 150, "swing", function () {
if (that.animateEndedCallback)
that.animateEndedCallback (that);
});
}
}
else
{
$(this.marker).css ("left", destLeftSide);
if (this.animateEndedCallback)
this.animateEndedCallback (this);
}
}
else
{
$(this.marker).css ("left", destLeftSide);
$(this.marker).css ("visibility","visible");
this.isShown = true;
}
}
MenuMarker.prototype.hide = function ()
{
$(this.marker).css ("visibility","hidden");
this.isShown = false;
}
@anthonyzz
Copy link

This tests awesome, quite different from the animations in menu control by C# I've experience with a WinForms UI Menu control. I think I've found what I eagerly need here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment