Как сделать так, чтобы тень всегда смотрела вниз на вращающийся объект

avatar
TheAndersMan
9 августа 2021 в 05:44
123
3
0

В настоящее время я делаю рабочие часы с помощью CSS и JavaScript, и мне нужно, чтобы на них были тени. в настоящее время тень всегда находится на одной стороне руки, и мне нужно, чтобы она всегда была обращена вниз. Я не могу поделиться точным кодом, но этот codepen очень похож: https://codepen.io/ilyasw/pen/PddVja

Вот соответствующий

HTML

  <img src="media/hour-hand.png" class="hourHand hand" />
  <img src="media/second-hand.png" class="secondHand hand" />
  <img src="media/minute-hand.png" class="minuteHand hand" />
  <img src="media/small-second-hand.png" class="smallSecondHand hand">

CSS

    .hand {
    position: absolute;
    top: 50%;
    left: 50%;
    filter: drop-shadow(5px 5px 5px black);
    height: 30vmin;
  }

  .hourHand {
    z-index: 2;
    transform: translate(-50%, -50%) rotate(55deg);
  }

  .minuteHand {
    z-index: 3;
    transform: translate(-50.5%, -50%) rotate(-51.7deg);
  }

  .secondHand {
    z-index: 4;
    transform: translate(-50%, -50%) rotate(140deg);
  }

  .smallSecondHand {
    left: calc(50% - 10vmin + 2px);
    height: 12vmin;
    transform: translate(-50%, -50%);
  }

JS

   setInterval("clock()", 10);

function clock() {
    let dt = new Date(),
        hr = dt.getHours(),
        min = dt.getMinutes(),
        sec = dt.getSeconds(),
        msec = dt.getMilliseconds(),
        hrDeg = 55 + (hr * 30) + (min * 30/60),
        minDeg = -51.7 + (min * 6) + (sec * 6/60),
        secDeg = (sec * 6) + (6 * msec/1000),
        hrHand = document.querySelector('.hourHand'),
        minHand = document.querySelector('.minuteHand'),
        secHand = document.querySelector('.smallSecondHand'),
        dayCell = document.querySelector('p');
    
    hrHand.style.transform = "translate(-50%, -50%) rotate(" + hrDeg + "deg)";
    minHand.style.transform = "translate(-50%, -50%) rotate(" + minDeg + "deg)";
    secHand.style.transform = "translate(-50%, -50%) rotate(" + secDeg + "deg)";

}

Единственное реальное отличие состоит в том, что я использую тень, потому что руки являются объектами PNG, а не CSS. Есть ли разумный способ сделать это?

Спасибо

Источник
לבני מלכה
9 августа 2021 в 05:47
0

вы должны включить соответствующий код, который мы можем вам помочь

TheAndersMan
9 августа 2021 в 05:49
0

@לבנימלכה все это включено в связанную кодовую ручку

לבני מלכה
9 августа 2021 в 05:50
0

Я знаю, но в будущем, если эта ссылка сломается, люди не смогут увидеть код

TheAndersMan
9 августа 2021 в 05:55
0

@לבנימלכה Добавлено

Ответы (3)

avatar
Tommyka
9 августа 2021 в 07:11
1

Вы можете использовать синус и косинус, чтобы найти смещение тени блока.

var d2rFactor = Math.PI / 180; //convert degrees to radians
var shadowAngle = 45; // what angle the shadow should have compared to line
var shadowOffset = 10; // distance

function rotateLine(target, deg) {
  var r = (shadowAngle - deg) * g2rFactor; // find the angle that the shadow should have to counter to rotation of the line.
  var x = Math.cos(r)*shadowOffset;
  var y = Math.sin(r)*shadowOffset;
  
  target.style.transform = `rotate(${deg}deg)`;
  target.style.boxShadow = `${x}px ${y}px 5px black`;
}

Вот тест, показывающий его работу https://codepen.io/tommyka/pen/vYmQbbd

TheAndersMan
9 августа 2021 в 07:25
0

это выглядит здорово! Я не понимаю всего этого, но я реализую это утром и посмотрю, смогу ли я заставить его работать. Спасибо!

slebetman
9 августа 2021 в 08:37
0

@TheAndersMan Если вы интересуетесь анимацией или просто графическим программированием в целом, вы должны понимать единичный круг: youtube.com/watch?v=1m9p9iubMLU. Обратите внимание, что вы можете просто погуглить «единичный круг», чтобы получить более глубокое представление о функциях sin и cos, однако видео Академии Хана, на которое я ссылался, является хорошим введением.

avatar
anatolhiman
9 августа 2021 в 06:49
0

Вы можете использовать настраиваемые свойства в качестве значений смещения box-shadow и манипулировать ими с помощью JavaScript в соответствии с положением рук. Можно сделать это очень мелкозернистым с крошечными обновлениями для каждого тика или настроить его так, чтобы он просто регулировал CSS, когда стрелки меняют вертикальное положение на горизонтальное:

    :root {
      --clockHandShadowHorizontalOffset: 0;
      --clockHandShadowVerticalOffset: 4px;
    }

    .clockhandshadow {
      box-shadow: var(--clockHandShadowHorizontalOffset) var(--clockHandShadowVerticalOffset) 6px #0000004a;
    }

Эскиз части JS:


    let root = document.documentElement;

    const rotateBoxShadow = ( degree ) => {

      let horizontalOffset, verticalOffset
      // Maybe reuse the function that makes hands move to calculate values?
      horizontalOffset = ... + 'px'
      verticalOffset = ... + 'px'
      
      // Update CSS
      root.style.setProperty('--clockHandShadowHorizontalOffset', horizontalOffset);
      root.style.setProperty('--clockHandShadowVerticalOffset, verticalOffset);
    }

    // Get a dynamic value for hand rotation somehow

    rotateBoxShadow(rotation)
avatar
A Haworth
9 августа 2021 в 06:15
0

Если свет падает сверху, вам нужно определить, когда стрелка проходит вертикальное положение (на 6 или 12 часов), и настроить стиль стрелки на правильную тень коробки.

Вы можете использовать тень блока, которая у вас есть, но выше, а не ниже изображения.