Skip to content

Instantly share code, notes, and snippets.

@long-lazuli
Created January 19, 2014 23:37
Show Gist options
  • Save long-lazuli/8512487 to your computer and use it in GitHub Desktop.
Save long-lazuli/8512487 to your computer and use it in GitHub Desktop.
A Pen by Long Lazuli.
/ 8 items :
%menu.circular.classic{:'data-title' => 'Go !'}
%label{:for => 'Doc'}
%a{:href => '#Doc'} Doc
%label{:for => 'Toto'}
%a{:href => '#Toto'} Toto
%label{:for => 'Poum'}
%a{:href => '#Poum'} Poum
%label{:for => 'Home'}
%a{:href => '#Home'} Home
%label{:for => 'Doc'}
%a{:href => '#Doc'} Doc
%label{:for => 'Toto'}
%a{:href => '#Toto'} Toto
%label{:for => 'Poum'}
%a{:href => '#Poum'} Poum
/ 7 items :
%menu.circular.new
%label{:for => 'i'}
%a{:href => '#i'} I
%label{:for => 'ii'}
%a{:href => '#ii'} II
%label{:for => 'iii'}
%a{:href => '#iii'} III
%label{:for => 'iv'}
%a{:href => '#iv'} IV
%label{:for => 'v'}
%a{:href => '#v'} V
%label{:for => 'vi'}
%a{:href => '#vi'} VI
%label{:for => 'vii'}
%a{:href => '#vii'} VII
/ 5 items :
%menu.circular.new2
%label{:for => 'Home'}
%a{:href => '#Home'} Home
%label{:for => 'Doc'}
%a{:href => '#Doc'} Doc
%label{:for => 'Toto'}
%a{:href => '#Toto'} Toto
%label{:for => 'Poum'}
%a{:href => '#Poum'} Poum
%label{:for => 'Pim'}
%a{:href => '#Pim'} Pim
/ 10 items :
%menu.circular
%label{:for => 'Home'}
%a{:href => '#Home'} 1 Home
%label{:for => 'Doc'}
%a{:href => '#Doc'} 2 Doc
%label{:for => 'Toto'}
%a{:href => '#Toto'} 3 Tototo
%label{:for => 'Poum'}
%a{:href => '#Poum'} 4 Poum
%label{:for => 'Pim'}
%a{:href => '#Pim'} 5 Pim
%label{:for => 'Home'}
%a{:href => '#Home'} Home di Pim poum 6
%label{:for => 'Doc'}
%a{:href => '#Doc'} Document 7
%label{:for => 'Toto'}
%a{:href => '#Toto'} Toto 8
%label{:for => 'Poum'}
%a{:href => '#Poum'} Poum Poum Pouuuum 9
%label{:for => 'Pim'}
%a{:href => '#Pim'} Pim 10
@import "compass";
// Maximum number of Item in menu. Will stop to generate Code at this limit.
//$max-items: 12;
// If you want the item text to be shown horizontally,
// Be aware that if you put a too large number; some menu will not be visible.
//$max-items-horizontal: 8;
// If you want only a portion of circle, you can change this :
//$circle-portion: 360;
// An arbitrary rotation shift for all element :
//$rotation-shift: 90;
// those 2 values are the limit for the Menu text to be inverted; to enhance the reading.
// However, this is not applied in menu with horizontal text.
//$invert-text-min-angle: 90;
//$invert-text-max-angle: 270;
// You can, if you want reverse the rotation direction.
// It iis by default, it is clockwise.
//$rotation-reverse: true;
// Just a background to test this code. This should not be in a production generated CSS.
body {
background-image: url( http://fc09.deviantart.net/fs27/f/2008/070/d/a/Wood_tile_wallpaper_by_neko_xexe.png );
background-size: cover;
}
// ********************************************************************** //
// here are the default values.
// * DO NOT CHANGE * //
$max-items: 12 !default;
$max-items-horizontal: 8 !default;
$circle-portion: 360 !default;
$rotation-shift: 0 !default;
$invert-text-min-angle: 90 !default;
$invert-text-max-angle: 270 !default;
$rotation-reverse: false !default;
/* ********************************************************** */
/* Menu */
menu.circular {
height: 4em;
margin: 7em 8em;
position: relative;
display: inline-block;
text-decoration: none;
transition-duration: 200ms;
transition-property: box-shadow;
width: 4em;
white-space: nowrap;
&, *, &:before, *:before, &:after, *:after {
// for debug :
// border: 1px solid blue;
// outline: 1px solid black;
border-radius: 50%;
box-sizing: border-box;
line-height: 4em;
padding: 0;
text-align: center;
transform-origin: 50% 50%;
overflow: visible;
}
*, &:before, *:before, &:after, *:after {
display: block;
color: inherit;
font-family: inherit;
font-weight: inherit;
height: 100%;
left: 50%;
margin: 0;
position: absolute;
text-decoration: inherit;
text-shadow: inherit;
top: 50%;
transform: translate( -50%, -50%);
transform-origin: 50% 50%;
white-space: inherit;
width: 100%;
}
&:before {
content: "";
box-sizing: content-box;
transition-delay: 300ms, 300ms, 300ms, 0, 300ms, 300ms;
transition-duration: 200ms;
transition-property: border, color, text-shadow, box-shadow, width, height;
transition-timing-function: linear;
}
&:after { content: "Menu"; }
&[data-title]:after { content: attr( data-title )!important;}
&:hover {
&:before {
transition-delay: 0;
transition-duration: 100ms;
}
}
}
/* ********************************************************** */
/* Menu Items */
menu.circular {
& > * {
opacity: 0.0;
transform-origin: -100% 0;
transition-delay: 200ms, 200ms, 100ms, 0;
transition-duration: 200ms, 200ms, 200ms, 200ms;
transition-property: margin, left, opacity, transform;
transition-timing-function: linear;
}
&:hover > * {
left: 150%;
opacity: 1;
transition-delay: 0, 0, 100ms, 200ms;
}
}
/* ********************************************************** */
/* Menu Items Links */
menu.circular {
& > * > * {
transform-origin: 0% 0%;
transition-delay: 0;
transition-duration: 200ms, 200ms, 50ms, 50ms, 50ms;
transition-property: transform, color, box-shadow, heigth, width;
transition-timing-function: linear;
}
&:hover > * > *{
text-align: left;
&:hover {
text-decoration: underline;
transition-delay: 0,500ms,0, 0, 0;
}
}
}
/* ********************************************************** */
/* Differents Style :
*/
/* CLASSIC (first one) */
menu.circular.classic {
background-color: rgba(0,0,0,0);
box-shadow: 0.125em 0.1em .5em rgba(0,0,0,0.5),
-0.1em -0.06em 0 rgba(255,255,255,0.5);
color: rgba(0,0,0,0.5);
font-family: sans-serif;
font-weight: bold;
text-shadow: -0.125em -0.1em .5em rgba(0,0,0,0.25),
0.1em 0.06em 0 rgba(255,255,255,0.5);
&:before {
border: rgba(0,0,0,0.0) 0.5em solid;
box-shadow: inset 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
inset -0.1em -0.06em 0 0 rgba(255,255,255,0.5);
height: 5.5em;
width: 6.5em;
}
&:after {
content: "menu";
text-transform: uppercase;
}
&:hover {
box-shadow: none;
&:before {
border-width: 6.5em;
color: transparent;
text-shadow: none;
}
}
& > * > * {
border: 0.5em transparent solid;
box-shadow: inset 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
inset -0.1em -0.06em 0 0 rgba(255,255,255,0.5);
color: transparent;
height: 150%;
text-shadow: none;
width: 150%;
}
&:hover > * > *{
color: inherit;
text-shadow: inherit;
margin-left: 75%;
text-align: center;
&:hover {
box-shadow: 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
-0.1em -0.06em 0 0 rgba(255,255,255,0.5);
text-decoration: none;
&:active {
box-shadow: 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
-0.1em -0.06em 0 0 rgba(255,255,255,0.5),
inset 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
inset -0.1em -0.06em 0 0 rgba(255,255,255,0.5);
}
}
}
}
/* new */
menu.circular.new {
box-shadow: 0.125em 0.1em .5em rgba(0,0,0,0.5),
-0.1em -0.06em 0 rgba(255,255,255,0.5);
font-weight: bold;
text-shadow: -0.125em -0.1em .5em rgba(0,0,0,0.25),
0.1em 0.06em 0 rgba(255,255,255,0.5);
&:before {
box-shadow: inset 0.125em 0.2em .4em 0 rgba(0,0,0,0.25),
inset -0.1em -0.06em 0 0 rgba(255,255,255,0.5),
1em 0.6em 2.5em 0 rgba(255,255,255,0.1);
height: 140%;
width: 165%;
}
&:after {
content: "new";
text-transform: uppercase;
}
&:hover {
box-shadow: inset 0.125em 0.1em .25em rgba(0,0,0,0.25),
inset -0.1em -0.06em 0 rgba(255,255,255,0.5),
-1em -0.6em 2.5em 0 rgba(255,255,255,0.1);
&:before {
height: 450%;
width: 450%;
}
&:after {
content: "";
}
}
& > * > * {
box-shadow: 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
-0.1em -0.06em 0 0 rgba(255,255,255,0.5);
height: 100%;
min-width: 100%;
}
&:hover > * > * {
box-shadow: 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
-0.1em -0.06em 0 0 rgba(255,255,255,0.5);
margin-left: 35%;
text-align: center;
text-decoration: none;
&:hover {
box-shadow: 0.125em 0.1em .5em 0 rgba(0,0,0,0.5),
-0.1em -0.06em 0 0 rgba(255,255,255,0.5),
inset 1em 0.6em 2.5em 0 rgba(255,255,255,0.1);
&:active {
box-shadow: 0.06em 0.05em .25em 0 rgba(0,0,0,0.25),
-0.1em -0.06em 0 0 rgba(255,255,255,0.5),
inset 1em 0.6em 2.5em 0 rgba(255,255,255,0.1);
}
}
}
}
/**
* This is the Tricky part.
* Calculating the rotation by the number of Item in the menu.
*
**/
@function child-nth-of($index, $total) {
@if $index == 1 {
@return unquote(" & > *:first-child:nth-last-child( #{ $total} )");
} @else {
@return unquote(" & > *:first-child:nth-last-child( #{ $total} ) ~ *:nth-child( #{ $index } )");
}
}
@function pgcd($a, $b) {
$r: $a % $b;
@while $r != 0 {
$a: $b;
$b: $r;
$r: $a % $b;
}
@return $b;
}
@if $rotation-shift != 0 {
$rotationValue: $rotation-shift;
@if $rotation-reverse == true {
$rotationValue: $rotationValue * -1;
}
/* First-Items Rotation : */
menu.circular:hover > *:first-child {
transform: rotate(#{$rotationValue}deg) translate(-50%, -50%);
}
@if $max-items-horizontal > 0 {
$sFirstItems: child-nth-of( 1, 1 );
@for $f from 2 through $max-items-horizontal {
$sFirstItems: $sFirstItems, child-nth-of( 1, $f );
}
menu.circular:hover {
#{$sFirstItems} {
& > * {
transform: rotate( #{$rotationValue * -1}deg ) translate( -50%, -50% ) ;
}
}
}
}
}
@for $itemCount from 1 through $max-items {
$item-portion: $circle-portion / $itemCount;
@for $itemIndex from 1 through $itemCount - 1 {
@if ( ( $itemCount % $itemIndex != 0 ) or $itemIndex == 1 ) {
@if pgcd($itemCount, $itemIndex) == 1 {
$rotationValue: ( $item-portion * $itemIndex ) + $rotation-shift;
@while $rotationValue > 360 { $rotationValue: $rotationValue - 360; }
@while $rotationValue < -360 { $rotationValue: $rotationValue + 360; }
@if $rotation-reverse == true {
$rotationValue: $rotationValue * -1;
}
$sItem: child-nth-of( $itemIndex + 1, $itemCount );
$sTextHorizontal: null;
$cTextHorizontal: 0;
$sTextClassic: null;
$cTextClassic: 0;
$l: 1;
@while $l < $max-items / $itemCount {
$index: $itemIndex * $l + 1;
$total: $itemCount * $l;
@if $l > 1{
$sItem: $sItem, child-nth-of( $index, $total );
}
@if ( $itemCount * $l ) <= $max-items-horizontal {
@if $cTextHorizontal == 0{
$sTextHorizontal: child-nth-of( $index, $total );
} @else {
$sTextHorizontal: $sTextHorizontal, child-nth-of( $index, $total );
}
$cTextHorizontal: $cTextHorizontal + 1;
} @else{
@if $cTextClassic == 0{
$sTextClassic: child-nth-of( $index, $total );
} @else {
$sTextClassic: $sTextClassic, child-nth-of( $index, $total );
}
$cTextClassic: $cTextClassic + 1;
}
$l: $l + 1;
}
menu.circular:hover {
#{$sItem} {
transform: rotate(#{$rotationValue}deg) translate(-50%, -50%);
}
@if $cTextHorizontal > 0 {
#{$sTextHorizontal} {
//text-align: center;
& > * {
transform: rotate( #{$rotationValue * -1}deg ) translate( -50%, -50% ) ;
text-align: center;
}
}
}
@if $cTextClassic > 0 {
#{$sTextClassic} {
@if $rotationValue >= $invert-text-min-angle
and $rotationValue < $invert-text-max-angle {
& > * {
transform:
rotate( 180deg )
translate( -50%, -50%);
text-align: right;
direction: rtl;
right: 0;
color: blue;
}
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment