JSFiddle - React, Tailwind, and code Playground
by kzima
HTML
<script src="//cdn.jsdelivr.net/snap.svg/0.2.0/snap.svg-min.js"></script>
<svg version="1.1" id="test" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="750px" viewBox="0 0 500 750" enable-background="new 0 0 500 750" xml:space="preserve">
<g id="plot-group">
<path id="compass" fill="#68A192" d="M250,175.886c-109.967,0-199.114,89.147-199.114,199.114
c0,109.969,89.147,199.114,199.114,199.114c109.969,0,199.114-89.146,199.114-199.114C449.114,265.033,359.969,175.886,250,175.886
z M250,184c3.592,0,6.5,2.908,6.5,6.5s-2.908,6.5-6.5,6.5s-6.5-2.908-6.5-6.5S246.408,184,250,184z M250,525
c-82.843,0-150-67.157-150-150s67.157-150,150-150s150,67.157,150,150S332.843,525,250,525z"/>
<circle id="plot-area" fill="#FFFFFF" style="opacity:0" cx="250" cy="375" r="150"/>
</g>
<circle id="handle" fill="red" cx="250" cy="275" r="15"/>
</svg>
JavaScript
function dragCompass( dx, dy, x, y, e ) {
var a = Snap.angle( xStart, yStart, e.offsetX, e.offsetY ) - 0;
var pgTran = handle.data( 'origTransform' );
handle.transform( pgTran + 'R' + [a,xStart,yStart] );
plotGroup.transform(handle.matrix)
lastAngle = a;
}
function startCompass( x, y, e ) {
handle.data( 'origTransform', handle.transform().local );
startAngle = Snap.angle( xStart, yStart, e.offsetX, e.offsetY );
/* lastAngle = angle */;
}
function stopCompass() {
/* angle = lastAngle */;
}
function plotDot( e ) {
var a = Snap.angle( xStart, yStart, e.offsetX, e.offsetY );
var r = 'r' + [a, e.offsetX, e.offsetY];
var attr = {
opacity: 1,
cx: e.offsetX,
cy: e.offsetY
};
dot.attr( attr ).transform( r );
}
var s = Snap('#test');
plotGroup = s.select('#plot-group');
trueIndex = s.select('#true-index');
compass = s.select("#compass");
handle = s.select("#handle");
plotArea = s.select('#plot-area');
dot = s.select("#plot-dot");
xStart = compass.getBBox().cx;
yStart = compass.getBBox().cy;
yShift = 0;
angle = 0;
lastAngle = 0;
startAngle = 0;
plotArea.click( plotDot );
handle.drag( dragCompass, startCompass, stopCompass );