如何使投影在旋转物体上始终面朝下



我目前正在用css和javascript制作一个工作时钟,我需要在它上面添加阴影。目前投影总是在手的一边,我需要它总是面朝下。我不能分享确切的代码,但是这个代码非常相似: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对象。有什么合理的方法可以做到这一点吗?

感谢

您可以使用正弦和余弦来查找框阴影的偏移量。

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

如果光线来自上方,那么你需要感知当手穿过垂直位置时(6或12点钟方向),并设置手的样式以获得正确的框影。

你可以在图像的上方而不是下方使用你已有的方框阴影。

您可以使用自定义属性作为框阴影偏移值,并根据手的位置使用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)

最新更新