JSFiddle - React, Tailwind, and code Playground
by turiyag
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<div class="container">
<h2>
Pie Wheels
</h2>
<div class="row black-bg">
<div class="dial dial-1"></div>
<div class="dial dial-3"></div>
<div class="dial dial-1"></div>
</div>
<div class="row">
<div class="dial dial-2"></div>
<div class="dial dial-3"></div>
<div class="dial dial-2"></div>
</div>
<div class="row">
<div class="dial dial-2"></div>
<div class="dial dial-3"></div>
<div class="dial dial-2"></div>
</div>
<div class="row">
<p id="log">
</p>
</div>
</div>
SCSS
* { box-sizing: border-box; }
.pie-container {
width: 320px;
max-width: 320px;
margin: 10% auto;
box-sizing: border-box;
border: 1px solid black;
}
.black-bg {
background: black;
}
.dial {
width: 144px;
height: 144px;
background: url('https://edgemontgeek.com/ziggurat/img/Ziggurat-rotiles-1.png');
/* border-radius: 50%; */
/* border: 20px solid black; */
/* border-color: red green blue yellow; */
/* box-sizing: border-box; */
float: left;
}
.dial-1 {
background: url('https://edgemontgeek.com/ziggurat/img/Ziggurat-rotiles-1.png');
}
.dial-2 {
background: url('https://edgemontgeek.com/ziggurat/img/Ziggurat-rotiles-2.png');
}
.dial-3 {
background: url('https://edgemontgeek.com/ziggurat/img/Ziggurat-rotiles-3.png');
}
JavaScript
function get_degrees(mouse_x, mouse_y, center_x, center_y) {
const radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
const degrees = Math.round((radians * (180 / Math.PI) * -1) + 100);
return degrees;
}
function nearest_90(degrees) {
let clean_degrees = degrees % 360
if (clean_degrees < 0) clean_degrees += 360
if (clean_degrees <= 45) return 0
else if (clean_degrees <= 45 + 90) return 90
else if (clean_degrees <= 45 + 180) return 180
else if (clean_degrees <= 45 + 270) return 270
else {
return 0
}
}
const INITIAL_ROTATIONS = [
180,90,0,
0,0,180,
180,90,0
];
(function($) {
'use strict';
/**
* Dial element
* @var object
*/
$('.dial').each(function(idx) {
const $dial = $(this);
/**
* Calculate mouse rotation relative to $dial center
* @param int mouse_x
* @param int mouse_y
*/
const radius = $dial.outerWidth() / 2;
const center_x = $dial.offset().left + radius;
const center_y = $dial.offset().top + radius;
let curr_degrees = INITIAL_ROTATIONS[idx];
$dial.css('transform', 'rotate(' + curr_degrees + 'deg)');
$dial.on('mousedown', function(event) {
// Calculate the mouse position in degrees
const click_degrees = get_degrees(event.pageX, event.pageY, center_x, center_y);
const pre_click_degrees = curr_degrees;
$(document).bind('mousemove', click_degrees, function(event) {
// Calculate the mouse move position, removing starting point
const degrees = get_degrees(event.pageX, event.pageY, center_x, center_y) - click_degrees;
$("#log").text(`center (x,y): (${center_x},${center_y}, page (x,y): ${event.pageX}, ${event.pageY}, click_degrees: ${click_degrees}, degrees: ${degrees}`)
curr_degrees = pre_click_degrees + degrees
$dial.css('transform', 'rotate(' + curr_degrees + 'deg)');
});
$(document).bind('mouseup', click_degrees, function(event) {
$(document).unbind('mousemove');
...