我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛
掘友们,🐇年快乐呀!😄
这是我第一次尝试在网上发表文章,希望可以让自己在新的一年有一个好的开始,有所成长!欢迎掘友们看完文章后在评论区里提出建议,相互学习。祝掘友们在新的一年里兔飞猛进、前兔似锦、前兔无量、大展宏兔!
制作步骤
- 绘制兔子
- 绘制星空背景
绘制兔子
效果预览
首先,让我们先看下兔子的整体页面结构:
<div class="rabbit">
<div class="rabbit-head">
<!-- 脸部 -->
<div class="rabbit-face">
<div class="rabbit-face-main"></div>
</div>
<!-- 耳朵 -->
<div class="rabbit-ear rabbit-left-ear"></div>
<div class="rabbit-ear rabbit-right-ear"></div>
<!-- 眼睛 -->
<div class="rabbit-eye rabbit-left-eye">
<div class="rabbit-eye-light"></div>
</div>
<div class="rabbit-eye rabbit-right-eye">
<div class="rabbit-eye-light"></div>
</div>
<!-- 鼻子 -->
<div class="rabbit-nose"></div>
<!-- 嘴巴 -->
<div class="rabbit-mouth"></div>
</div>
<div class="rabbit-body" ref="rabbitBody">
<!-- 肚子 -->
<div class="rabbit-body-tum">
</div>
</div>
<!-- 手部 -->
<div class="rabbit-hand rabbit-left-hand"></div>
<div class="rabbit-hand rabbit-right-hand"></div>
<div class="rabbit-foot rabbit-left-foot">
<i class="toe"></i>
</div>
<div class="rabbit-foot rabbit-right-foot">
<i class="toe"></i>
</div>
</div>
其次,让我们看看兔子的样式,这也是最重要的部分:
1.绘制脸部
利用三个宽高不一的椭圆重叠在一起,绘制出一个轮廓分明的脸部;
.rabbit {
width: 200px;
height: 300px;
position: absolute;
transform: scale(1.8);
z-index: 10;
bottom: 20%;
}
.rabbit-head {
left: 0;
position: absolute;
z-index: 10;
width: 163px;
height: 200px;
animation: swing 3s .15s linear infinite;
}
.rabbit-head::before, .rabbit-head::after {
position: absolute;
top: 70%;
content: '';
width: 30px;
height: 15px;
background-color: #F19A9D;
opacity: 0.5;
border-radius: 50%;
z-index: 10;
filter: blur(3px);
}
.rabbit-head::before {
left: 10%;
}
.rabbit-head::after {
right: 10%;
}
.rabbit-face {
width: 163px;
height: 200px;
position: absolute;
top: 0;
}
.rabbit-face::before, .rabbit-face::after {
position: absolute;
content: '';
display: inline-block;
background-color: #ffffff;
border: 3px solid #000000;
filter: blur(1px);
}
.rabbit-face-main {
position: absolute;
left: 50%;
top: 60px;
transform: translateX(-50%);
z-index: 3;
width: 152px;
height: 125px;
background-color: #ffffff;
border-radius: 50%;
}
.rabbit-face::before {
left: 50%;
top: 55px;
transform: translateX(-50%);
width: 155px;
height: 125px;
border-radius: 50%;
}
.rabbit-face::after {
left: 50%;
top: 90px;
z-index: 1;
transform: translateX(-50%);
width: 163px;
height: 110px;
border-radius: 110px;
border-bottom: 0;
border-width: 2px;
}
2.绘制耳朵和眼睛
眼睛和耳朵比较简单,使用border-radius属性就可以绘制出来了;
.rabbit-ear {
width: 40px;
height: 80px;
background-color: #ffffff;
border: 4px solid #000000;
border-bottom: none;
border-radius: 40% 50% 40% 50% / 50% 50% 50% 50%;
position: absolute;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
filter: blur(0.3px);
}
.rabbit-ear::before {
content: '';
display: inline-block;
width: 50%;
height: 60%;
background-color: #F19A9D;
border-radius: 50% 70%;
opacity: 0.8;
filter: blur(1px);
}
.rabbit-left-ear {
left: 5px;
top: -5px;
transform: rotate(-30deg);
}
.rabbit-right-ear {
right: 30px;
top: -15px;
transform: rotate(12deg);
}
.rabbit-eye {
width: 30px;
height: 50px;
position: absolute;
z-index: 10;
border-radius: 50%;
background: #ffffff;
border: 2px solid #000000;
overflow: hidden;
animation: blink 4s infinite;
animation-delay: .5s;
}
.rabbit-eye::before {
position: absolute;
content: '';
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 20;
width: 30%;
height: 30%;
background-color: #ffffff;
border-radius: 50%;
animation: eye-ball-blink 4s infinite;
animation-delay: .5s;
}
.rabbit-eye-light {
position: absolute;
z-index: 20;
width: 5px;
height: 5px;
background-color: #ffffff;
border-radius: 50%;
animation: eye-ball-blink 4s infinite;
animation-delay: .5s;
}
.rabbit-eye::after {
position: absolute;
content: '';
width: 100%;
height: 80%;
bottom: -5px;
background: #000000;
/* fallback for old browsers */
background: -webkit-linear-gradient(45deg, #434343, #000000);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(45deg, #434343, #000000);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
border-radius: 50%;
animation: eye-ball-blink 4s infinite ease-in-out;
animation-delay: .5s;
}
.rabbit-left-eye {
left: 22%;
top: 90px;
transform: rotate(-10deg);
}
.rabbit-left-eye::after {
left: 5px;
}
.rabbit-left-eye .rabbit-eye-light {
right: 25%;
bottom: 20%;
}
.rabbit-right-eye {
right: 22%;
top: 85px;
transform: rotate(-5deg);
}
.rabbit-right-eye .rabbit-eye-light {
right: 60%;
bottom: 15%;
}
3.绘制鼻子和嘴巴
.rabbit-nose {
position: absolute;
z-index: 10;
top: 140px;
left: 50%;
width: 8px;
height: 8px;
border-bottom-left-radius: 6px;
background-color: #000000;
opacity: 0.7;
filter: blur(0.5px);
transform: rotate(-60deg) skewX(-30deg) scale(1, 0.866);
}
.rabbit-nose::before, .rabbit-nose::after {
content: "";
position: absolute;
background: inherit;
width: inherit;
height: inherit;
border-bottom-left-radius: 6px;
}
.rabbit-nose::before {
transform: rotate(135deg) skewY(-45deg) scale(0.707, 1.414) translate(-50%, 0);
}
.rabbit-nose::after {
transform: rotate(-135deg) skewX(-45deg) scale(1.414, 0.707) translate(0%, 50%);
}
.rabbit-mouth {
width: 30px;
height: 20px;
position: absolute;
z-index: 10;
top: 155px;
left: 75px;
filter: blur(0.6px);
}
.rabbit-mouth::before, .rabbit-mouth::after {
content: '';
width: 50%;
height: 100%;
border: 0 solid #000000;
position: absolute;
border-radius: 50%;
border-bottom-width: 3px;
}
.rabbit-mouth::before {
left: 1px;
}
.rabbit-mouth::after {
right: 1px;
}
动画部分
/* 眨眼 */
@keyframes blink {
100% {
margin-top: 15px;
height: 30px;
border: 2px solid #000000;
border-radius: 50% 50% 0 0/100% 100% 0 0;
border-bottom: none;
}
0% {
margin-top: 0;
height: 50px;
border-radius: 50%;
}
}
/* 睁闭眼,眼球状态 */
@keyframes eye-ball-blink {
50%,
100% {
opacity: 0;
}
0% {
opacity: 1;
}
}
/* 摇头 */
@keyframes swing {
10% {
transform: rotate(15deg);
}
20% {
transform: rotate(-10deg);
}
30% {
transform: rotate(5deg);
}
40% {
transform: rotate(-5deg);
}
50%,
100% {
transform: rotate(0deg);
}
}
/* 挥手 */
@keyframes swingHand {
0% {
transform: rotateZ(160deg);
}
100% {
transform: rotateZ(130deg);
}
}
一开始本来是想画一整只兔子的,奈何能力有限,无从下手,兔子的下半身实在是想不出要怎么画,后来灵机一动,想着可以把兔子放在草丛中,而草丛刚好可以遮住下半身,这样就可以不用去考虑下半身了😎。
这样,我开始在网上寻找合适的草丛图片,在寻找的过程中,也在
iconfont图标库中找到几个星星和月亮图片,添加上星空作为背景,页面也不再单调了,
随机星星以及闪烁动画
<img src="moon.png" alt="月亮" class="moon">
<div class="sky">
</div>
<div class="grassland">
</div>
通过js动态生成不同形状、不同位置的星星,并且为了不让星星闪烁频率相同,我给每一颗星星都设置了随机的动画延迟时长。
window.onload = function(){
creatStars()
}
const starImgs = ['./star1.png', './star2.png', './star3.png','./star4.png']
function randomNum(minValue, maxValue) {
return Math.floor(Math.random() * (maxValue - minValue + 1) + minValue);
}
function creatStars() {
const skyDom = document.getElementsByClassName('sky')[0];
const fragment = document.createDocumentFragment();
const screenW = skyDom.clientWidth;
const screenH = skyDom.clientHeight;
const imgLens = starImgs.length;
for (let i = 0; i < 150; i++) {
var span = document.createElement('span');
var x = parseInt(Math.random() * screenW);
var y = parseInt(Math.random() * screenH);
var curIndex = randomNum(0, imgLens - 1);
span.style.backgroundImage = 'url(' + starImgs[curIndex] + ')';
span.style.left = x + 'px';
span.style.top = y + 'px';
var rate = Math.random() * 1.5 + 1;
span.style.animationDelay = rate + 's';
var scale = Math.random() * 1.5;
span.style.transform = 'scale(' + scale + ', ' + scale + ')';
fragment.appendChild(span);
}
skyDom.appendChild(fragment);
}
这里用了drop-shadow属性给星星和月亮实现了发光效果,让场景更加生动;
@keyframes flash {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.sky {
width: 100%;
height: 100%;
background: #4b6cb7;
/* fallback for old browsers */
background: -webkit-radial-gradient(#3d5896, #182848);
/* Chrome 10-25, Safari 5.1-6 */
background: radial-gradient(#3d5896, #182848);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
position: absolute;
z-index: 1;
overflow: hidden;
filter: blur(1px);
}
.sky span {
display: inline-block;
width: 20px;
height: 20px;
position: absolute;
z-index: 1;
animation: flash 1s ease-in-out infinite;
filter: drop-shadow(0px 0px 10px rgb(215, 234, 131 , .5));
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: center;
}
.moon{
position: absolute;
top: 5%;
right: 5%;
width: 100px;
height: 100px;
z-index: 20;
border-radius: 50%;
filter: drop-shadow(0px 0px 10px rgb(215, 234, 131 , .5));
/* box-shadow: 0 5px 20px rgba(251, 152, 11, .5); */
animation: swing 1s ease-in-out infinite;
}
.grassland {
position: absolute;
bottom: 0;
z-index: 100;
background-image: url(./grassland.png);
filter: drop-shadow(0px 0px 10px rgba(106, 241, 129, 0.5));
background-position: center;
background-size: 100% 100%;
width: 100%;
height: 60%;
}
总结
这就是我的第一篇文章,写的比较粗糙,希望后续能够多写技术文章,提高自己的写作水平,欢迎掘友们在评论区留言。
最后,祝掘友们在新的一年里工作顺心,事业有成,进账似若水,存款似山河!🚀🚀🚀