哈喽,大家好呀~,520即将到来,大家都是怎么过呀,有没有心仪的对象呀?有的话可以把这 HTML 表白biu 发给那个他(她),没有的话也可以拿去表白呀~;话不多说,下面呢我们来看看代码实现的效果吧。
首先我们来看看效果是怎样的。
实现思路
我们有个 GIF 图,让它自己自动播放,进度条随着变化跟着变化 ,设置个数组,记录每个小爱心的位置,让它们逐一显示(总体来看就是,有两个盒子(div)上下结构,一个盒子(div)装小人与爱心(小人与爱心又是两个盒子(div)),另一个盒子(div)装最下面的进度条)。
HTML实现部分
🎆先看 HTML 部分与 CSS 的部分,在左边有个 GIF 让他自己自动播放
<div class="body_left"> <img src="images/biubiubiu.gif" alt="" ondragstart='return false;'> <!-- ondragstart:开始拖动元素时发生。--> </div>
.body_left { width: 300px; height: 300px; left: 0; bottom: 110px; position: absolute; z-index: 98; }
CSS 实现部分
🎆再设置其他 CSS 属性例如内外边距、宽度高度等。
* { margin: 0; padding: 0; border: 0; } .icon-love { width: 400px; } html, body { width: 100%; height: 100%; } body { /*background-color: skyblue;*/ overflow: hidden; /*隐藏超出的部分*/ } .container { width: 100%; height: 100%; position: relative; }
🎆中间的爱心部分 HTML 部分与 CSS 的部分
<div class="body_center love"> <div class="block"> <div class="div1"></div> <div class="div2"></div> <div class="div3"></div> <div class="div4"></div> </div> </div>
.container .love { width: 520px; /* 13 * 40 */ height: 440px; /* 11 * 40 */ left: 50%; top: 50%; position: absolute; margin: -260px 0 0 -220px; /*background-color: gray;*/ } .love .block { right: 0; position: absolute; visibility: hidden; /*未开始升空动画前隐藏*/ background-color: yellow; } .love .block div { width: 40px; height: 40px; position: absolute; background: url("../images/heart.png") no-repeat; background-size: contain; /*background-color: #c40908;*/ /*border: 1px solid silver;*/ box-sizing: border-box; }
🎆一个大的 div 我们已经写好了,下面是页脚(进度条的展示)。
<div class="footer"> <div class="border"> <div class="border-top"></div> <div class="border-bottom"></div> </div> </div>
.footer { bottom: 30px; position: relative; z-index: 99; } .footer .border .border-top { /*width: 0;*/ /*display: inline-block;*/ border-top: 3px solid black; transform-origin: left center; -webkit-animation: border 312 linear; -o-animation: border 12s linear; animation: border 12s linear; animation-fill-mode : both; /*border-bottom: none;*/ } .footer .border .border-bottom { /*width: 0;*/ /*display: inline-block;*/ float: right; border-top: 3px solid red; transform-origin: right center; -webkit-animation: border 7s linear 12s; -o-animation: border 7s linear 12s; animation: border 7s linear 12s; animation-fill-mode : both; /*border-bottom: none;*/ } .footer .copyright { width: 100%; height: 30px; position: absolute; bottom: -30px; text-align: center; /*background-color: gray;*/ } .copyright div { width: 30%; line-height: 30px; display: inline-block; } .copyright div span { color: dimgray; }
🎆然后我们需要设置动画的效果
@keyframes border { 0% { width: 0; } 5% { width: 5%; } 10% { width: 10%; } 15% { width: 15%; } 20% { width: 20%; } 25% { width: 25%; } 30% { width: 30%; } 35% { width: 35%; } 40% { width: 40%; } 45% { width: 45%; } 50% { width: 50%; } 55% { width: 55%; } 60% { width: 60%; } 65% { width: 65%; } 70% { width: 70%; } 75% { width: 75%; } 80% { width: 80%; } 85% { width: 85%; } 90% { width: 90%; } 95% { width: 95%; } 100% { width: 100%; } }
JavaScript 实现部分
🎆最后我们来看看 JS 代码
const blk_pitn = { //各小方块相对【自身中心】的位置 -- 【自身中心】确定为#div22的方块 block1: [[0, 1], [0, 0], [-1, 0], [-1, -1]], block2: [[0, 1], [0, 0], [-1, 0], [0, -1]], block3: [[-1, 1], [0, 0], [-1, 0], [-1, -1]], block4: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block5: [[-1, 1], [0, 0], [-1, 0], [0, -1]], block6: [[0, -1], [0, 0], [-1, 0], [1, -1]], block7: [[-1, -1], [0, 0], [-1, 0], [1, 0]], block8: [[-1, 1], [0, 0], [-1, 0], [-1, -1]], /* 3 */ block9: [[0, -1], [0, 0], [-1, 0], [1, 0]], block10: [[-1, 1], [0, 0], [-1, 0], [1, 0]], block11: [[2, 0], [0, 0], [-1, 0], [1, 0]], /* — */ block12: [[0, 1], [0, 0], [-1, 0], [0, -1]], /* 2 */ block13: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block14: [[1, 1], [0, 0], [-1, 0], [1, 0]], block15: [[1, -1], [0, 0], [-1, 0], [1, 0]], block16: [[-1, -1], [0, 0], [-1, 0], [1, 0]], /* 7 */ block17: [[0, 1], [0, 0], [-1, 0], [0, -1]], /* 2 */ block18: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block19: [[0, -1], [0, 0], [-1, 0], [1, 0]], /* 9 */ block20: [[1, -1], [0, 0], [-1, 0], [1, 0]], block21: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block22: [[1, 1], [0, 0], [-1, 0], [1, 0]], /* 14 */ block23: [[0, 2], [0, 0], [0, -1], [0, 1]] /* | */ }, offset_pitn = { //各方块block相对【爱心中心】的位置 block1: [5, 3], block2: [5, 1], block3: [3, 4], block4: [3, 2], block5: [3, -1], block6: [2, 5], block7: [2, 1], block8: [1, -1], block9: [1, -3], block10: [1, 2], block11: [0, 3], block12: [0, 0], /* 【爱心中心】*/ block13: [-1, -4], block14: [0, -2], block15: [-2, 4], block16: [-2, 2], block17: [-2, 0], block18: [-3, -2], block19: [-4, 0], block20: [-3, 5], block21: [-5, 3], block22: [-4, 1], block23: [-6, 1] /* 因动画需要移动一个方块,故y轴坐标-1*/ }; let blocks = document.getElementsByClassName("block"), block = blocks[0], love = document.getElementsByClassName("love")[0], timer = null, index = 0, //记录拼接爱心的动画步骤 clone_block; //用于克隆方块 //1.移动方块的【自身中心】到【爱心中心】 block.style.top = "50%"; block.style.left = "50%"; block.style.margin = "-20px 0 0 -20px"; const block_left = parseFloat(window.getComputedStyle(block, null).left.slice(0, -2)), //【爱心中心】 左边距离父元素的距离 block_top = parseFloat(window.getComputedStyle(block, null).top.slice(0, -2)); //【爱心中心】 顶部距离父元素的距离 function Next() { if (++index >= 24) { clearInterval(timer); Rise(); // alert("已经是最后一个了!"); return; } block.style.visibility = "visible"; //升空动画前允许可见 //2.移动方块到指定的位置-即是移动【自身中心】到目标位置 block.style.left = block_left + 40 * offset_pitn["block" + index][0] + "px"; block.style.top = block_top - 40 * offset_pitn["block" + index][1] + "px"; for (let i = 0; i < block.children.length; i++) { // block.children[1].innerText = index; //编号便于调试 block.children[i].style.left = blk_pitn["block" + index][i][0] * -40 + "px"; /* -40 是因为逻辑坐标和浏览器的x,y轴方向不一样*/ block.children[i].style.top = blk_pitn["block" + index][i][1] * -40 + "px"; } //3.克隆方块—保存现在的位置 /* 一共会克隆23个方块,加上原先的一个方块block,共24个方块,即多出原先的block方块*/ clone_block = block.cloneNode(true); love.appendChild(clone_block); if (love.children.length >= 24) { blocks[blocks.length - 1].children[2].style.display = "none"; //去掉多余的小方块 block.style.display = "none"; //隐藏多出的block方块 } } function Rise() { //4.爱心升高,多出的那个小方块开始掉落 console.log("开始升空"); let timer2 = null, distance = 0; /* 升高时,移动的距离*/ const target = 120, /* 目标距离*/ speed = 1; /*移动速度*/ let love_top = parseFloat(window.getComputedStyle(love, null).top.slice(0, -2)); //爱心盒子距离屏幕顶部的距离 timer2 = setInterval(() => { distance += speed; // console.log(distance); if (distance >= target) { clearInterval(timer2); console.log("升空完毕"); } love.style.top = (love_top - distance) + "px"; }, 22); } window.onload = function () { setTimeout(() => { timer = setInterval(() => { Next(); }, 300); }, 12000); //gif图播放完毕所需时间为11.73s };
注意:
这里有个小细节,我们无论是内部引入 js 文件还是外部引入 js 文件,我们要把 js 放在 html 的下面,让页面先显示出页面内容,再加载 js 代码展示效果,如果不这样的话会导致页面效果加载过慢,严重时可能造成页面空白。
(求关注)持续更新中……