-
-
Save McNull/ea3e87e7022fef2878e0c208e85b71a8 to your computer and use it in GitHub Desktop.
SVG ring 4
This file contains 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 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 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 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