BLOGTOP

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » BLOGTOP » Уголок wap мастера » JavaScript » Рандомайзер цвета в формате рулетки


Рандомайзер цвета в формате рулетки

Сообщений 1 страница 2 из 2

1

[html]
<style>
/* import font(s) */
@import url("https://fonts.googleapis.com/css?family=Alegreya+Sans+SC:400,900");

/* detail root variables
--color-theme cascades to most html elements, and will be later updated in JavaScript
*/
:root {
  --font: "Alegreya Sans SC", sans-serif;
  --color-bg: #000b14;
  --color-theme: #70a9fe;
}

/* heading centered atop the page */
h17 {
  text-align: center;
  margin: 1rem 0 0;
  font-size: 3rem;
  transition: all 0.25s ease-in-out;
display: block;
position: absolute;
right: 110px;
top: 160px;
border: 3px solid currentColor;
padding: 10px;
background: #fff;
color: var(--color-theme);
}
/* shown/hidden through an dedicated class */
h17.isHidden {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1rem) scale(0);
}

/* wheel positioned to the left of the page, and occupying 50% of whichever dimension is the biggest */
svg#wheel {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 500px;
  height: 500px;
}

/* arrow positioned to the right of the wheel, and pointing at the very middle section */
svg#pin {
  position: absolute;
  left: 500px;
  width: calc(50vmax / 25);
  height: calc(50vmax / 25);
  top: 50%;
  transform: translateY(-50%);
  fill: var(--color-theme);
}

/* instructions displayed on the right side, in a single column layout */
.instructions {
  min-height: 600px;
  color: var(--color-theme);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  padding: 1rem;
}
.instructions h2 {
  font-size: 1rem;
  letter-spacing: 0.1rem;
  position: relative;
}
/* beside a silly exclamation point add a simple word in the middle of the sentence hinting at the innocent nature of the project */
.instructions h2:after {
  content: "!";
}
.instructions h2:before {
  position: absolute;
  content: "suspicious";
  font-size: 0.75rem;
  opacity: 0.6;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) rotate(-12deg);
}

.instructions button {
  margin-top: 1rem;
  padding: 0.25rem 0.75rem;
  font-size: 1.55rem;
  font-family: inherit;
  color: inherit;
  border: none;
  border-radius: 10px;
  box-shadow: 0 0 0 2px currentColor;
  background: var(--color-bg);
  /* transition for a simple hover and active state */
  transition: all 0.5s ease-out;
}
.instructions button:hover {
  box-shadow: 0 0 0 1px var(--color-bg), 0 0 0 3px currentColor,
    0 0 0 5px var(--color-bg), 0 0 0 7px currentColor;
}
.instructions button:active {
  box-shadow: 0 0 0 2px currentColor, 0 0 0 4px var(--color-bg),
    0 0 0 6px currentColor;
  transform: scale(0.95) translateY(0.1rem);
}
/* cursor customized to grab, and not allowed when the wheel is spinning (class added in JS) */
.instructions button,
svg#pin {
  cursor: grab;
}
.instructions button.isSpinning,
svg#pin.isSpinning {
  cursor: not-allowed;
}
/*
animation for the pin, to have it soundly move up and down alongside the spinning wheel
the duration of the animation is customized in JS to have it run a certain number of times
*/
@keyframes pinWheel {
  33% {
    transform: translateY(-50%) rotate(-10deg);
  }
  67% {
    transform: translateY(-50%) rotate(10deg);
  }
}

</style>
<script>
// target the SVG and the pin right next to it
const containerSlices = document.querySelector('g#slices');
const pin = document.querySelector('svg#pin');

// immediately add simple dots around the wheel
for (let i = 0; i < 48; i += 1) {
  const transform = `rotate(${360 / 48 * i}), translate(0 -49.5), rotate(${-360 / 48 * i})`;
  const dot = `<circle r="0.5" cx="50" cy="50" fill="currentColor" transform="${transform}"/>`;
  containerSlices.innerHTML += dot;
}

// target the heading and the button
const heading = document.querySelector('h17');
const spinButton = document.querySelector('button');

// variable updated for the timeout
let timeoutID = 0;

// utility functions returning a random integer in a range and a random hex value
const randomInt = (min = 0, max = 16) => Math.floor(Math.random() * (max - min) + min);
const randomHex = () => randomInt().toString(16);

// object used throughout the script, describing the colors and 3 particular rotation values
// the idea is to include the three slices aroud the wheel and have the arrow point always at one of them
const suspicious = [
  {
    rotation: 45,
    color: 'A2CCB6'
  },
  {
    rotation: 180,
    color: 'FCEEB5'
  },
  {
    rotation: 315,
    color: 'EE786E'
  }
];

// add a random fill color to the circle behind the slices
let randomFill = '';
for (let i = 0; i < 6; i += 1) {
  randomFill += randomHex();
}
document.querySelector('svg circle#slice').style.fill = randomFill;

// create the slices, 24 in total, using a bit of trigonometry to compute the appropriate arc coordinates
for (let i = 360; i > 0; i -= 15) {
  // values for the path element
  const xCoor = 50 + Math.sin(i * Math.PI / 180) * 47;
  const yCoor = 50 - Math.cos(i * Math.PI / 180) * 47;
  const flags = i > 180 ? '0 1 1' : '0 0 1';

  // initialize a variable for the fill color
  let fill = '';
  // create six random hex values for the fill color
  // ! the look might be rather jarring
  for (let j = 0; j < 6; j += 1) {
    fill += randomHex();
  }
  // if the de-cremented variable matches the arbitrary rotation value of one of the objects, find the specific object
  const suspect = suspicious.find(pairing => pairing.rotation === i);
  // if existing, substitute the random hex with the value specified in said object
  if (suspect) {
    fill = suspect.color;
  }

  // create the path element and append it to the SVG container
  const path = `
    <path d="M 50 50 L 50 3 A 47 47 ${flags} ${xCoor} ${yCoor}" fill=#${fill} />
  `;
  containerSlices.innerHTML += path;
}

// function spinning the wheel
function spinWheel() {
  // remove the event listener from the button and the wheel, to avoid running the function twice at the same time
  spinButton.removeEventListener('click', spinWheel);
  pin.removeEventListener('click', spinWheel);

  // immediately hide the heading showing the matching color
  heading.classList.add('isHidden');
  // add a class to the pin and the button to show how they should not be clicked
  pin.classList.add('isSpinning');
  spinButton.classList.add('isSpinning');

  // create variables for the duration of the rotation, as whell as the number of rotations achieved by the wheel
  const randomDuration = randomInt(4, 10);
  const randomRotate = randomInt(10, 20);
  // crate a variable to pick from one of the objects at random
  const randomSuspect = randomInt(0, 3);

  // apply the transition and the transform properties
  containerSlices.style.transformOrigin = '50%';
  containerSlices.style.transition = `transform ${randomDuration}s ease-out`;
  /* for the rotation, beside an arbitrary x360 rotation, remember to
  - add 90 to match the position of the arrow (to the very right of the wheel)
  - subtract the rotation of the slices
  - add up to a slice as to have the arrow point within the slice's boundaries
  */
  containerSlices.style.transform = `rotate(${randomRotate * 360 - suspicious[randomSuspect].rotation + 90 + randomInt(0, 360 / 24)}deg)`;

  pin.style.animation = `pinWheel ${randomDuration / 10}s 10 ease-in-out`;

  // after the time allocated for the rotation show the heading with the "random" color, update the custom property with its value
  timeoutID = setTimeout(() => {
    heading.textContent = `#${suspicious[randomSuspect].color}`;
    heading.classList.remove('isHidden');
    pin.style.animation = '';
    document.documentElement.style.setProperty('--color-theme', `#${suspicious[randomSuspect].color}`);

    // remove the class on the pin and button showing the forbidden cursor
    pin.classList.remove('isSpinning');
    spinButton.classList.remove('isSpinning');

    // reset the event listener on the button and the pin
    spinButton.addEventListener('click', spinWheel);
    pin.addEventListener('click', spinWheel);

    // clear the interval and set the boolean back to false
    clearInterval(timeoutID);
  }, randomDuration * 1000);
}

// attach a click event listener on the button, at which point call the spinWheel function
spinButton.addEventListener('click', spinWheel);

// call the same function when pressing the pin
pin.addEventListener('click', spinWheel);

</script>

<!--
  project's structure
  - svg for the color wheel (consisting of circle elements, and a group in which the slices are added)
  - svg for the arrow pointing at the selected color (positioned to the right of the circle)
  - heading in which to show the color selected through the wheel (hidden by default)
  - container for the simple instructions and the button spinning the wheel
-->

<svg id="wheel" viewBox="0 0 100 100">
  <circle
    cx="50"
    cy="50"
    r="48"
    fill="none"
    stroke-width="1"
    stroke="currentColor"
  />
<!-- add an id to the underlying circle as this depicts the final slice, and as to add a random color -->
  <circle id="slice" cx="50" cy="50" r="47" fill="#001C34" />
  <g id="slices"></g>
</svg>
<svg id="pin" viewBox="0 0 50 50"><path d="M 0 25 L 50 0 V 50" /></svg>

<h17 class="isHidden" style="user-select: all;">#ffffff00</h17>

<div class="instructions">
  <h2>Spin that color <span>wheel</span></h2>
  <button>Spin!</button>
</div>
[/html]

Код:
[html]
<style>
/* import font(s) */
@import url("https://fonts.googleapis.com/css?family=Alegreya+Sans+SC:400,900");

/* detail root variables
--color-theme cascades to most html elements, and will be later updated in JavaScript
*/
:root {
  --font: "Alegreya Sans SC", sans-serif;
  --color-bg: #000b14;
  --color-theme: #70a9fe;
}

/* heading centered atop the page */
h17 {
  text-align: center;
  margin: 1rem 0 0;
  font-size: 3rem;
  transition: all 0.25s ease-in-out;
display: block;
position: absolute;
right: 110px;
top: 160px;
border: 3px solid currentColor;
padding: 10px;
background: #fff;
color: var(--color-theme);
}
/* shown/hidden through an dedicated class */
h17.isHidden {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1rem) scale(0);
}

/* wheel positioned to the left of the page, and occupying 50% of whichever dimension is the biggest */
svg#wheel {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 500px;
  height: 500px;
}

/* arrow positioned to the right of the wheel, and pointing at the very middle section */
svg#pin {
  position: absolute;
  left: 500px;
  width: calc(50vmax / 25);
  height: calc(50vmax / 25);
  top: 50%;
  transform: translateY(-50%);
  fill: var(--color-theme);
}

/* instructions displayed on the right side, in a single column layout */
.instructions {
  min-height: 600px;
  color: var(--color-theme);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  padding: 1rem;
}
.instructions h2 {
  font-size: 1rem;
  letter-spacing: 0.1rem;
  position: relative;
}
/* beside a silly exclamation point add a simple word in the middle of the sentence hinting at the innocent nature of the project */
.instructions h2:after {
  content: "!";
}
.instructions h2:before {
  position: absolute;
  content: "suspicious";
  font-size: 0.75rem;
  opacity: 0.6;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) rotate(-12deg);
}

.instructions button {
  margin-top: 1rem;
  padding: 0.25rem 0.75rem;
  font-size: 1.55rem;
  font-family: inherit;
  color: inherit;
  border: none;
  border-radius: 10px;
  box-shadow: 0 0 0 2px currentColor;
  background: var(--color-bg);
  /* transition for a simple hover and active state */
  transition: all 0.5s ease-out;
}
.instructions button:hover {
  box-shadow: 0 0 0 1px var(--color-bg), 0 0 0 3px currentColor,
    0 0 0 5px var(--color-bg), 0 0 0 7px currentColor;
}
.instructions button:active {
  box-shadow: 0 0 0 2px currentColor, 0 0 0 4px var(--color-bg),
    0 0 0 6px currentColor;
  transform: scale(0.95) translateY(0.1rem);
}
/* cursor customized to grab, and not allowed when the wheel is spinning (class added in JS) */
.instructions button,
svg#pin {
  cursor: grab;
}
.instructions button.isSpinning,
svg#pin.isSpinning {
  cursor: not-allowed;
}
/*
animation for the pin, to have it soundly move up and down alongside the spinning wheel
the duration of the animation is customized in JS to have it run a certain number of times
*/
@keyframes pinWheel {
  33% {
    transform: translateY(-50%) rotate(-10deg);
  }
  67% {
    transform: translateY(-50%) rotate(10deg);
  }
}

</style>
<script>
// target the SVG and the pin right next to it
const containerSlices = document.querySelector('g#slices');
const pin = document.querySelector('svg#pin');

// immediately add simple dots around the wheel
for (let i = 0; i < 48; i += 1) {
  const transform = `rotate(${360 / 48 * i}), translate(0 -49.5), rotate(${-360 / 48 * i})`;
  const dot = `<circle r="0.5" cx="50" cy="50" fill="currentColor" transform="${transform}"/>`;
  containerSlices.innerHTML += dot;
}

// target the heading and the button
const heading = document.querySelector('h17');
const spinButton = document.querySelector('button');

// variable updated for the timeout
let timeoutID = 0;

// utility functions returning a random integer in a range and a random hex value
const randomInt = (min = 0, max = 16) => Math.floor(Math.random() * (max - min) + min);
const randomHex = () => randomInt().toString(16);

// object used throughout the script, describing the colors and 3 particular rotation values
// the idea is to include the three slices aroud the wheel and have the arrow point always at one of them
const suspicious = [
  {
    rotation: 45,
    color: 'A2CCB6'
  },
  {
    rotation: 180,
    color: 'FCEEB5'
  },
  {
    rotation: 315,
    color: 'EE786E'
  }
];

// add a random fill color to the circle behind the slices
let randomFill = '';
for (let i = 0; i < 6; i += 1) {
  randomFill += randomHex();
}
document.querySelector('svg circle#slice').style.fill = randomFill;

// create the slices, 24 in total, using a bit of trigonometry to compute the appropriate arc coordinates
for (let i = 360; i > 0; i -= 15) {
  // values for the path element
  const xCoor = 50 + Math.sin(i * Math.PI / 180) * 47;
  const yCoor = 50 - Math.cos(i * Math.PI / 180) * 47;
  const flags = i > 180 ? '0 1 1' : '0 0 1';

  // initialize a variable for the fill color
  let fill = '';
  // create six random hex values for the fill color
  // ! the look might be rather jarring
  for (let j = 0; j < 6; j += 1) {
    fill += randomHex();
  }
  // if the de-cremented variable matches the arbitrary rotation value of one of the objects, find the specific object
  const suspect = suspicious.find(pairing => pairing.rotation === i);
  // if existing, substitute the random hex with the value specified in said object
  if (suspect) {
    fill = suspect.color;
  }

  // create the path element and append it to the SVG container
  const path = `
    <path d="M 50 50 L 50 3 A 47 47 ${flags} ${xCoor} ${yCoor}" fill=#${fill} />
  `;
  containerSlices.innerHTML += path;
}

// function spinning the wheel
function spinWheel() {
  // remove the event listener from the button and the wheel, to avoid running the function twice at the same time
  spinButton.removeEventListener('click', spinWheel);
  pin.removeEventListener('click', spinWheel);

  // immediately hide the heading showing the matching color
  heading.classList.add('isHidden');
  // add a class to the pin and the button to show how they should not be clicked
  pin.classList.add('isSpinning');
  spinButton.classList.add('isSpinning');

  // create variables for the duration of the rotation, as whell as the number of rotations achieved by the wheel
  const randomDuration = randomInt(4, 10);
  const randomRotate = randomInt(10, 20);
  // crate a variable to pick from one of the objects at random
  const randomSuspect = randomInt(0, 3);

  // apply the transition and the transform properties
  containerSlices.style.transformOrigin = '50%';
  containerSlices.style.transition = `transform ${randomDuration}s ease-out`;
  /* for the rotation, beside an arbitrary x360 rotation, remember to
  - add 90 to match the position of the arrow (to the very right of the wheel)
  - subtract the rotation of the slices
  - add up to a slice as to have the arrow point within the slice's boundaries
  */
  containerSlices.style.transform = `rotate(${randomRotate * 360 - suspicious[randomSuspect].rotation + 90 + randomInt(0, 360 / 24)}deg)`;

  pin.style.animation = `pinWheel ${randomDuration / 10}s 10 ease-in-out`;

  // after the time allocated for the rotation show the heading with the "random" color, update the custom property with its value
  timeoutID = setTimeout(() => {
    heading.textContent = `#${suspicious[randomSuspect].color}`;
    heading.classList.remove('isHidden');
    pin.style.animation = '';
    document.documentElement.style.setProperty('--color-theme', `#${suspicious[randomSuspect].color}`);

    // remove the class on the pin and button showing the forbidden cursor
    pin.classList.remove('isSpinning');
    spinButton.classList.remove('isSpinning');

    // reset the event listener on the button and the pin
    spinButton.addEventListener('click', spinWheel);
    pin.addEventListener('click', spinWheel);

    // clear the interval and set the boolean back to false
    clearInterval(timeoutID);
  }, randomDuration * 1000);
}

// attach a click event listener on the button, at which point call the spinWheel function
spinButton.addEventListener('click', spinWheel);

// call the same function when pressing the pin
pin.addEventListener('click', spinWheel);

</script>

<!--
  project's structure
  - svg for the color wheel (consisting of circle elements, and a group in which the slices are added)
  - svg for the arrow pointing at the selected color (positioned to the right of the circle)
  - heading in which to show the color selected through the wheel (hidden by default)
  - container for the simple instructions and the button spinning the wheel
-->

<svg id="wheel" viewBox="0 0 100 100">
  <circle
    cx="50"
    cy="50"
    r="48"
    fill="none"
    stroke-width="1"
    stroke="currentColor"
  />
	<!-- add an id to the underlying circle as this depicts the final slice, and as to add a random color -->
  <circle id="slice" cx="50" cy="50" r="47" fill="#001C34" />
  <g id="slices"></g>
</svg>
<svg id="pin" viewBox="0 0 50 50"><path d="M 0 25 L 50 0 V 50" /></svg>

<h17 class="isHidden" style="user-select: all;">#ffffff00</h17>

<div class="instructions">
  <h2>Spin that color <span>wheel</span></h2>
  <button>Spin!</button>
</div>
[/html]
Подпись автора

вопрос по ◆ВТ◆ в личку

вопрос по ◆ВТ◆ в тему

+1

2

Круть https://i.imgur.com/l4UzEfF.gif ваще

0

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»


упс таблица

Откуда гость?
ВНИМАНИЕ! В подписи запрещены ссылки на конкурирующие сайты или форумы!


Вы здесь » BLOGTOP » Уголок wap мастера » JavaScript » Рандомайзер цвета в формате рулетки