Home > Blockchain >  Can you rotate an element using a input value?
Can you rotate an element using a input value?

Time:11-21

I want to use the Input[type=range] to rotate the red circle with the id of outer, I tried to select the circle's style, then transform, and that is equal to the value of the input, but it has to be between the parenthesis in rotateZ(), which is a string. Here is my code;

var value = document.getElementById("slider").value;
        console.log(value);
        document.getElementById("inner").style.transform = document.getElementById("slider").value;
 body {
        display:flex;
        align-items:center;
        justify-content:center;
    }
    #outer {
        background:red;
        height:20vw;
        position:relative;
        border-radius:50%;
        width:20vw;
        display:flex;
        justify-content:center;
    }
    #inner {
        transform:translateY(10%);
        border-bottom-left-radius:100%;
        border-bottom-right-radius:100%;
        position:absolute;
        bottom:0;
        background:darkgreen;
        width:10%;
        height:50%;
    }
    <div id="outer"><div id="inner"></div></div>
    <input min="0" max="360" type="range" id="slider">
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

But it doesn't work. I need to somehow put the value between parenthesis.

CodePudding user response:

Two things, first of all as you said you can't just set it to a number, but need to set it to a string, here using a template literal. Secondly, since you want the rotation linked to the slider, you'll need to add a listener to the slider in this case listening for an input event which gives the most immediate feedback.

var slider = document.getElementById("slider");

slider.addEventListener('input', () => {
  document.getElementById("outer").style.transform = `rotate(${slider.value}deg)`;
});
body {
        display:flex;
        align-items:center;
        justify-content:center;
    }
    #outer {
        background:red;
        height:20vw;
        position:relative;
        border-radius:50%;
        width:20vw;
        display:flex;
        justify-content:center;
    }
    #inner {
        transform:translateY(10%);
        border-bottom-left-radius:100%;
        border-bottom-right-radius:100%;
        position:absolute;
        bottom:0;
        background:darkgreen;
        width:10%;
        height:50%;
    }
<div id="outer">
  <div id="inner">
  </div>
</div>

<input min="0" max="360" type="range" id="slider">
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You need to provide a string that conforms to the CSS property, such as rotateZ(180deg). Mind the deg unit, because it will not work without one.

If you want to translate the hand at the same time, you need to put that into the string as well since there is only one transform property and you will overwrite it. The order is important here: first rotate, then translate, or the result will change. Not to forget, you need to move the transform-origin as well (see example).

Add a listener to the slider's input event, otherwise the value will only be applied once when the script loads. Best use template literals with backticks (`rotateZ(${value}) translate(10%)`) since it is more convenient, but you can also add the strings together ('rotateZ(' value 'deg) translate(10%)').

Edit: Or you can just rotate the outer circle like in the other answer, saves you accounting for the translate. However, if you also want to add something like numbers of a clock to the circle, they would be rotated as well in that case.

var slider = document.getElementById("slider"),
    hand = document.getElementById("inner");

slider.addEventListener('input', function() {
  hand.style.transform = `rotateZ(${this.value}deg) translateY(10%)`;
});
body {
  display:flex;
  align-items:center;
  justify-content:center;
}

#outer {
  background:red;
  height:20vw;
  position:relative;
  border-radius:50%;
  width:20vw;
  display:flex;
  justify-content:center;
}

#inner {
  transform: rotateZ(180deg) translateY(10%);
  transform-origin: top center;
  border-bottom-left-radius:100%;
  border-bottom-right-radius:100%;
  position:absolute;
  bottom:0;
  background:darkgreen;
  width:10%;
  height:50%;
}
<div id="outer"><div id="inner"></div></div>
<input min="0" max="360" type="range" id="slider">
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

const inputValue = document.querySelector('#slider')
const inner = document.querySelector('.inner')
const rotate = document.querySelector('.rotate')
var root = document.querySelector(':root');
let oldVariable = 0
// Listen to any change in the progress bar
inputValue.addEventListener("change", function(){
  const newVariable = inputValue.value
  root.style.setProperty('--my-start-deg',`${oldVariable}deg`);
   root.style.setProperty('--my-end-deg', `${newVariable}deg`);
  inner.classList.remove("rotate");
  // Reset CSS Keyframes
  void inner.offsetWidth;
  
  inner.classList.add("rotate");
  oldVariable = inputValue.value;
});
:root {
    --my-start-deg: 0deg;
    --my-end-deg: 0deg;
}

#frame{
  position: relative;
  height: 200px;
  width: 200px;
  margin: 100px;
  padding: 10px;
  border:10px solid #000;
  border-radius:100%;
  top:50%;
  left:50%;
  transform:translate(-50%);
   transiton:all 3s;
}

.inner{
 position: absolute;
  top:50%;
  left:50%;
  transform:translate(-50%);
  height:100px;
  width:2px;
  border-radius:50%;
  background-color: red;
}

.rotate {
   transform: rotate(0deg);
  transform-origin: 0% 0%;
  animation: progressBar 3s;
  animation-fill-mode:forwards;
  transiton:all 3s;
  
}


@keyframes progressBar {
    0% {  transform: rotate(var(--my-start-deg)); }
    100% {  transform: rotate(var(--my-end-deg)); }
}
<input min="0" max="360" value="0" type="range" id="slider">
<div id="frame">
  <div class="inner rotate"></div>
</div>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related