我和我亲爱的祖国(用CSS来为祖国母亲庆生)

“我和个人祖国一刻也不能分割,不管我走到哪里都流出一首赞歌。”javascript

相信你们最近已经被 《我和个人祖国》 这首歌给刷屏了,鱼头每次在听到这首歌的时候,总会感慨万千,咱们伟大的新中国,这70年真的经历了太多太多了。css

可是就是在一代又一代的人不懈的努力下,现在的中国,已经成为了各个国家,乃至西方列强所没法忽视的强大存在。html

从辉煌到屈辱

中国是世界上文明发达最先的国家之一,有将近5000年的有文字可考的历史。前端

曾经,西汉开辟了丝绸之路,经过丝绸链接了从古都长安到罗马帝国这条路上的各个国家;java

曾经,成吉思汗和他的后代,从公元1205年起,前后灭掉了西夏和金朝,而后又征服了中亚、西亚和亚洲西部的许多国家,一直打到欧洲的多瑙河畔。git

可是,从1840年 第一次鸦片战争 开始,中国受了将近100年的屈辱。github

从1840年鸦片战争到1919年五四运动前夕的旧民主主义革命阶段,微信

从1919年五四运动到1949年中华人民共和国成立前夕的新民主主义革命阶段,dom

咱们经历了太多太多。svg

曾经在1936年柏林奥运会69人的表明团因全军覆没,途经新加坡时,被当地报刊讽刺为 “东亚病夫” 。就如同下面的GIF同样,残缺,破损。

dybf

上面GIF的风格被称之为是“故障风(Glitch Effect)”,是近期比较流行的一种设计风格。因此是怎么实现的呢?

思路拆分

<style> .ge-text { position: relative; color: #fff; font-size: 72px; line-height: 1; letter-spacing: 0.01em; transform: scale3d(1, 1, 1); padding: 10px 20px; background: linear-gradient(to right, #232526, #414345); overflow: hidden; } .ge-text::before, .ge-text::after { content: attr(aria-title); position: absolute; left: 0; top: 0; width: 100%; height: 100%; color: #fff; background: linear-gradient(to right, #232526, #414345); clip-path: inset(79px 50px 43px 0px); overflow: hidden; } .ge-text::before { left: 7px; animation: glitch-effect 3s infinite linear alternate-reverse; } .ge-text::after { left: 3px; animation: glitch-effect 2s infinite linear alternate-reverse; } @keyframes glitch-effect { 0% { clip-path: inset(4px 50px 61px 0px); } 5% { clip-path: inset(99px 50px 30px 0px); } ...(省略了不一样百分比下的的值) 95% { clip-path: inset(7px 50px 59px 0px); } 100% { clip-path: inset(79px 50px 43px 0px); } } </style>
<div class="glitch-effect">
    <h1 class="ge-text" aria-title="东亚病夫">东亚病夫</h1>
</div>
复制代码

(重复代码太多,就不所有放出来了,具体实现能够看个人codepen

咱们看上面的GIF,不难发现所谓的故障风就是相同图形不一样的位置跳动。只是都是浮在正常图形之上的跳动,因此看起来有物体故障的感受,抖音的LOGO GIF就是这么个操做。

既然知道这一点,咱们第一步就是作三个如出一辙,可是位置不一样的图形了。

上述DEMO我是用了::before::after,固然,重复的图形,你能够只用一个,或者多个均可以,随你喜欢,就看你喜欢怎样的故障了。

以后的核心就是clip-path: inset@keyframes的配合。

clip-path

clip-path 能够引入或者建立一个指定裁剪区域的强大属性,它在代替了已经弃用的clip属性的同时还多了须要有趣的功能。

本文不打算详细讲解这个属性,有兴趣的能够经过MDN 或者 CSS clip-path 生成器 来深刻了解。

clip-path主要由如下4个可选函数:

函数 做用
clip-path: inset( <shape-arg>{1,4} [round <border-radius>]? ) 用于定义裁剪的矩形区域
clip-path: circle( [<shape-radius>]? [at <position>]? ) 用于定义裁剪的圆形区域
clip-path: ellipse( [<shape-radius>{2}]? [at <position>]? ) 用于定义裁剪的椭圆区域
clip-path: polygon( [<fill-rule>,]? [<shape-arg> <shape-arg>]# ) 用于定义裁剪的多边形区域

下面图示即是用 clip-path: polygon 所画出来的。

clipy

图片来自CSS clip-path 生成器

那么咱们的故障风该如何画呢?

首先咱们来看看clip-path: inset不一样值的状态。

clipy1

上面随手输入了几组值,咱们不难发现,不一样的值所裁剪的区域是不同的,这个时候只要咱们用::before::after去作这个变更的处理,而后给它们各自加上不一样的left值,则会有最上面的效果。

从弱小到强大

从东亚病夫,到金砖四国,再到国家GDP排名全世界前三;

从开国大典红旗冉冉升起,到第一科原子弹爆炸成功,到97香港回归,再到08年奥运会,再到现在,中国经历了太多太多。

因此时常在听到国歌,看到国旗的时候,内心总会百感交集。

提及国旗,咱们不来尝试下用代码来画个五星红旗吗?

具体属性

首先咱们要知道,国旗是五星红旗,旗面为红色,长宽比例为3:2。左上方缀黄色五角星五颗,四颗小星(其外接圆直径为旗高1/10)环拱在一颗大星(其外接圆直径为旗高3/10)的右面,并各有一个角尖正对大星的中心点。

通用尺寸有如下五种:

  1. 长288厘米,高192厘米;
  2. 长240厘米,高160厘米;
  3. 长192厘米,高128厘米;
  4. 长144厘米,高96厘米;
  5. 长96厘米,高64厘米。

国旗墨线图以下:

flag

知道这个以后咱们就能够按照上述的比例去作一画一个五星红旗出来,效果以下:

flag

此效果DEMO核心实现灵感来自此文:前端实现旗帜飘动效果系列 (Ⅰ):dom+css实现,有兴趣的能够去看看原文。

代码实现

因此该如何实现上述红旗飘飘的功能呢?

首先咱们来看伪代码

<style> * { margin: 0; padding: 0; } html, body { height: 100%; width: 100%; } li { list-style: none; } .flag { position: absolute; left: 50%; top: 50%; animation: wave ease-in-out infinite; } .flag > li { height: 100%; float: left; background-image: url("flag.jpg"); background-size: auto 100%; animation: flag ease-in-out infinite; } </style>
<ul id="flag" class="flag"></ul>
<script> 'use strict' const flag = document.querySelector('#flag') const image = new Image() image.src = 'flag.jpg' const flagWidth = 800 const flagHeight = 640 let imgWidth = '' let imgHeight = '' /** * @func * @name 分割图片 * @param sliceCount 切片数量 * @param amplitude 振幅 * @param period 固定周期个数 * @param duration 一个周期的时长 */ const imgRender = ({ sliceCount = 70, amplitude = 20, period = 1.5, duration = 2, }) => {/* 具体生成红旗DOM片断的逻辑 */} image.onload = () => { imgWidth = image.width imgHeight = image.height const ratio = image.width / image.height if (imgWidth > flagWidth) { imgWidth = flagWidth imgHeight = imgWidth / ratio } if (imgHeight > flagHeight) { imgWidth = imgHeight * ratio imgHeight = flagHeight } flag.style.width = imgWidth + 'px' flag.style.height = imgHeight + 'px' flag.style.marginLeft = -imgWidth / 2 + 'px' flag.style.marginTop = -imgHeight / 2 + 'px' imgRender({ sliceCount: 70, amplitude: 20, period: 1.5, duration: 2, }) } </script>
复制代码

所添加的 imgRender 究竟作了什么?

若是大家知道什么是 雪碧图(CSS Sprite) ,这个应该就好理解了,在 HTTP1 的时代里, 雪碧图(CSS Sprite) 是一个很常见的技术概念,因为译名的缘由,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法是将小图标和背景图像合并到一张图片上,而后利用css的背景定位来显示须要显示的图片部分。

CSS雪碧的基本原理是把你的网站上用到的一些图片整合到一张单独的图片中,而后使用CSS backgroundbackground-position 属性渲染。

因此 imgRender 就是作了这么一件事,将红旗图片按等分切割出来,而后进行循环,生成 sliceCount 量的DOM节点,而后添加background-position,这时候的background-position值是跟循环到的下标有关的,具体逻辑其实能够按需去改,以后就是动画属性的配置了。

具体实现能够看鱼头的CODEPEN

Mmmm,本文标题是CSS,其实这里也不算用了JS,毕竟它在这里只是做为一个脚本生成重复的代码,主要核心仍是雪碧图 + animation

SVG版本的红旗

咱们实现了CSS版的五星红旗,那么如今就让咱们来实现一次SVG版本的。

用SVG去处理一些复杂的图案是很是轻松的,咱们只须要知道路径,就能够对它进行操做。

固然咱们该怎么知道路径?这可让咱们的UI设计师从AI中导出SVG,或者去www.iconfont.cn找也能够,以后咱们就能够作咱们想作的操做了。

若是咱们要画上面的红旗,也很是简单。

这里直接上代码:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="600" viewBox="0 0 30 20">
    <defs>
        <path id="s" d="M0,-1 0.587785,0.809017 -0.951057,-0.309017H0.951057L-0.587785,0.809017z" fill="#ffde00"/>
    </defs>
    <rect width="30" height="20" fill="#de2910"/>
    <use xlink:href="#s" transform="translate(5,5) scale(3)"/>
    <use xlink:href="#s" transform="translate(10,2) rotate(23.036243)"/>
    <use xlink:href="#s" transform="translate(12,4) rotate(45.869898)"/>
    <use xlink:href="#s" transform="translate(12,7) rotate(69.945396)"/>
    <use xlink:href="#s" transform="translate(10,9) rotate(20.659808)"/>
</svg>
复制代码

从上面咱们不难看出,这个五星红旗只须要定义一个红色画布,一个星星的轮廓,而后use进去以后给定不一样的位置就能够了。

效果以下:

Hongqi

“五星红旗,你是个人骄傲;五星红旗,我为你自豪;为你欢呼,我为你祝福;你的名字,比我生命更重要;”

写到这里的时候,脑子自动响起了红旗飘飘的旋律。祝愿祖国愈来愈强盛,也祝你们国庆节快乐。

若是你、喜欢探讨技术,或者对本文有任何的意见或建议,你能够扫描下方二维码,关注微信公众号“ 鱼头的Web海洋 ”,随时与鱼头互动。欢迎!衷心但愿能够碰见你。

qrcode-base
相关文章
相关标签/搜索