Выделите анимацию на вращающемся колесе

У меня есть это вращающееся колесо, и я пытаюсь сделать так, чтобы когда колесо начинает вращаться, блок, который в настоящее время находится в центре, должен иметь непрозрачность 100%, а остальные, скажем, 50%, чтобы это дало эффект подсветки.

Ссылка на Codepen:

Code in link

заранее спасибо

Блок в центре должен подсвечиваться при вращении

Если мы сделаем это в javascript, это сильно повлияет на производительность, так как вы будете проверять положение каждого блока относительно строки в середине каждую секунду. если вам нужна альтернатива этому, вы, вероятно, могли бы иметь 2 полупрозрачных элемента или псевдоэлемента по обеим сторонам вашего селектора и иметь зазор размером в 1 блок между ними. не тот эффект, который вы хотите, но близкий

KyloDev 16.04.2023 20:12

Не могли бы вы показать мне пример в коде, как это будет выглядеть?

aaaaSton2 16.04.2023 20:20

вы хотите показать элемент под селектором, как в фокусе?

Faust Life 16.04.2023 20:24

Я не вижу никаких CSS или JS в вашем коде, который пытается установить непрозрачность.

James 16.04.2023 20:34

да, потому что я не знал, как это сделать, поэтому я спросил...

aaaaSton2 16.04.2023 23:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
5
102
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Пусть все элементы .card имеют opacity: 0.5. Мы применим opacity: 1 к активу .card по мере необходимости. Чтобы сохранить максимально возможную производительность, мы прислушиваемся к активным изменениям позиции только тогда, когда вращается спиннер. Мы используем requestAnimationFrame(), чтобы синхронизировать наши проверки с кадром дисплея.

const {
  start,
  stop,
  tick
} = (() => {
  // Whether we should be actively listening for changes in the active item.
  let highlightListen = false;
  // The currently highlighted item.
  let active;

  // Do a check of which element should be highlighted.
  const tick = () => {
    // Get the x-coordinate of the middle of the screen.
    const middle = window.innerWidth / 2;
    const middleCard = document
      // Get all elements at the point in the document of x: middle, y: 50px.
      .elementsFromPoint(middle, 50)
      // Filter this list to `.card` elements.
      .filter((element) => element.matches('.card'))
      // Get the first item from this array.
      ?.[0];

    // If this middle card is different from the last-known active item.
    if (active !== middleCard) {
      // Remove the highlight opacity style that was on the previously
      // active item.
      if (active) {
        active.style.opacity = '';
      }
      // Add the highlight opacity style to the new middle card. Check
      // that it exists since we might have hit an instance where the
      // the middle of the screen is not on a card.
      if (middleCard) {
        middleCard.style.opacity = '1';
      }
      // Store the new middle card.
      active = middleCard;
    }

    // If we should be listening to positional changes, run this check
    // again on the next drawing frame.
    if (highlightListen) {
      requestAnimationFrame(tick);
    }
  };

  return {
    // Start listening for active changes.
    start() {
      highlightListen = true;
      tick();
    },
    // Stop listening for active changes.
    stop() {
      highlightListen = false;
    },
    // Do a single check.
    tick,
  };
})();

$(document).ready(function() {
  //setup multiple rows of colours, can also add and remove while spinning but overall this is easier.
  initWheel();
  // Once all the elements are set up, do a single check to mark the initial state.
  tick();

  $('button').on('click', function() {
    var outcome = parseInt($('input').val());
    spinWheel(outcome);
  });
});

function initWheel() {
  var $wheel = $('.roulette-wrapper .wheel'),
    row = "";

  row += "<div class='row'>";
  row += "  <div class='card red'>1</div>";
  row += "  <div class='card black'>14</div>";
  row += "  <div class='card red'>2</div>";
  row += "  <div class='card black'>13</div>";
  row += "  <div class='card red'>3</div>";
  row += "  <div class='card black'>12</div>";
  row += "  <div class='card red'>4</div>";
  row += "  <div class='card green'>0</div>";
  row += "  <div class='card black'>11</div>";
  row += "  <div class='card red'>5</div>";
  row += "  <div class='card black'>10</div>";
  row += "  <div class='card red'>6</div>";
  row += "  <div class='card black'>9</div>";
  row += "  <div class='card red'>7</div>";
  row += "  <div class='card black'>8</div>";
  row += "</div>";

  for (var x = 0; x < 29; x++) {
    $wheel.append(row);
  }
}

function spinWheel(roll) {
  var $wheel = $('.roulette-wrapper .wheel'),
    order = [0, 11, 5, 10, 6, 9, 7, 8, 1, 14, 2, 13, 3, 12, 4],
    position = order.indexOf(roll);

  //determine position where to land
  var rows = 12,
    card = 75 + 3 * 2,
    landingPosition = (rows * 15 * card) + (position * card);

  var randomize = Math.floor(Math.random() * 75) - (75 / 2);

  landingPosition = landingPosition + randomize;

  var object = {
    x: Math.floor(Math.random() * 50) / 100,
    y: Math.floor(Math.random() * 20) / 100
  };

  $wheel.css({
    'transition-timing-function': 'cubic-bezier(0,' + object.x + ',' + object.y + ',1)',
    'transition-duration': '6s',
    'transform': 'translate3d(-' + landingPosition + 'px, 0px, 0px)'
  });

  // Start active positional checking.
  start();

  setTimeout(function() {
    $wheel.css({
      'transition-timing-function': '',
      'transition-duration': '',
    });

    var resetTo = -(position * card + randomize);
    $wheel.css('transform', 'translate3d(' + resetTo + 'px, 0px, 0px)');

    // Stop active positional checking.
    stop();
  }, 6 * 1000);
}
body {
  font-family: 'Titillium Web', sans-serif;
  background: #191B28;
}

.roulette-wrapper {
  position: relative;
  display: flex;
  justify-content: center;
  width: 100%;
  margin: 0 auto;
  overflow: hidden;
}

.roulette-wrapper .selector {
  width: 3px;
  background: grey;
  left: 50%;
  height: 100%;
  transform: translate(-50%, 0%);
  position: absolute;
  z-index: 2;
}

.roulette-wrapper .wheel {
  display: flex;
}

.roulette-wrapper .wheel .row {
  display: flex;
}

.roulette-wrapper .wheel .row .card {
  height: 75px;
  width: 75px;
  margin: 3px;
  border-radius: 8px;
  border-bottom: 3px solid rgba(0, 0, 0, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 1.5em;
  opacity: 0.5;
}

.card.red {
  background: #F95146;
}

.card.black {
  background: #2D3035;
}

.card.green {
  background: #00C74D;
}

* {
  box-sizing: border-box;
}
<link href = "https://fonts.googleapis.com/css?family=Titillium+Web" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-3.3.1.min.js"></script>

<div class='roulette-wrapper'>
  <div class='selector'></div>
  <div class='wheel'></div>
</div>

<div>
  <input placeholder='outcome'>
  <button>
    Spin Wheel
  </button>
</div>

это, кажется, именно это

aaaaSton2 16.04.2023 23:46

$(document).ready(function() {
  //setup multiple rows of colours, can also add and remove while spinning but overall this is easier.
  initWheel();

  $('button').on('click', function() {
    var outcome = parseInt($('input').val());
    spinWheel(outcome);
  });
});

function initWheel() {
  var $wheel = $('.roulette-wrapper .wheel'),
    row = "";

  row += "<div class='row'>";
  row += "  <div class='card red'>1</div>";
  row += "  <div class='card black'>14</div>";
  row += "  <div class='card red'>2</div>";
  row += "  <div class='card black'>13</div>";
  row += "  <div class='card red'>3</div>";
  row += "  <div class='card black'>12</div>";
  row += "  <div class='card red'>4</div>";
  row += "  <div class='card green'>0</div>";
  row += "  <div class='card black'>11</div>";
  row += "  <div class='card red'>5</div>";
  row += "  <div class='card black'>10</div>";
  row += "  <div class='card red'>6</div>";
  row += "  <div class='card black'>9</div>";
  row += "  <div class='card red'>7</div>";
  row += "  <div class='card black'>8</div>";
  row += "</div>";

  for (var x = 0; x < 29; x++) {
    $wheel.append(row);
  }
}

function spinWheel(roll) {
  var $wheel = $('.roulette-wrapper .wheel'),
    order = [0, 11, 5, 10, 6, 9, 7, 8, 1, 14, 2, 13, 3, 12, 4],
    position = order.indexOf(roll);

  //determine position where to land
  var rows = 12,
    card = 75 + 3 * 2,
    landingPosition = (rows * 15 * card) + (position * card);

  var randomize = Math.floor(Math.random() * 75) - (75 / 2);

  landingPosition = landingPosition + randomize;

  var object = {
    x: Math.floor(Math.random() * 50) / 100,
    y: Math.floor(Math.random() * 20) / 100
  };

  $wheel.css({
    'transition-timing-function': 'cubic-bezier(0,' + object.x + ',' + object.y + ',1)',
    'transition-duration': '6s',
    'transform': 'translate3d(-' + landingPosition + 'px, 0px, 0px)'
  });

  setTimeout(function() {
    $wheel.css({
      'transition-timing-function': '',
      'transition-duration': '',
    });

    var resetTo = -(position * card + randomize);
    $wheel.css('transform', 'translate3d(' + resetTo + 'px, 0px, 0px)');
  }, 6 * 1000);
}
body {
  font-family: 'Titillium Web', sans-serif;
  background: #191B28;
}

.roulette-wrapper {
  position: relative;
  display: flex;
  justify-content: center;
  width: 100%;
  margin: 0 auto;
  overflow: hidden;
}

.roulette-wrapper .selector {
  width: 3px;
  background: grey;
  left: 50%;
  height: 100%;
  transform: translate(-50%, 0%);
  position: absolute;
  z-index: 2;
}

/* What I added */
.roulette-wrapper .selector:before,
.roulette-wrapper .selector:after {
  content: '';
  position: absolute;
  height: 100%;
  width: calc(50vw - (75px / 2));
  background: #191B28;
  opacity: 50%
}

.roulette-wrapper .selector:before {
  right: 37px;
}

.roulette-wrapper .selector:after {
  left: 37px;
}
/****************/

.roulette-wrapper .wheel {
  display: flex;
}

.roulette-wrapper .wheel .row {
  display: flex;
}

.roulette-wrapper .wheel .row .card {
  height: 75px;
  width: 75px;
  margin: 3px;
  border-radius: 8px;
  border-bottom: 3px solid rgba(0, 0, 0, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 1.5em;
}

.card.red {
  background: #F95146;
}

.card.black {
  background: #2D3035;
}

.card.green {
  background: #00C74D;
}

* {
  box-sizing: border-box;
}
<link href = "https://fonts.googleapis.com/css?family=Titillium+Web" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-3.3.1.min.js"></script>

<div class='roulette-wrapper'>
  <div class='selector'></div>
  <div class='wheel'></div>
</div>

<div>
  <input placeholder='outcome'>
  <button>
    Spin Wheel
  </button>
</div>

Это не совсем то, что вы хотели, но это близко и менее тяжело для вычислений.

Как проверить перекрытие вы можете найти здесь Обнаружение коллизий jQuery/JavaScript Но я не уверен, что ваше решение правильное...

в вашем коде это может быть что-то вроде этого в initWheel исправьте инициализацию строки row += "<div class='row'>"; row += " <div class='list card red'>1</div>";... в методе spinWheel добавьте это: var list = $('.list'); в методе setTimeout добавьте это:

Faust Life 16.04.2023 21:05

Другим подходом было бы наложение полупрозрачных карт сероватого цвета с прозрачным средним битом. Таким образом, никаких дополнительных вычислений не должно происходить.

Вот простой фрагмент — наложение черного, прозрачного, черного линейного градиента. Очевидно, вы можете изменить это, чтобы получить желаемый эффект.

<link href = "https://fonts.googleapis.com/css?family=Titillium+Web" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-3.3.1.min.js"></script>
<style>
  body {
    font-family: 'Titillium Web', sans-serif;
    background: #191B28;
  }
  
  .roulette-wrapper {
    position: relative;
    display: flex;
    justify-content: center;
    width: 100%;
    margin: 0 auto;
    overflow: hidden;
  }
  
  .roulette-wrapper::after {
    content: '';
    width: 100%;
    height: 100%;
    background-image: linear-gradient(to right, black, transparent calc(50% - (75px / 2)) calc(50% + (75px / 2)), black);
    top: 0;
    left: 0;
    position: absolute;
  }
  
  .roulette-wrapper .selector {
    width: 3px;
    background: grey;
    left: 50%;
    height: 100%;
    transform: translate(-50%, 0%);
    position: absolute;
    z-index: 2;
  }
  
  .roulette-wrapper .wheel {
    display: flex;
  }
  
  .roulette-wrapper .wheel .row {
    display: flex;
  }
  
  .roulette-wrapper .wheel .row .card {
    height: 75px;
    width: 75px;
    margin: 3px;
    border-radius: 8px;
    border-bottom: 3px solid rgba(0, 0, 0, 0.2);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 1.5em;
  }
  
  .card.red {
    background: #F95146;
  }
  
  .card.black {
    background: #2D3035;
  }
  
  .card.green {
    background: #00C74D;
  }
  
  * {
    box-sizing: border-box;
  }
</style>
<div class='roulette-wrapper'>
  <div class='selector'></div>
  <div class='wheel'></div>
</div>

<div>
  <input placeholder='outcome'>
  <button>
    Spin Wheel
  </button>
</div>
<script>
  $(document).ready(function() {
    //setup multiple rows of colours, can also add and remove while spinning but overall this is easier.
    initWheel();

    $('button').on('click', function() {
      var outcome = parseInt($('input').val());
      spinWheel(outcome);
    });
  });

  function initWheel() {
    var $wheel = $('.roulette-wrapper .wheel'),
      row = "";

    row += "<div class='row'>";
    row += "  <div class='card red'>1</div>";
    row += "  <div class='card black'>14</div>";
    row += "  <div class='card red'>2</div>";
    row += "  <div class='card black'>13</div>";
    row += "  <div class='card red'>3</div>";
    row += "  <div class='card black'>12</div>";
    row += "  <div class='card red'>4</div>";
    row += "  <div class='card green'>0</div>";
    row += "  <div class='card black'>11</div>";
    row += "  <div class='card red'>5</div>";
    row += "  <div class='card black'>10</div>";
    row += "  <div class='card red'>6</div>";
    row += "  <div class='card black'>9</div>";
    row += "  <div class='card red'>7</div>";
    row += "  <div class='card black'>8</div>";
    row += "</div>";

    for (var x = 0; x < 29; x++) {
      $wheel.append(row);
    }
  }

  function spinWheel(roll) {
    var $wheel = $('.roulette-wrapper .wheel'),
      order = [0, 11, 5, 10, 6, 9, 7, 8, 1, 14, 2, 13, 3, 12, 4],
      position = order.indexOf(roll);

    //determine position where to land
    var rows = 12,
      card = 75 + 3 * 2,
      landingPosition = (rows * 15 * card) + (position * card);

    var randomize = Math.floor(Math.random() * 75) - (75 / 2);

    landingPosition = landingPosition + randomize;

    var object = {
      x: Math.floor(Math.random() * 50) / 100,
      y: Math.floor(Math.random() * 20) / 100
    };

    $wheel.css({
      'transition-timing-function': 'cubic-bezier(0,' + object.x + ',' + object.y + ',1)',
      'transition-duration': '6s',
      'transform': 'translate3d(-' + landingPosition + 'px, 0px, 0px)'
    });

    setTimeout(function() {
      $wheel.css({
        'transition-timing-function': '',
        'transition-duration': '',
      });

      var resetTo = -(position * card + randomize);
      $wheel.css('transform', 'translate3d(' + resetTo + 'px, 0px, 0px)');
    }, 6 * 1000);
  }
</script>

Примечание. Использование графического процессора на моем ноутбуке составляло 15%, когда это работало.

Другие вопросы по теме