Skip to content

Instantly share code, notes, and snippets.

@tanduong
Created July 29, 2015 03:03
Show Gist options
  • Save tanduong/d1dbbdc851ce64c2f873 to your computer and use it in GitHub Desktop.
Save tanduong/d1dbbdc851ce64c2f873 to your computer and use it in GitHub Desktop.
qdQRMZ
<html ng-app="buttons">
<div button-group>
<div button-main>
<div>Main</div>
</div>
<div button-item>
<div>Item 1</div>
</div>
<div button-item>
<div>Item 2</div>
</div>
<div button-item>
<div>Item 3</div>
</div>
<div button-item>
<div>Item 4</div>
</div>
</div>
</html>
var app = angular.module('buttons', []);
app.directive('buttonGroup', function() {
return {
restrict: 'EA',
transclude: true,
scope: {
},
controller: function($scope) {
var items = $scope.items = [];
var rightAngle = 1.57079633;
var endAngle = 1.57079633;
var startAngle = 3.14159265;
var startAngle = 0;
var flightOutRadius = 150; //px
var primaryItemRadius = 50;
var secondaryItemRadius = 25;
var itemStartPosition = {
top: primaryItemRadius - secondaryItemRadius,
left: primaryItemRadius - secondaryItemRadius
};
var originPosition = {
top: primaryItemRadius,
left: -primaryItemRadius
};
function recomputeItemsPosition() {
var index, alpha, itemCount;
index = 0;
itemCount = items.length;
angular.forEach(items, function(item){
var itemAngle = startAngle + index*(endAngle - startAngle)/(itemCount - 1);
item.top = Math.floor(itemStartPosition.top - flightOutRadius * Math.sin(itemAngle));
item.left = Math.floor(itemStartPosition.left + flightOutRadius * Math.cos(itemAngle));
index = index + 1;
});
}
this.itemStartPosition = itemStartPosition;
console.log('here in controller');
this.addItem = function(item) {
items.push(item);
recomputeItemsPosition();
};
this.toggleActive = function() {
angular.forEach($scope.items, function(item){
item.ctrl.toggleActive();
});
};
},
template: '<div><div class="button-group" ng-transclude></div></div>'
};
})
.directive('buttonMain', function() {
return {
restrict: 'EA',
transclude: true,
scope: {},
require: '^buttonGroup',
link: function(scope, element, attrs, buttonGroupCtrl) {
scope.ctrl = {};
scope.ctrl.toggleActive = function() {
buttonGroupCtrl.toggleActive();
};
console.log('here in main');
},
template: '<div class="button-main" ng-transclude ng-click="ctrl.toggleActive()"></div>'
};
})
.directive('buttonItem', function() {
return {
restrict: 'EA',
transclude: true,
replace: true,
scope: {},
require: '^buttonGroup',
link: function(scope, element, attrs, buttonGroupCtrl) {
console.log('here in item');
buttonGroupCtrl.addItem(scope);
element.css({
top: buttonGroupCtrl.itemStartPosition.top + 'px',
left: buttonGroupCtrl.itemStartPosition.left + 'px'
});
scope.ctrl = {};
scope.ctrl.toggleActive = function() {
if(scope.isActive) {
element.css({
top: buttonGroupCtrl.itemStartPosition.top + 'px',
left: buttonGroupCtrl.itemStartPosition.left + 'px'
});
}
else {
element.css({
top: scope.top + 'px',
left: scope.left + 'px'
});
}
scope.isActive = !scope.isActive;
};
},
template: '<div class="button-item" ng-transclude></div>'
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
.button-group, .button-main, .button-item {
border-radius: 50%;
width: 100px;
height: 100px;
line-height: 100px;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.button-group {
margin-top: 200px;
position: relative;
}
.button-main {
background-color: blue;
z-index: 2;
position: absolute;
top: 0;
left: 0;
}
.button-item {
line-height: 50px;
background-color: green;
z-index: 1;
position: absolute;
transition: top 0.5s, left 0.5s;
width: 50px;
height: 50px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment