Created
September 14, 2016 07:35
-
-
Save anonymous/35fb1e4461837469918ff3301f5b51c3 to your computer and use it in GitHub Desktop.
SVG ring 4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container" ng-app="app"> | |
<div ng-controller="MyCtrl as vm"> | |
<svg width="400" viewbox="-300 -300 600 600"> | |
<g id="circle" style="transform: rotate({{vm.circleRotate}}deg)" ng-class="{ dragging: vm.dragStart }"> | |
<circle fill="#F1F1F1" cy="0" cx="0" ng-attr-r="{{ ::vm.circleRadius }}"></circle> | |
<g ng-repeat="icon in vm.icons" class="icon" ng-attr-transform="{{ 'rotate(-' + vm.iconRotate * $index + ') translate(0, ' + (vm.circleRadius - vm.iconSize) + ')' }}"> | |
<rect ng-attr-width="{{ ::vm.iconSize }}" | |
ng-attr-height="{{ ::vm.iconSize }}" | |
ng-attr-fill="{{ icon.color }}" | |
ng-attr-x="{{ ::-(vm.iconSize/2) }}" | |
ng-attr-y="{{ ::-(vm.iconSize/2) }}"></rect> | |
<text ng-attr-x="0" ng-attr-y="5" | |
text-anchor="middle" | |
font-family="Verdana" | |
font-size="20"> | |
{{ $index }} | |
</text> | |
</g> | |
</g> | |
</svg> | |
<button ng-click='vm.addIcon()'>Add</button> | |
<button ng-click='vm.removeIcon()'>Remove</button> | |
<input type="number" ng-model="vm.activeIndex"/> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var app = angular.module('app', []); | |
class MyCtrl { | |
constructor($scope, $element, $timeout) { | |
this.circleRotate = 0; | |
this.circleRadius = 300; | |
this.icons = []; | |
this.iconSize = 60; | |
this.activeIndex = 0; | |
this.dragDir = 0; // dragDir should actually be dragAngle | |
this.scope = $scope; | |
this.timeout = $timeout; | |
var iconCount = 9; | |
for(var i = 0; i < iconCount; i++) { | |
this.addIcon(); | |
} | |
$scope.$watch(() => this.icons.length, () => { | |
this.iconRotate = 360/this.icons.length; | |
}); | |
$scope.$watchGroup([ | |
() => this.iconRotate, | |
() => this.activeIndex, | |
() => this.dragDir | |
], () => { | |
// console.log(this.activeIndex, this.iconRotate, this.dragDir); | |
this.circleRotate = this.activeIndex * this.iconRotate + this.dragDir; | |
}); | |
this.registerDrag($element[0]); | |
} | |
registerDrag(container) { | |
var self = this; | |
function mousedown(e) { | |
document.body.addEventListener('mousemove', mousemove); | |
document.body.addEventListener('mouseup', mouseup); | |
self.dragStart = { | |
x: e.x, y: e.y | |
}; | |
} | |
function mousemove(e) { | |
self.scope.$apply(() => { | |
// need to get the origin of the rotation | |
// http://stackoverflow.com/questions/10298658/mouse-position-inside-autoscaled-svg | |
var x = Math.atan2(e.x - self.dragStart.x, e.y - self.dragStart.y); | |
x = x * (180 / Math.PI); | |
console.log('x', x); | |
self.dragDir = self.dragStart.x - e.x; | |
// console.log('dragDir', self.dragDir); | |
}); | |
} | |
function mouseup(e) { | |
document.body.removeEventListener('mousemove', mousemove); | |
document.body.removeEventListener('mouseup', mouseup); | |
self.scope.$apply(() => { | |
// set circle rot 0-360 range | |
self.circleRotate = (self.circleRotate + 360) % 360; | |
// if circle rot was negative we want to avoid a 360 deg spinning | |
// let the css adjust (without transition duration set) | |
self.timeout(() => { | |
delete self.dragStart; | |
self.dragDir = 0; | |
// map active index (rot/iconRotate) | |
self.activeIndex = Math.round(self.circleRotate / self.iconRotate); | |
// console.log(self.activeIndex); | |
}); | |
}); | |
} | |
container.addEventListener('mousedown', mousedown); | |
} | |
addIcon() { | |
var iconColor = '#EB6A05'; | |
this.icons.push({ | |
color: iconColor | |
}); | |
} | |
removeIcon() { | |
this.icons.length -= 1; | |
} | |
} | |
app.controller('MyCtrl', MyCtrl); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.container { | |
padding: 20px; | |
margin-left: auto; | |
margin-right: auto; | |
width: 300px; | |
} | |
svg { | |
border: 1px solid black; | |
} | |
svg text { | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
-khtml-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none; | |
} | |
#circle { | |
transition: all 1s; | |
} | |
#circle.dragging { | |
transition: none; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment