目录
PS切图
前端开发的大部分时间里都需要做网页重构,即把设计师提供的设计稿还原成网页代码,还原代码的过程就是切图+码代码
切图不仅是一门技术活,还是一门手艺活,要力求实用和低功耗
切图的准备工作
工具介绍
Photoshop
版本选择
PhotoshopCS4
缓存路径更改
最好不要存在C盘,使用久了会使系统内存负重太大
编辑-菜单-首选项-性能,将暂存盘改为除了C盘之外的其他盘
默认单位修改
网页中元素使用的默认单位是px,用Photoshop切图最好单位也设置为px
编辑-菜单-首选项-单位与标尺,将标尺和文字的单位都修改为像素
Photoshop预设
视图-标尺,窗口-段落/图层/信息/工具
常用工具
启用选择工具时,左上角的自动选择工具可以选择对图层进行操作,也可以对一组图层进行操作,图层中一个文件夹代表一个组
启用裁剪工具时,信息中显示选取的宽度和高度
启用字体工具并将光标点击至效果图中有文字的地方,字符信息中显示字体和字体颜色、大小、行高等信息
放大缩小图层:Alt+滚轮
撤销操作:Ctrl+Alt+Z
合并图层:Ctrl+E
图层面板的使用
点击图层面板中,不需要显示的图层左边的眼睛,可以隐藏这些图层
要使图层覆盖在另一个图层上面,可以交换图层面板中图层排列的顺序
借助辅助线辅助切图
网页设计师设计网页时往往有个视野宽度在0~1200px之间,并且是居中的,视野区外往往是一些不重要的内容
如何借助辅助线辅助切图?
启用移动工具拉取辅助线到合适的位置,再用裁剪工具,这时候裁剪区就会自动吸附到辅助线上
如何裁剪出背景为透明的可供使用的logo图?
新建一个透明图层,将裁剪出来的logo图拖拽到该透明图层上,点击图像-裁切,基于-透明像素,就能把没有颜色的区域都裁减掉
制作一个背景为透明的包含多图层的图片时,可以先合并图层再进行拖拽,也可以直接用裁剪工具裁剪下来,再进行拖拽
存储的格式
- jpeg可以设置图片品质,但不能处理背景图片为透明的图片
- png24不能被IE低版本浏览器所支持,图片会模糊,背景会被填充颜色,但png24可以利用js手段使得它在IE浏览器上也能正常显示出来
- png8饱和度不如png24
- wbmp是位图格式,不经常使用
裁切详解
切片工具可以一次性裁剪多个图片并一键生成,裁切完成后,点击文件-存储为Web所用格式,存储。它会自动生成一个images的文件夹,里面是我们刚刚裁切的图片,但是它的效率很低,因为实际开发中往往不需要切那么多图,用css样式就可以实现同样的效果。
字体设置
如果我们电脑中没有设计稿上应用的字体,可以将这个字体下载下来,打开控制面板-字体,将字体文件拖拽进去,就成功在我们电脑上安装好新的字体,这时只需重启Photoshop就可以使用这个字体了。
总结
切图的优化
3秒定律
如果用户加载一个网页超过3秒,那么他就会关闭这个网页,导致我们丢失流量。
由于图片也要耗费资源,因此网页开发中图片越少越好。
利用样式平铺效果颜色代替图片
一些图片如果是自身的平铺图,就只需将宽度设置为1px并存储,在css中引用时设置实际宽度来进行平铺即可。
能够用css样式实现的效果,就不用图片来显示。
雪碧图的制作
使用“雪碧图”能够减少资源的耗费,将要使用的多个图片集中在一个背景为透明的png上,再用定位手段来显示我们想要的区域,这样一来,图片资源就只需加载一次。
字体图标的使用
以文字的形式代替图片的使用,现在很多图标库可以实现很多图片,就可以代替图片的使用。
快捷键的使用
实际开发过程中,敏捷开发才是第一生产力,要学会使用快捷键,这样可以加快开发速度,提高开发效率。
操作类快捷键
删除图层:delete
合并图层:Ctrl+E
工具类快捷键
移动:V
裁切:C
快捷键失效
可能是一些快捷键被输入法软件和QQ程序占用
切图辅助工具
Markman
可以帮助我们快速测量图中的颜色、字体代销、字体和文字之间的间距
TinyPNG
用于压缩png图片的大小
前端自动化
与中高级前端有关,可以快速生成雪碧图
宣传页项目
前端开发流程
产品经理做需求分析→视觉交互做视觉设计、交互动画设计→前端开发做前端静态页开发、动画效果开发
相关工具
编辑器:subline3
标注工具:pxcook
切图工具:Photoshop
开发前的准备工作
视觉设计稿PSD
设计图标注
PS切图
雪碧图(http://alloyteam.github.io/gopng/)
页面内容和样式
开发技巧
从大到小
BEM开发模式
BEM代表块(Block),元素(Element),修饰符(Modifier)
模块(没有前缀,多个单词用 - 连接)
元素(元素在模块之后,可以有多个层级,以__连接)
修饰(某元素、或者某模块特别的状态,必须有一个状态名和状态值,使用 _ 连接)【比如某个标签的高亮状态】
居中法小结
文字垂直居中
将文字行高设置为与容器的高度一致
.item{
height:38px;
line-height:38px;
}
块元素垂直居中于父元素
给父元素设置为相对定位,子元素设置为绝对定位,距离顶部top50%的高度,margin-top为负的元素高度的一半
.father{
position:relative;
}
.child{
position:absolute;
height:38px;
top:50%;
margin-top:-19px;
}
块元素水平居中
.item{
width:38px;
margin:0 auto;
}
网页动态效果
CSS动画背景知识
- 新的选择器,如:div:last-child(div节点下面的最后一个直接子节点)
- 多列布局,如:-webkit-column-count:3(就不必再用float)
- 圆角:bordder-radius
- 渐变背景图:background-image:-webkit-gradient(liner,0% 0%,100% 0%,from(#2A8BBE),to(#FE280E));
- transfrom
- transitions
- animation
CSS实现动画的两种方式
- transition:all 1s;(选择器中所有元素都在1s内完成变化)
- -webkit-animation:rock 2s infinite ease-in-out .5s;
动画效果测试脚本工具
用鼠标点击模拟页面模块切换
用添加、移除class名的方法在给元素设置动画始末状态的样式
测试脚本小结
两种遍历,遍历对象{ },遍历数组[ ]
获取元素querySelector(一个元素)
字符串截取substr、字符串替换replace
CSS动画小结
构建复杂动画
CSS伪类的使用及触发动画效果
网页交互效果
帧动画定义→帧动画使用
背景图覆盖模式
.bg{
background-size:cover;
}
作业
要点
-
载入页面时,导航栏自上而下飘至视口顶部
先用transform中的translate把导航栏的默认样式设置为距离顶部为负的导航栏本身的高度。载入页面时,给导航栏添加init样式,仍用transform中的translate设置为与顶部的距离为0。用transition实现两个样式的过渡效果,并将导航栏的position设置为fixed,z-index在最高层。
<!-- 基本样式 -->
.header__wrap{
width: 100%;
height: 60px;
position: fixed; <!-- 固定在视口顶部 -->
margin: 0 auto;
background:linear-gradient(rgba(0,0,0,.8),rgba(255,255,255,0)); <!-- 渐变效果 -->
z-index: 999;
}
<!-- 动画效果 -->
<!-- 默认样式 -->
.header__wrap{
transition: all 1s;
transform: translate(0,-60px); <!-- 用translate进行相对定位,使页面载入前默认在视口顶部以上,不可见 -->
}
<!-- init样式 -->
.header__wrap_animate_init{
transform: translate(0,0); <!-- 用translate进行相对定位,使页面载入时过渡至视口顶部 -->
}
<!-- done样式 -->
.header__wrap_animate_done{
transform: translate(0,0); <!-- 这句是为了不让元素样式在后来整体页面元素状态切换中受到影响 -->
}
<!-- 滚动滑动条时导航栏变色 -->
.header__wrap_status_black{
background-color: rgba(0,0,0,.5);
}
- 载入页面时,自动播放第一屏的动画
由于刚载入时,并不会发生滚动条滚动事件,也就不会去调用onscroll中第一屏的done函数,因此要使页面一加载完成就播放第一屏的动画,需要先将第一屏的元素事先设置成init状态,然后在js文件中调用第一屏的done函数。
//载入页面时将所有屏幕设置为init状态,除了screen-1
window.οnlοad=function(){
for(k in screenAnimateElements){
if(k==='.screen-1') continue; //第一屏不在这里初始化,而是在css中加上init样式,并通过setTimeout来切换成done
setScreenAnimateInit(k);
}
//获取滚动条高度
var top=document.body.scrollTop;
//第一屏
if(top>0&&top<1*640-150){
playScreenAnimationDone('.screen-1');
switchNavItemsAcitve(0);
navTip.style.left=40+'px';
}
//...
}
//调用setTimeout函数,载入页面0.2s后将第一屏由init切换成done(init是在css文件中设置好了的)
setTimeout(function(){
playScreenAnimationDone('.screen-1');
},200)
其实有一个更简单的方法,直接把第一屏播放的条件由top>0改成top>=0,就可以不需要再单独去调用第一屏的done函数,也不需要在初始化时在css中单独去给第一屏元素设置init,而是像其他屏一样在载入时就用init函数去初始化。
window.οnlοad=function(){
for(k in screenAnimateElements){
if(k==='.screen-1') continue; //第一屏不在这里初始化,而是在css中加上init样式,并通过setTimeout来切换成done
setScreenAnimateInit(k);
}
var top=document.body.scrollTop;
//top>=0就可以在页面刚载入时就将init切换成done
if(top>=0&&top<1*640-150){
playScreenAnimationDone('.screen-1');
switchNavItemsAcitve(0);
navTip.style.left=40+'px';
}
//...
}
- 载入页面时,导航栏的active元素默认是第一个
在css文件中给第一个元素设置status_active样式(文字highlight),并且用将滑动门设置在第一个元素的位置。
不在css文件中设置也可以,只要top=0就会调用switchNavItemsActive(0)来设置也能达到同样的效果。
window.οnlοad=function(){
for(k in screenAnimateElements){
if(k==='.screen-1') continue; //第一屏不在这里初始化,而是在css中加上init样式,并通过setTimeout来切换成done
setScreenAnimateInit(k);
}
var top=document.body.scrollTop;
if(top>=0&&top<1*640-150){ //重点是这里的top=0
playScreenAnimationDone('.screen-1');
switchNavItemsAcitve(0); //文字highlight
navTip.style.left=40+'px'; //滑动门滑至第一个元素的位置
}
//...
}
- 进入不同的屏幕时,自动播放相应的动画
- 进入不同的屏幕时,导航栏/大纲的active元素随之改变
/* 播放屏内的元素动画的函数 */
var playScreenAnimationDone=function(screenCls){
//播放动画,改init为done
var screen=document.querySelector(screenCls); //获取当前屏对象
var animateElements=screenAnimateElements[screenCls]; //需要设置动画的元素
for (var i=0;i<animateElements.length;i++) {
var element=document.querySelector(animateElements[i]); //遍历当前屏的所有元素
var baseCls=element.getAttribute('class'); //先取出初始的class名(含init样式)
element.setAttribute('class',baseCls.replace('_animate_init','_animate_done'));
//把init样式替换成done样式
}
}
//获取导航栏元素
var navItems=getAllElem('.header__nav-item');
//获取大纲元素
var outlineItems=getAllElem('.outline__item');
//删除所有元素的active样式,再给当前元素设置active样式
var switchNavItemsAcitve=function(index){
for(var i=0;i<navItems.length;i++){
delCls(navItems[i],'header__nav-item_status_active');
delCls(outlineItems[i],'outline__item_status_active');
}
addCls(navItems[index],'header__nav-item_status_active');
addCls(outlineItems[index],'outline__item_status_active');
}
/* 在载入时调用样式init方法 */
window.οnlοad=function(){
for(k in screenAnimateElements){
if(k==='.screen-1') continue;
//第一屏不在这里初始化,而是在css中加上init样式,并通过setTimeout来切换成done
setScreenAnimateInit(k);
}
var top=document.body.scrollTop;
//根据滚动条高度来判断当前位于哪个屏幕,并调用相应的done函数和switchNavItemsActive函数,改变滑动门位置
if(top>=0&&top<1*640-150){
playScreenAnimationDone('.screen-1');
switchNavItemsAcitve(0);
navTip.style.left=40+'px';
}
else if(top>=1*640-150&&top<2*640-150){
playScreenAnimationDone('.screen-2');
switchNavItemsAcitve(1);
navTip.style.left=(40+1*101)+'px';
}
else if(top>=2*640-150&&top<3*640-150){
playScreenAnimationDone('.screen-3');
switchNavItemsAcitve(2);
navTip.style.left=(40+2*101)+'px';
}
else if(top>=3*640-150&&top<4*640-150){
playScreenAnimationDone('.screen-4');
switchNavItemsAcitve(3);
navTip.style.left=(40+3*101)+'px';
}
else{
playScreenAnimationDone('.screen-5');
switchNavItemsAcitve(4);
navTip.style.left=(40+4*101)+'px';
}
}
- 点击导航标签或大纲标签时,定位至对应的屏幕
var setJump=function(i,lib){
var item=lib[i];
item.οnclick=function(){
document.body.scrollTop=i*640; //滚动条高度的写入
}
}
for(var i=0;i<navItems.length;i++){
setJump(i,navItems);
}
for(var i=0;i<outlineItems.length;i++){
setJump(i,outlineItems);
}
- 鼠标移向导航中的某个元素时,滑动门滑至该元素,鼠标移走时,滑动门滑回当前屏对应的导航元素
//获取滑动门元素
var navTip=getElem('.header__nav-tip');
//初始位置有偏移,先进行调整
navTip.style.left=40+'px';
var setTip=function(index,lib){
lib[index].οnmοuseοver=function(){
//鼠标滑入,定位至相应的导航标签
navTip.style.left=(40+index*101)+'px';
}
//鼠标移出,找到当前页面对应的导航标签,将滑动门移至该标签下
var activeIndex=0;
lib[index].οnmοuseοut=function(){
for(var i=0;i<lib.length;i++){
/* 找到当前选中的元素,是被激活的元素 */
if(getCls(lib[i]).indexOf('header__nav-item_status_active')>-1)
{
activeIndex=i;
break;
}
navTip.style.left=(40+activeIndex*101)+'px';
}
}
//给每个导航元素添加滑动事件
for(var i=0;i<navItems.length;i++){
setTip(i,navItems);
}
总结
滑动门的位置是用navTip.style.left来控制的,它与active的不同之处在于:鼠标滑入时会跟着鼠标走,即获取当前鼠标移入的导航标签(传入函数的index),修改navTip.style.left,使滑动门滑动到鼠标所指的位置,当鼠标移出又回到当前屏对应的导航标签(遍历导航标签,找到当前设置了active样式的元素,记下其索引值,并修改navTip.style.left),由于这些操作都是对navTip.style.left进行修改,所以每次滑动门只会在一个位置,不会出现多个滑动门。而active只根据scrollTop来确定当前屏幕。
待改进
希望通过滚动条、导航、大纲进入某个屏幕时,都能重新播放动画,而不是只能有一次init→done,过后就不再生效
改进思路
滚动条每到一个屏幕区域时,就将其他屏幕再次设置为init状态,只有当滚动条再次移动到这些屏幕区域时,才将init状态改为done状态。个人觉得这样做有点麻烦,但是目前没有想到更好的方法。
成品图