当青训营遇上码上掘金——主题1“我的名片”代码创作

104 阅读7分钟

当青训营遇上码上掘金

我正在参加「青训营 X 码上掘金」主题创作活动入营版

本次活动我选择的是主题一,以“我的名片”为主题进行自我介绍,使用的技术是基础三件套HTML CSS JS。

成果展示

先上效果图和码上掘金的代码~ 2hhq4-qy5bb.gif

创作灵感

首先说到名片,想到的第一个就是一张印着个人信息的卡片,而如果只是用文字来表达自己的信息会不会太枯燥了一点呢?如果用代码来表达的话,我想让整个页面都成为我名片的布景,除了有文字介绍,还要有相关的图片元素点缀。

创作思路

画好了草图,就开始思考如何用代码实现效果。实现效果除了基础的结构和样式,比较难的部分就是绘制元素和动画效果的制作。所以代码创作过程的描述主要围绕这两个方面。

绘制元素

有想过把图片丢在代码里,但是用码上掘金不知道怎么引用本地图片,好像只能引用在线图片,打的草稿有几个是比较简单的图案,所以决定用css来画。

白云元素

将盒子设置为圆形,调整大小后使用box-shadow来添加多个“阴影”,box-shadow会在元素框架上添加阴影效果,这些阴影大小与原元素一致,可以通过设置颜色、x、y坐标来把一模一样的圆球组合在一起,就变成了一颗简单的云朵啦。

QQ截图20230115162556.png

<div class="cloud1"></div>
.cloud1 {
			position: absolute;
			top: 100px;
			left: 50px;
			width: 200px;
			height: 100px;
			background-color: #fff;
			border-radius: 50%;
			box-shadow: #fff 120px 0px 0 -5px, #fff 60px -25px, #fff 30px 15px, #fff 100px 20px 0 -5px;
		}

草坪元素

绘制思路和云朵差不多

.grass1 {
			position: absolute;
			bottom: 0;
			left: 100px;
			width: 250px;
			height: 200px;
			background-color: green;
			border-radius: 50%;
			box-shadow: green 100px 50px, green -100px 50px, green 150px 100px, green -150px 100px;
		}

花朵元素

和云朵一样,使用box-shadow用几个圆圈圈围绕原元素来组合成花朵。对x、y坐标的掌握可以打开控制台,选择想调整的元素,在样式中使用阴影编辑器来可视化地调整阴影位置。 当鼠标移到花朵上时要产生一个旋转效果,可以直接用transform: rotate(30deg)来实现。

QQ截图20230115163123.png

.flower {
			display: inline-block;
			width: 10px;
			height: 10px;
			border-radius: 50%;
			box-shadow: palevioletred 0px -8px, palevioletred 7px -3px, palevioletred -7px -3px, palevioletred -5px 5px, palevioletred 5px 5px;
			background-color: pink;

		}

星星元素

设置一个小小的圆形,调整模糊半径和扩散半径可以让星星有一个发光的效果。

海浪元素

海浪元素的实现思路是利用两个重叠、半径为45%和47%的且透明度不同的盒子在页面的上方不断旋转,将页面的背景色设为海的颜色,盒子设置为天空的颜色,通过盒子的旋转会产生海浪在流动的视觉效果。两个透明度不同的盒子重叠,可以让海浪有层次感。代码参考的是腾讯IMWeb前端团队的纯 CSS 实现波浪效果的代码。

.wave::before,.wave::after {
			content: "";
			position: absolute;
			left: 50%;
			min-width: 300vw;
			min-height: 300vw;
			background-color: rgb(30, 47, 67);
			animation-name: rotate;
			animation-iteration-count: infinite;
			animation-timing-function: linear;
		}

		.wave::after {
			bottom: 12vh;
			opacity: .5;
			border-radius: 47%;
			animation-duration: 10s;
		}

		.wave::before {
			bottom: 15vh;
			border-radius: 45%;
			animation-duration: 10s;
		}

		@keyframes rotate {
			0% {
				transform: translate(-50%, 0) rotateZ(0deg);
			}

			50% {
				transform: translate(-50%, -2%) rotateZ(180deg);
			}

			100% {
				transform: translate(-50%, 0%) rotateZ(360deg);
			}
		}

关于绘制元素的一个想法

在绘制元素的时候思考过如果要给使用box-shadow绘制的简单元素加上阴影要怎么加,思考的结果就是再创建一个一样的元素,调整这个新元素的颜色,设置为纯灰的阴影色,叠在要创造阴影的元素下面,再通过调整阴影元素的位置,就可以做出阴影的效果了。

动画效果

在这个程序中的动画效果主要有动画淡入淡、随机星星闪烁的效果。这几个动画效果使用到了js,对dom元素进行了操作,在这里放一下html的完整代码。

<div class="bg">
		<div class="el" style="opacity: 1;">
			<div class="cloud1"></div>
			<div class="cloud2"></div>
			<div class="cloud3"></div>

			<div class="switch">
				<span style="margin-right:10px;">click me</span>
				<div class="flower"></div>
			</div>
			<div class="text1">
				<p>Hi~ 我是NONI</p>
			<p>我喜欢电影、音乐</p>
		</div>
			<div class="grass0"></div>
			<div class="grass1"></div>
			<div class="grass2"></div>
			<div class="grass3"></div>
			<div class="grass4"></div>
		</div>
		<div class="el2" style="opacity: 0;">
			<div class="text2">
				<p>我来自海边的一个小城市</p>
				<p style="text-align: center;">很高兴遇见你</p>
			</div>
			<div class="wave">
			</div>
		</div>
	</div>

淡入淡出

当点击花朵按钮的时候,第一画面淡出同时第二画面要淡入,我在这里使用了js来实现这个效果。点击事件发生的时候,第一画面的所有元素透明度变为0(原为1),第二画面的元素透明度变为1(原为0),并且点击按钮被移除,因为透明度变0的时候元素还在,所以如果鼠标继续点击画面1就会继续淡出。 来说说淡化的效果实现思路。设置一个定时器,在定时器内在一定时间内不断执行,每次执行都将透明度变低或变高一点,产生一种缓慢变化透明度的效果,关键就在于透明度如何变高和变低,我们可以设置一个变量来控制,在每次定时器执行的时候,这个变量都不断自增或自减,变量范围在0~10之间,将变量除10得到的即使此次执行时元素的透明度。为了防止定时器不断执行,当变量超出范围的时候清除定时器。

        // 淡出效果
	var button = document.querySelector('.switch');
	var el1 = document.querySelector('.el');
	var el2 = document.querySelector('.el2');
	function fadeOut(element,speed) {
		var speed = speed || 30;
		var num = 10;
		var st = setInterval(function () {
			num--;
			element.style.opacity = num / 10;
			if (num <= 0) { clearInterval(st); }
		}, speed);
	}
	// 淡入效果
	function fadeIn(element,speed){
        var speed = speed || 30 ;
        var num = 0;
        var st = setInterval(function(){
        num++;
        element.style.opacity = num/10;
        if(num>=10)  {  clearInterval(st);  }
        },speed);
}
	button.onclick = function () {
		fadeOut(el1, 100);
		fadeIn(el2, 100);
		button.remove();
	}

星星的随机分布和闪烁

要制造出星星一闪一闪的效果,可以通过控制星星的透明度(这里类似淡化效果)来实现,当星星的透明度从1到0又从0到1的时候就可以显示出闪烁的效果。难点就在于如果所有星星一起闪烁这样不能满足我们的需求,所以就要控制随机的星星来实现这个效果,同时我们的星星的位置也是随机的。

首先绘制好星星的样式:

.star {
			position: absolute;
			width: 2px;
			height: 2px;
			border-radius: 50%;
			background-color: gold;
			box-shadow: gold 0 0 5px 1px;
			z-index: 1;
		}

在js中创建星星元素,并为这些元素添加上实现写好的星星基本样式。为了让星星的位置不同,因为是采用绝对定位的方式,所以即控制他们的top与left的不同来实现位置的不同,又因为要随机分配位置,所以我们可以用Math.random()函数来生成随机的top与left的值,再给新生成的星星加上。代码和注释如下:

        //随机分配位置函数
	function changePosition(star) {
		var top = Math.random() * 500;
		var left = Math.random() * 1500;
		star.style.top = top + "px";
		star.style.left = left + "px";

	}
	var arr = new Array();
        //创建星星元素
	for (var i = 0; i < 100; i++) {
		var star = document.createElement('div');//创建星星元素
		star.className = 'star';//给星星元素加上基础样式
		arr.push(star);//把每个新建的元素放入数组,为了后续方便获取各个星星元素
		changePosition(star);//为星星的left和top赋一个随机值,随机分配位置
		el2.appendChild(star);//把元素放入文档流才可以显示

	}

随机闪烁效果的实现需要随机获取星星,同样使用Math.random()来生成随机序列,获取数组中对应的星星元素来加入闪烁的动画效果。 动画效果代码:

@keyframes light {
			0% {
				opacity: 100%;
			}

			10% {
				opacity: 75%;
			}

			20% {
				opacity: 50%;
			}

			30% {
				opacity: 25%;
			}

			40% {
				opacity: 0%;
			}

			50% {
				opacity: 25%;
			}

			60% {
				opacity: 50%;
			}

			70% {
				opacity: 75%;
			}

			100% {
				opacity: 100%;
			}
		}

随机选择星星代码:

setInterval(function () {
                //随机选取50个星星来进行重复闪烁的效果
		for(let j = 0;j < 50;j++){
			let num = Math.floor(Math.random()* arr.length) ;
		arr[num].style.animation = 'light 3s infinite';
		}
	}, 1000);

最后

关于我的程序的介绍就到这里啦。还有很多不足的地方,比如布局这块我还是比较不熟练,在这个程序里使用的是绝对定位的方法,但是这样的在不同大小的屏幕里显示的效果有一定的差异,影响到展示的效果了,后面一定要多熟悉布局的方法。代码很多地方都写得很冗长,不够简洁,看上去比较混乱。还有很多要加强的地方,继续努力(ง •_•)ง