我正在尝试创建一个等待/倒计时屏幕,显示一只眼睛连同眼皮,和一个虹膜效果的眼球。鉴于我们中的许多人花时间毫无意义地盯着这样的旋转者,我试图达到的效果是“眼睛”旋转者回头看着观看者并眨眼。
null
document.getElementById('waitDia').showModal();
var ticks = 300,
ticker = setInterval(changeTick,1000);
function changeTick()
{
document.getElementById('spnTick').innerText = --ticks;
if (0 === ticks) clearInterval(ticker);
}
#waitDia
{
position:absolute;
left:0 !important;
top:0 !important;
width:100vw !important;
height:100vh !important;
padding:0;
min-width:100vw;
min-height:100vh;
background-color:transparent !important;
}
#waitDia::backdrop{background-color:rgba(127,127,127,0.2);}
#spnTick
{
position:absolute;
display:inline-block;
width:100%;
left:0;
top:0;
}
#waitbox
{
left:0 !important;
top:0 !important;
width:100vw !important;
height:100vh !important;
position:absolute;
overflow:hidden;
}
#eyeball
{
position:relative;
top:-10vh;
left:-6px;
width:calc(24vh + 12px);
height:calc(24vh + 12px);
box-sizing:border-box;
background:rgba(0,128,128,0.5);
border-radius:100%;
border:1px solid transparent;
box-shadow:inset 0 0 18px 2px blue;
z-index:99999998;
}
#waitsecs
{
position:absolute;
left:calc(50vw - 12vh);
top:46vh;
width:24vh;
height:24vh;
font-size:8vh;
text-align:center;
display:block;
}
#waitEye
{
position:absolute;
top:27vh;
left:calc(50vw - 23vh);
width: 46vh;
height: 46vh;
background-color: rgba(255,255,255,.9);
border-radius: 100% 0px;
transform: rotate(45deg);
mix-blend-mode:overlay;
z-index:199999999;
box-shadow:0 -0.5vh 0 2px #f1c27d,inset 0 6px 4px 4px black;
}
body,html
{
background:black;
font-family:arial;
}
<dialog id='waitDia' class='waitdia'>
<div id='waitbox'>
<div id='waitsecs'><span id='spnTick'>300</span><div id='eyeball'></div></div>
<div id='waitEye'></div>
</div>
</dialog>
null
到目前为止,我所能达到的效果如下所示--我在这里仅仅是为了说明,将代码设置为300秒,所以它可以保持长时间的工作--在实际应用程序中,等待时间可能要短得多。
虽然这种效果正朝着正确的方向发展,但它仍然缺乏眼睑眨眼的效果。我怀疑这是很容易做到的帮助下,正确的“框阴影”操作和一个简单的动画。然而,这里我触及了我的兼职CSS技能的极限。我将非常感谢在座的任何一位能够提出改进建议以完成这一实施的人。
我会用不同的方法来做,并考虑旋转来实现眨眼效果。诀窍是用两个元素(眼皮)创建眼睛,使其能够眨眼。
下面是只有闪烁动画的代码:
null
.eye {
width: 250px;
height: 80px;
margin: 50px;
display:inline-block;
perspective: 200px;
background:
radial-gradient(circle 100px at 50% 250%,#f1c27d 99% ,transparent 100%) top/100% 50%,
radial-gradient(circle 100px at 50% -150%,#f1c27d 99% ,transparent 100%) bottom/100% 50%;
background-repeat:no-repeat
}
.eye>div {
height: 50%;
position:relative;
overflow:hidden;
transform-origin:bottom;
animation:b1 0.8s infinite ease-out alternate;
}
.eye>div:last-child {
transform-origin:top;
animation-name:b2;
}
.eye>div:before {
content: "";
position: absolute;
top:0;
left:10%;
right:10%;
padding-top:80%;
border-radius:50%;
background:#fff;
box-shadow:
-2px 0 0 3px inset #f1c27d,
inset -5px 5px 2px 4px black;
}
.eye>div:last-child:before {
bottom:0;
top:auto;
box-shadow:
-2px 0 0 3px inset #f1c27d,
inset -6px -4px 2px 4px black;
}
body {
background:#000;
}
@keyframes b1{
to { transform:rotateX(-88deg);}
}
@keyframes b2{
to {transform:rotateX(88deg);}
}
<div class="eye">
<div></div>
<div></div>
</div>
没有计数器的版本
d
来实现眼睑上下位置的暂停动画
null
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="25%" height="25%" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet">
<defs>
<radialGradient id="grad1" cx="40%" cy="20%" r="100%" fx="45%" fy="20%">
<stop stop-color="#B7B3B8" offset="10%"/>
<stop stop-color="#CDC9D0" offset="65%"/>
<stop stop-color="#9D90A2" offset="85%"/>
<stop stop-color="#CDBED3" offset="100%"/>
</radialGradient>
</defs>
<image xlink:href="https://i.stack.imgur.com/gDG2U.jpg" width="100%" height="100%" />
<path id="veko" fill="url(#grad1)" stroke="#B9B5BB" stroke-width="4" d="m12.7 132c0 0 25.6-19.6 39.8-27.1 11.7-6.2 23.9-11.9 36.9-14.4 10.7-2.1 21.9-2 32.6-0.4 8.5 1.3 16.8 4.3 24.6 7.8 9 4.1 17.1 9.9 25.2 15.5 2.2 1.5 4.9 2.6 6.4 4.9 0.4 0.6 1.1 2.4 0.4 2.1-6.7-2.5-17.2-10.3-26.1-14.8-6.6-3.3-13.1-6.8-20.1-9.1-5.2-1.7-10.6-2.9-16.1-3.4-8.6-0.8-17.5-1.3-26.1 0.4-12.4 2.5-24 8.4-35.4 14-14.6 7.1-42.2 24.6-42.2 24.6z" >
<animate attributeName="d" dur="4s" repeatCount="indefinite" values="
m12.7 132c0 0 25.6-19.6 39.8-27.1 11.7-6.2 23.9-11.9 36.9-14.4 10.7-2.1 21.9-2 32.6-0.4 8.5 1.3 16.8 4.3 24.6 7.8 9 4.1 17.1 9.9 25.2 15.5 2.2 1.5 4.9 2.6 6.4 4.9 0.4 0.6 1.1 2.4 0.4 2.1-6.7-2.5-17.2-10.3-26.1-14.8-6.6-3.3-13.1-6.8-20.1-9.1-5.2-1.7-10.6-2.9-16.1-3.4-8.6-0.8-17.5-1.3-26.1 0.4-12.4 2.5-24 8.4-35.4 14-14.6 7.1-42.2 24.6-42.2 24.6z;
m12.7 132c0 0 25.6-19.6 39.8-27.1 11.7-6.2 23.9-11.9 36.9-14.4 10.7-2.1 21.9-2 32.6-0.4 8.5 1.3 16.8 4.3 24.6 7.8 9 4.1 17.1 9.9 25.2 15.5 2.2 1.5 4.9 2.6 6.4 4.9 0.4 0.6 1.1 2.4 0.4 2.1-6.7-2.5-17.2-10.3-26.1-14.8-6.6-3.3-13.1-6.8-20.1-9.1-5.2-1.7-10.6-2.9-16.1-3.4-8.6-0.8-17.5-1.3-26.1 0.4-12.4 2.5-24 8.4-35.4 14-14.6 7.1-42.2 24.6-42.2 24.6z;
m12.7 132c0 0 25.6-19.6 39.8-27.1 11.7-6.2 23.9-11.9 36.9-14.4 10.7-2.1 21.9-2 32.6-0.4 8.5 1.3 16.8 4.3 24.6 7.8 9 4.1 17.1 9.9 25.2 15.5 2.2 1.5 6.4 4.9 6.4 4.9-0.1 0.7 2.8-0.5 0.4 2.1-4.7 5.2-11 10.6-17.4 14.6-6 3.8-12.7 6.5-19.5 8.9-6.1 2.1-12.4 3.9-18.9 4.7-8.3 1-16.8 0.5-25.2 0-13-0.8-26-2.3-38.8-4.7-15.6-2.9-46.2-11.9-46.2-11.9z;
m12.7 132c0 0 25.6-19.6 39.8-27.1 11.7-6.2 23.9-11.9 36.9-14.4 10.7-2.1 21.9-2 32.6-0.4 8.5 1.3 16.8 4.3 24.6 7.8 9 4.1 17.1 9.9 25.2 15.5 2.2 1.5 6.4 4.9 6.4 4.9-0.1 0.7 2.8-0.5 0.4 2.1-4.7 5.2-11 10.6-17.4 14.6-6 3.8-12.7 6.5-19.5 8.9-6.1 2.1-12.4 3.9-18.9 4.7-8.3 1-16.8 0.5-25.2 0-13-0.8-26-2.3-38.8-4.7-15.6-2.9-46.2-11.9-46.2-11.9z;
m12.7 132c0 0 25.6-19.6 39.8-27.1 11.7-6.2 23.9-11.9 36.9-14.4 10.7-2.1 21.9-2 32.6-0.4 8.5 1.3 16.8 4.3 24.6 7.8 9 4.1 17.1 9.9 25.2 15.5 2.2 1.5 4.9 2.6 6.4 4.9 0.4 0.6 1.1 2.4 0.4 2.1-6.7-2.5-17.2-10.3-26.1-14.8-6.6-3.3-13.1-6.8-20.1-9.1-5.2-1.7-10.6-2.9-16.1-3.4-8.6-0.8-17.5-1.3-26.1 0.4-12.4 2.5-24 8.4-35.4 14-14.6 7.1-42.2 24.6-42.2 24.6z" />
</path>
</svg>
SVG
+JavaScript
版本
主要思想是通过移动bezier曲线的两个控制点来形成眼睑的形状,这取决于动画帧之间的delta时间:
null
requestAnimationFrame(draw);
function draw(t) {
circle.setAttribute('cx', Math.sin(t/1000)*2);
grad.setAttribute('offset', 40 + Math.sin(t/3000)*20 + '%');
t = Math.max(0, Math.sin(t/300));
t = (t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t)*6-3;
let d = `-7 0C-2 ${t} 2 ${t} 7 0`;
mask.setAttribute('d', `M-7 -7${d}L7 -7z`)
eyelid.setAttribute('d', `M${d}`)
requestAnimationFrame(draw);
}
<svg viewbox="-10 -10 20 20" height="90vh">
<defs><radialGradient id="g1" cx="50%" cy="50%" r="50%">
<stop stop-color="black" offset="0%"/>
<stop id="grad" stop-color="teal" offset="30%"/>
<stop stop-color="white" offset="100%"/>
</radialGradient></defs>
<circle id="circle" r="2.4" stroke="black" fill="url(#g1)" stroke-width="0.2"></circle>
<path id="mask" stroke="none" fill="white"></path>
<path id="eyelid" stroke="black" fill="none"></path>
<svg>