写点什么

原来 css 也能这么炫酷(二)

  • 2020-01-07
  • 本文字数:4938 字

    阅读完需:约 16 分钟

原来css也能这么炫酷(二)

有没有炫到呢?先贴完整的代码再讲解:

Html:


(温馨提示:左右/上下滑动可查看全部代码)


<section class="container-fluid">       <div id="HD-pictures">           <div class="row pic-banner">               <div class="col-md-6 col-md-offset-3 hidden-sm hidden-xs">                   <div class="img-box">                       <div class="img-mask"></div>                   </div>               </div>           </div>           <div class="pic-content">               <span class="toLeft glyphicon glyphicon-chevron-left"></span>               <span class="toRight glyphicon glyphicon-chevron-right"></span>               <ul class="img-list clearfix">                   <li>                       <div class="ac-img"></div>                       <img width="100%" src="images/section/img-list-1.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-2.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-3.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-4.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-5.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-6.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-7.jpg" alt=""/>                   </li>                   <li>                       <img width="100%" src="images/section/img-list-8.jpg" alt=""/>                   </li>               </ul>           </div>       </div>   </section>
复制代码


Css:


(温馨提示:左右/上下滑动可查看全部代码)


<style type="text/css">   body {     background: #333   }   ul {     padding:0;   }   section #HD-pictures .pic-content {     margin: 0 50px;     overflow: hidden ;     position: relative;   }   section #HD-pictures .pic-content .toLeft,   section #HD-pictures .pic-content .toRight {       position: absolute;       top: 35%;     z-index: 300;     font-size: 50px;     color: rgba(245, 234, 8, 0.2);     cursor: pointer;     transition: .3s;   }   section #HD-pictures .pic-content .toLeft {       left: 0;   }   section #HD-pictures .pic-content .toRight {       right: 0;   }   section #HD-pictures .pic-content .toLeft:hover,   section #HD-pictures .pic-content .toRight:hover {       color: rgba(235, 43, 4, 0.8);   }   section .img-list {     margin: 0;     position: relative;     left: 0px;     transition: .5s;     cursor: pointer;   }   section .img-list > li {       position: relative;       float: left;   }   section .pic-banner > .hidden-sm {       margin-top: 20px;       margin-bottom: 20px;       position: relative;   }   section .img-box {       position: relative;   }   section .img-box > .obj {      position: absolute;   }   section .img-mask {       position: absolute;       width: 100%;       height: 100%;       top: 0;       left: 0;       z-index: 100;   } </style>
复制代码


Js:


(温馨提示:左右/上下滑动可查看全部代码)


$(function () {     +function () {         var ulList = $(".img-list");         var acImg = $('.img-list .ac-img');         var imgBox = $('.img-box');         var moved = 0;//位移数         var movedAimg = 0;//activeIMG的位移数         var liWidth = parseFloat(layout()[0]);         //左右播图         $('.pic-content>span').click(function () {             var sizes = layout();             liWidth = parseFloat(sizes);             if ($(this).hasClass('toRight')) {                 if (moved > -4) {                     moved--;                     ulList.css('left', moved * liWidth + 'px');                 }                 if (movedAimg < 7) {                     movedAimg++;                     acImg.css('left', movedAimg * liWidth + 'px');                     splitShowImg(movedAimg);                 }                 //right             } else {                 //left                 if (moved < 0) {                     moved++;                     ulList.css('left', moved * liWidth + 'px');                 }                 if (movedAimg > 0) {                     movedAimg--;                     acImg.css('left', movedAimg * liWidth + 'px');                     splitShowImg(movedAimg);                 }             }         });
var k = 0; $('.img-list>li>div.ac-img').click(function (e) { e.stopPropagation(); k = parseFloat($('.img-list>li>.ac-img').css('left')) / liWidth; k = parseInt(k, 10); movedAimg = k; }); $('.img-list>li').click(function () { k = $('.img-list>li').index($(this)); movedAimg = k; acImg.css('left', k * liWidth + 'px'); splitShowImg(k); });
var xCount = 10;//水平分割数 var yCount = 6; var animateBase = ['bounce', 'flash', 'pulse', 'rubberBand', 'shake', 'swing', 'tada', 'wobble', 'jello', 'bounceIn', 'bounceInLeft', 'bounceInRight', 'lightSpeedIn', 'flip', 'rollIn', 'bounceInUp'];
function splitShowImg(movedAimg) { var frag = document.createDocumentFragment(); var parentW = parseFloat(imgBox.parent().css('width')).toFixed(4); imgBox.css({ 'width': parentW + 'px', 'height': (parentW * 9 / 16) + 'px' }); var selfH = parseFloat(imgBox.css('height')); for (var m = 0; m < xCount; m++) { for (var n = 0; n < yCount; n++) { var no = parseInt(Math.random()*(animateBase.length), 10); var div = $(`<div class="obj animated ${animateBase[no]}"></div>`); div.css({ 'width': (parentW / xCount).toFixed(0) + 'px', 'height': (parseFloat(imgBox.css('height')) / yCount).toFixed(0) + 'px' }); var l = m * parseFloat(div.css('width')).toFixed(0); var t = n * parseFloat(div.css('height')).toFixed(0); var bannerImg = $('.img-list img').eq(movedAimg); var url = bannerImg.attr('src'); div.css({ 'top': t + 'px', 'left': l + 'px' }); div.css({ 'background': `url("${url}") no-repeat -${l}px -${t}px / ${parentW}px ${selfH}px` }); $(frag).append(div[0]); } } $('.img-box').append($(frag)); }
splitShowImg(movedAimg); }(); //布局 function layout() { var boxW = parseFloat($(".pic-content").css('width')); var lis = $(".img-list>li"); lis.css('width', boxW * 0.25 + 'px'); var ulW = parseFloat(lis.eq(0).css('width')) * lis.length + 10 + 'px'; $(".img-list").css('width', ulW); return lis.eq(0).css('width'); }});
复制代码


大家看了代码是否觉得实现起来很简单呢,这个是一个精简版的,最初设计的是一个响应式的轮播,每个小方块都会按不同的屏幕宽度去排列,不过这不是重点,我们只需要关注 splitShowImg 这个函数,他接受一个 img,然后就可以分割这个 img 为我们指定数量的小方块,然后每个小方块以随机漂移的动画从分散状态组装为一个完整的大图。我们这里分为了 60 个小方块。


关键实现点:


(温馨提示:左右/上下滑动可查看全部代码)


var animateBase = ['bounce', 'flash', 'pulse', 'rubberBand', 'shake',             'swing', 'tada', 'wobble', 'jello', 'bounceIn', 'bounceInLeft',             'bounceInRight', 'lightSpeedIn', 'flip', 'rollIn','bounceInUp'   ];

复制代码


这里我们定义一个‘动画库’,里面的每一个元素都是 animate 这个动画库提供的类名,然后我们生成一个 0 到数组长度的随机数


(温馨提示:左右/上下滑动可查看全部代码)


var no = parseInt(Math.random()*(animateBase.length), 10);
复制代码


接下来要生成一个小方块:


(温馨提示:左右/上下滑动可查看全部代码)


var div = $(`<div class="obj animated ${animateBase[no]}"></div>`); div.css({            'width': (fatherW / xCount).toFixed(0) + 'px',         'height': (parseFloat(imgBox.css('height')) / yCount).toFixed(0) + 'px'        }); var l = m * parseFloat(div.css('width')).toFixed(0); var t = n * parseFloat(div.css('height')).toFixed(0); var bannerImg = $('.img-list img').eq(movedAimg); var url = bannerImg.attr('src'); div.css({             'top': t + 'px',             'left': l + 'px'        }); div.css({              'background': `url("${url}") no-repeat -${l}px -${t}px / ${fatherW}px ${selfH}px`        });
复制代码


这里就是重点所在了,我们根据展示大图区域的大小计算出每个小方块的尺寸,然后再利用绝对定位的偏移量结合自身尺寸做排列,这样就完成了小方块的布局,最后最关键的就是 background 了,我们这里用简写,规则如下:


background: img_url repeat position / size


也就是background-img、background-repeat、background-position、background-size
复制代码


看到这里你是不是就很明白了呢?简单来说就是利用 background-position、background-size 和定位来实现,background-size 是关键点,它可以保证整个背景图片的大小和布局区域相同,这样就可以等比的赋予每一个小方块对应位置的背景图片,这是 css3 的新属性,详细请参考(如无法打开,请复制链接到浏览器) http://www.w3school.com.cn/css3/css3_background.asp


写了这么久的 css 是不是现在才发现,原来简单的背景图片和绝对定位也可以这样玩?


最后,虽然这种做法看着很炫,但是实际项目中我们却很少这样做,一方面是因为很多样式都是 css3 的新特性,浏览器兼容问题难以解决,更重要的一方面就是这样大量的操作 dom 带来的性能问题是十分严重的,我们只是切了 60 份已经很明显的感觉到切图时略微卡顿,要是再多,页面直接就崩溃了。


我想要表达的其实是很多特效只要我们有想法,肯大胆去创新,最普通的样式组合起来就有可能成为最炫酷的效果。


本转载自 Think 体验设计公众号。


原文链接:https://mp.weixin.qq.com/s/U9sFGG6ZWzh9E4kKUm41ZA


2020-01-07 15:39625

评论

发布
暂无评论
发现更多内容

老生常谈React的diff算法原理-面试版

beifeng1996

React

产品的可持续发展

ShineScrum捷行

产品 产品负责人 产品的可持续发展

A-Ops性能火焰图——适用于云原生的全栈持续性能监测工具

openEuler

Linux 运维 操作系统 定位 性能监控

手写JS函数的call、apply、bind

helloworld1024fd

JavaScript

阿里前端必会手写面试题汇总

helloworld1024fd

JavaScript

从react源码看hooks的原理

flyzz177

React

问:React的setState为什么是异步的?

beifeng1996

React

实现一个简单的Database9(译文)

GreatSQL

sqlite greatsql greatsql社区

20个 Git 命令玩转版本控制

SEAL安全

git 企业号 2 月 PK 榜 git command

前端react面试题指南

beifeng1996

React

百度前端常考vue面试题(附答案)

bb_xiaxia1998

Vue

焕新启航,「龙蜥大讲堂」2023 年度招募来了!13 场技术分享先睹为快

OpenAnolis小助手

直播 开源社区 龙蜥大讲堂 机密计算 月度主题

深入React源码揭开渲染更新流程的面纱

goClient1992

React

基于昇腾计算语言AscendCL开发AI推理应用

华为云开发者联盟

人工智能 华为云 昇腾 企业号 2 月 PK 榜 华为云开发者联盟

前端react面试题(边面边更)

beifeng1996

React

用Docker搭建更酷的本地开发环境

致知Fighting

Java Docker Linux 后端 开发

Vue.$nextTick的原理是什么-vue面试进阶

bb_xiaxia1998

Vue

深度分析React源码中的合成事件

goClient1992

React

手写一个react,看透react运行机制

goClient1992

React

promise执行顺序面试题令我头秃,你能作对几道

loveX001

JavaScript

零基础入门AI?先来把机器学习捣鼓明白吧

博文视点Broadview

高级前端二面vue面试题(持续更新中)

bb_xiaxia1998

Vue

vivo 自研Jenkins资源调度系统设计与实践

vivo互联网技术

运维 jenkins 资源调度

前端一面常考手写面试题整理

helloworld1024fd

JavaScript

从recat源码角度看setState流程

flyzz177

React

Vue的computed和watch的区别是什么?

bb_xiaxia1998

Vue

面试官问我:CSS有哪些属性可以继承

华为云开发者联盟

前端 华为云 企业号 2 月 PK 榜 华为云开发者联盟

前端必会面试题

loveX001

JavaScript

怎样徒手写一个React

helloworld1024fd

JavaScript

QCon演讲实录(上):多云环境下应用管理与交付实践

阿里云大数据AI技术

大数据 运维 企业号 2 月 PK 榜 云环境

5分钟体验代码仓托管、CloudIDE云端代码编辑、调试、运行

华为云开发者联盟

云计算 华为云 企业号 2 月 PK 榜 华为云开发者联盟

原来css也能这么炫酷(二)_语言 & 开发_Think体验设计_InfoQ精选文章