I was trying to come up with some JS (pure JS) code making the indicator move around the circle while the pin is being moved (as if it was a speedometer), but I failed. I tried to use offsets, count the offsetTop etc., but it doesn't work. Can anyone help me out here, please?
If there is some other way to do this without using some extra libraries (for example, just using the css options), let me know - I'll be really grateful as it's really important for me to understand the concept here!
'use strict';
let firstIndicator = document.querySelector('.indicator');
let pinLevel = document.querySelector('.effect-level__pin');
let effectLevelLine = document.querySelector('.effect-level__line');
let effectLevelDepth = document.querySelector('.effect-level__depth');
let changeOverlay = function (percentage) {
pinLevel.style.left = percentage + '%';
effectLevelDepth.style.width = percentage + '%';
};
pinLevel.addEventListener('mousedown', function (evt) {
evt.preventDefault();
let startX = evt.clientX;
let startLevelDepthWidth = effectLevelDepth.offsetWidth;
let clickedPercentageLevel = startLevelDepthWidth / effectLevelLine.offsetWidth * 100;
changeOverlay(clickedPercentageLevel);
let onMouseMove = function (moveEvt) {
moveEvt.preventDefault();
let shift = moveEvt.clientX - startX;
let levelWidth = startLevelDepthWidth + shift;
let movedPercentageLevel = levelWidth / effectLevelLine.offsetWidth * 100;
movedPercentageLevel = Math.max(0, movedPercentageLevel);
movedPercentageLevel = Math.min(100, movedPercentageLevel);
changeOverlay(movedPercentageLevel);
firstIndicator.style.top = (firstIndicator.offsetHeight * 3) - (movedPercentageLevel / 100) + 'px';
firstIndicator.style.transform = 'rotate('+ (52 + movedPercentageLevel * 2.4) + 'deg' + ')';
};
let onMouseUp = function (upEvt) {
upEvt.preventDefault();
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
.circle {
margin: 0 auto;
margin-top: 50px;
width: 150px;
height: 150px;
border: 1px solid black;
border-radius: 50%
}
.indicator {
position: relative;
}
.indicator svg {
position: absolute;
top: -100px;
transform: rotate(82deg);
left: 108px;
}
.effect-level {
position: absolute;
bottom: -30px;
left: 50%;
width: 495px;
height: 33px;
font-size: 12px;
line-height: 42px;
text-align: center;
color: black;
white-space: nowrap;
background-color: #ffffff;
border: none;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
.effect-level__value {
display: none;
}
.effect-level__line {
position: absolute;
top: 50%;
right: 20px;
left: 20px;
height: 5px;
font-size: 0;
background-color: rgba(0, 0, 0, 0.2);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.effect-level__pin {
position: absolute;
top: 50%;
left: 0%;
z-index: 1;
width: 18px;
height: 18px;
margin: -9px 0 0;
background-color: #fff;
border-radius: 50%;
border: 1px solid #323232;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
cursor: move;
}
.effect-level__depth {
position: absolute;
width: 0%;
height: 100%;
background-color: #323232;
}
<div class="circle"></div>
<div class="indicator">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="337.0744522647706 304.4241607573019 28.925547735229372 104" width="24.93" height="100"><defs><path d="" id="c6VRx4235S"></path><path d="M348.07 305.42L338.07 405.42" id="f84HmfmJk"></path><path d="M340.01 305.42L338.07 403.88" id="azVXtGrDR"></path></defs><g><g><g><use xlink:href="#c6VRx4235S" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#f84HmfmJk" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#azVXtGrDR" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g></g>
</svg>
</div>
<fieldset class="effect-level">
<input class="effect-level__value" type="number" name="effect-level" value="0">
<div class="effect-level__line">
<div class="effect-level__pin" tabindex="0">Кнопка изменения эффекта </div>
<div class="effect-level__depth">Глубина эффекта</div>
</div>
</fieldset>