<div class="box">
  <div class="box-inner">
    <div class="box-main">
      <div class="elements-holder">
        <div class="elements">
          <div class="elem-1"></div>
          <div class="elem-2"></div>
          <div class="origin">
            <div class="origin-anchor"></div>
          </div>
        </div>
        <code>
          transform: rotate(<span data-digit-id="rotate">0deg</span>);<br/>
          transform-origin: <span data-digit-id="origin">center</span>;
        </code>
      </div>
    </div>
    <div class="controller">
      <div class="controller-item">
        <div class="indicator">
          <label for="rotate">Rotation:</label>
          <span class="digit" data-digit-id="rotate">0deg</span>
        </div>
        <div class="slider">
          <input type="range" id="rotate" min="-360" max="360" step="1" value="0" oninput="showVal(this.value, 'rotate', 'deg')" onchange="showVal(this.value, 'rotate', 'deg')">
        </div>
      </div>
      <div class="controller-item">
        <div class="selector">
          <label for="origin">Transform Origin:</label>
          <select name="origin" id="origin" onchange="showOrigin(this.value); showVal(this.value, 'origin', false)">
            <option value="center" data-origin-left="50%" data-origin-top="50%">center (default)</option>
            <option value="left top" data-origin-left="0" data-origin-top="0">left top</option>
            <option value="25px bottom" data-origin-left="25px" data-origin-top="100%">25px bottom</option>
            <option value="0% 150%" data-origin-left="0%" data-origin-top="150%">0% 150%</option>
          </select>
        </div>
      </div>
    </div>
  </div>
</div>
@import url('https://fonts.googleapis.com/css2?family=League+Spartan&display=swap');
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@500&display=swap');

:root {
  --font-family-mono: 'League Mono', monospace;
  --font-family-dm: 'DM Sans', sans-serif;
  --rotate: 0deg;
  --origin-left: 50%;
  --origin-top: 50%;
  --transform-origin: center;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.box {
  background: #151f28;
  max-width: 750px;
  margin: 20px auto;
  border-radius: 8px;
  padding: 16px 32px;
  font-size: 16px;
}
.box-inner {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.box-main {
  padding: 50px 32px 32px;
  background: white;
  border-radius: 4px;
  min-height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.elements-holder {
  min-width: 475px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 50px;
}
.elements {
  position: relative;
  width: 80px;
  height: 80px;
}
.elem-1 {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  border: 4px dashed #9295a0;
}
.elem-2 {
  position: relative;
  width: 100%;
  height: 100%;
  background: #4433ff;
  opacity: 0.8;
  transform: rotate(var(--rotate));
  transform-origin: var(--transform-origin);
}
.origin {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  transform: translate(-8px, -8px);
}
.origin-anchor {
  position: absolute;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 4px solid black;
  background: white;
  left: var(--origin-left);
  top: var(--origin-top);
}
code {
  font-size: 1rem;
  font-family: var(--font-family-mono);
  background: #e1e3ea;
  padding: 6px 8px;
  border-radius: 4px;
  text-align: left;
  line-height: 1.5;
}
.controller {
  display: grid;
  gap: 32px;
  grid-template-columns: 1fr 1fr;
  color: white;
  font-family: var(--font-family-dm);
  font-weight: 500;
}
.indicator {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}
.digit {
  font-size: 0.875em;
}
.slider {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 1.625rem;
}
.slider input {
  background: transparent;
  appearance: none;
}
.slider input::-webkit-slider-runnable-track {
  height: 4px;
  background-color: #5c6670;
}
.slider input::-webkit-slider-thumb {
  appearance: none;
  height: 16px;
  width: 16px;
  border-radius: 50px;
  background: #d9e0e8;
  cursor: grab;
  transform: translateY(-6px);
}
.selector {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.selector label {
  margin-bottom: 10px;
}
.selector select {
  color: #d9e0e8;
  background-color: #2b333b;
  font-size: 1rem;
  padding: 8px 52px 8px 12px;
  border-radius: 8px;
  outline: none;
}
function showVal(val, id, u){
  let unit = u ? u : '';
  let _deg = `${val}${unit}`
  $(`[data-digit-id=${id}]`).text(_deg);
  $(':root').css(`--${id}`, _deg);
};
function showOrigin(val){
  $(':root').css({
    '--origin-left': $(`[value="${val}"]`).attr('data-origin-left'),
    '--origin-top': $(`[value="${val}"]`).attr('data-origin-top'),
    '--transform-origin': val
  });
};

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js