手记

【活动】HTML5+CSS3实现春节贺卡(笔记整理)

春节没什么事把HTML5+CSS3实现春节贺卡笔记整理下

本文的内容大部分都是个人的理解,可能有很多不恰当或是错误的地方,如果大家发现的不对的地方,欢迎指出,本人不胜感激。本文对有些知识点还有很多的参考文章,都是引用,为了保证作者的权益都只给出链接地址,不会复制文章内容。文中列出的所有CSS代码都不考虑兼容,都没有添加浏览器前缀,请自行添加,笔记内容也不会完全按照老师讲课的顺序来列出,有极少量的调整,老师这个教程定位的是中级教程,所以很多的知识点都是直接用,我会对部分知识点作 个简单的说明,方便初级开发者更方便的学习,谢谢。

课程介绍部分,大家听一下就好了,此处略过。。。。

设计图的分析
一般我们在做开发时,都是由设计师设计好PSD图给到我们,然后我们自己去做切图,也有部分设计师是切好图给到我们,在这里我更偏向于自己来切图,因为有时设计师切的图并不是我们想要的,有时我们本想切到同一张图上的,她给切成了多个,我们还得用代码拼到一起,有时我们需要切开的,她却给切到一张上,我们就得自己重新切一次。设计师并不知道我们的代码怎么写,怎么切更方便写代码,所以她们切的图就不方便我们来写代码,如果我们告诉他们哪里应该怎么切,还不如我们自己来切的方便,因为沟通也是很耗时。所以还是自己切的方便。当我们拿到设计图时,一定要先看一下所有的图,首先是他们的图层会的是不是清晰,比喻每一个页面放到一个文件夹内,这样我们选中一个文件平就能看到一个完整的页面,看起来就很方便,我曾经就看到过有的设计图根本就没有文件夹,所有的图层就是平级的,还是多个页面放在一起,结果只想看一个页面,你根本就不知道应该选中哪些图层,等你一个页面点出来半天就过去了。还有就是页面效果是不是我们都可以实现,可能有些设计我们用代码很难去实现,至少以我们现的水平很难去实现,(即使别人已经实现,但你又看不到源码,也不知道是怎么实现的),等等,只要是对我们开发有困难的地方,一定要及时提出,和设计师沟通,看看他们是不是有其他的方案可代替,如果是图层乱放,这个不是协商,是必须要求她重做。这样下来就能为我们开发清除很多的障碍,千万不要等开发了一半,才发现开发不下去,那样问题就大了。
开发前一定要确认需求,否则等你开发完才发现和需求不一致就麻烦了。需求确认清楚了,一定要选好全适的开发技术,这个对开发效率和维护成本都有很大的帮助。我们在开发过程中一定要考虑程序的性能,性能方面一定要考虑清楚,尤其是移动项目的开发。

开发工具的说明
老师在写代码时,一下子就出现了一大堆的代码,有些初学者可能不知道是怎么实现的,老师用的是sublime的编辑器,里面用到了很多的快捷输入,基本都是用到了 emmet插件的功能,sublime的插件安装方式和使用可参考Sublime Text 3常用插件安装(含Emmet插件指令介绍)

HTML代码实现
编写代码前一定要设置好viewport,老师把这一讲放到了最后,我个人觉得这个不是很合适,因为这个可以影响到代码的具体展现,我们必须在viewport设置好的基础上还编写我们的效果,才是最终效果。否则当我们写好代码再来添加这个就会发现很多的代码是多余的,甚至有负作用的。有些本来是可以添加viewprot就好了的效果,因为我们开始没有加viewport,就会用代码去调很久,浪费时间不说,最后可能还发现,当我们加了viewport后,本来调好的代码又会乱掉。接下来就是开始编写代码了,在html中代码的结构一定要清晰,让别人直接看html就知道哪一块代码是干什么用的,不要添加一些无用的标签,比喻老师那第二页的三个圈就只用了一个div就是一个很好的经验。用before和after伪类去实现内层和外层的圈,而我们自己经常就是3个div或3个span来做,这样就会多出2个标签。因为我们这个页面结构比较简单,所以老师都用了div,在我们平常的开发是不推荐通篇全是div的写法的。我们在做移动端时,html5的一些新标签都是可以放心使用的,比喻header、footer、nav、section、article等等这些语义标签都可以使用的。viewport 控制视口 可参考移动前端开发之viewport的深入理解 html5 中meta标签可以配置很多选项 可参考html5手机网站需要加的那些meta/link标签,html5 meta全解

CSS实现

*{ margin: 0; padding: 0; border: none; font-size: 1.5625vw; font-family: "Microsoft YaHei"; }

老师用了一个的通过选择符,表示选择页面的所有标签,其实在日常开发中我们也是不推荐直接使用 作为选择符的,因为他的效率比较低,现在网上有很多的reset的css样式,大家可以去网上找一下看看。
首先,这里出现了2个新的单位,vm和vh 关于单位的介绍可以参看 视区相关单位vw, vh..简介以及可实际应用场景.
font-size: 1.5625vw;是怎么回事呢?这个1.5625 = (10/640)*100 ,这个10是怎么来的呢,为了开发方便大家都喜欢把根字体设为10px,因为这样的话1rem就等于10px,而我们在量设计图时得到的单位是px,所以我们在转成rem时直接除以10就可以,计算非常方便。这个640是一般的设计图都是640px宽的,这个值可以根据设计图的实际大小来调整。为什么要乘以100呢,因为要换算到vm的单位。

.music{
    position: fixed;
    top: 3vh;
    right: 4vw;
    z-index: 5;
    width: 15vw;
    height: 15vw;
    border: 4px solid #ef1639;
    border-radius: 50%;
    background: #fff;
}

这个 top为什么会是 3vh呢?我们量音乐图标顶部到页面最上面的距离是35px , 而页面的高度是1136px (测量psd宽度为6401136);(35/1136) 100 大概就是3 ;right为什么是4呢,量音乐图标右部到页面最右面的距离是26px,页面的宽度是640px,所以 (26/640)100 大概就是4 ;为什么有时除1136 有时除 640,如果是水平距离,比喻宽、left、right 就需要相对于页面的宽来计算,就是除以640,单位是vm; 如果是垂直距离,比喻高、top、bottom 就需要相对于页面的高来计算,就是除以1136,单位是vh; 为什么我前面都说大概呢?因为我没有设计图,就是基于做好的页面来量的,可能会有一点误差。z-index:5;这个5 是不是随便写的呢?当然不是 因为后面有一个 /#page2 > .p2_bg_loading 的z-index是4*/ ;而这个音乐图标又要在最上面,所以就需要大于4。

body{
    height: 100%;
    overflow: hidden;
}

html5中,html和body也是块状元素,所以高度默认为0,所以需要设置height:100%来让它撑满屏幕

.page > .bg{
    position: absolute;
    z-index: -1;
    height: 100%;
    width: 100%;
}

这里z-index为-1是为了保证背景图片在最下层,不遮盖任何内容
绝对定位会使块状元素的默认100%的宽度变成0,所以需要手动设置一下

#page1 > .bg{
    background: url("../images/p1_bg.jpg") no-repeat center center;
    background-size: 100%;
}

background-size 可以参考 CSS3 background-size 属性

#page1 > .p1_lantern{
    position: absolute;
    top: -3.4%;
    right: 0;
    left: 0;
    margin: auto;
    background: url("../images/p1_lantern.png") no-repeat center bottom;
    background-size: 100%;
    width: 45vw;
    height: 71.2vh;
    font-size: 3.506rem;
    padding-top: 31vh;
    text-align: center;
    color: #fff;
    box-sizing: border-box;
}

top:-3.4% 为什么,可能是因为让图片上移一点,不然会出现下移的现象,(可是我觉得这个好像没有必要,老师的这个width: 45vw;和height: 71.2vh;量的有不太对,我对老师切好的图量了一下width: 45.15625vw ; height: 68.838028vh;值是多少并不是太重要,主要是宽高比对应不上,所以背景图上并不能完全铺满,所以上面会有一点是没有背景图的,就会出现下移的情况)
font-size: 3.506rem; 又是怎么来的呢,老师说是量的,其实是量后计算的。值应该是35.06pt(为什么是pt,psd上我见到的字体单位一般都是pt,我又经常认为pt和px近使相等,这是我个人理解,大家可以去查下资料),然后换算成rem 前面说过是除以10,就得到了3.506rem;
right:0;left:0; 怎么看就觉得这两个属性是冲突的,我开始一直这么认为,这两个是相反的属性,为什么可以同时设置呢?按照正常的逻辑应该是后写的那一个生效呀,这里是为什么我也不知道,哈哈,但确实是两个都生效了,如果少写一个还不行,可能是因为position: absolute;正常我们写水平居中时就是一个 margin:0 auto;如果你不写left和right,你会发现这个也不灵了,这又是为什么呢?可以还是因为position: absolute,呵呵,这个大家自己去查资料吧。
rem 相关知识可参考 CSS3的REM设置字体大小
box-sizing: border-box;box-sizing又是个什么东西,可参考 CSS3 box-sizing 属性

#page1 > .p1_lantern:before{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
    content: "";
    margin: auto;
    width: 30vw;
    height: 30vw;
    background: #d60b3b;
    /*如果值是零点几,就是什不到1的小数  前面的0可以省略,直接从点开始写*/
    opacity: .5;
    border-radius: 50%;
    /*http://www.w3school.com.cn/cssref/pr_box-shadow.asp*/
    box-shadow: 0 0 10vw 10vw #d60b3b;
    animation: p1_lantern .5s infinite alternate;
}

height:30vw ? 刚才说的高是用vh做单位,这里怎么就变成了vw呢,因为宽和高是一样的,所以就用了相同的单位.
opcity:.5 点5又是个什么东东?因为如果值是零点几,就是不到1的小数 前面的0可以省略,直接从点开始写,这么写好像可以少写一个0,少写一个文件的体积就会小点,我一直这么认为,哈哈哈
这里使用:before和:after伪类来实现两个圈,是一个很好的技巧,可以减少页面的html标签数量。
box-shadow 可参考 CSS3 box-shadow 属性

.page{
    position: absolute;
    height: 100%;
    width: 100%;
}

每一个页面都是一个完整的单页的,所以每一个页面都要重新给一个定位的参考基点,也就是需要添加 position: absolute;

.music > img:first-of-type{
    position: absolute;
    top: 24%;
    right: 2.5%;
    width: 28.421%;
    z-index: 1;
}
.music > img:last-of-type{
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    margin: auto;
    width: 79%;
    z-index: 0;
}

这里同时设置top和bottom为0,和上面说的问题是相同的。这两个z-index一个0一个1,是为了保证为了保证这个触片在光盘上面

@keyframes p2_circle_inner {
    0%{
        transform: rotate(0deg);
    }
    100%{
        transform: rotate(-1080deg);
    }
}

老师说一圈的效果不好,这里的效果体现在哪里呢?首先动画的时间是1S,转一圈是360度,转三圈就是1080度。所以就是1S转一圈和1S转三圈的区别,最终效果就体现在转动的速度上,所以老师说的效果就是转动速度的效果。

animation: p2_circle_outer 1s linear 3s infinite;
animation: p2_circle_middle 1s linear 2s infinite;
animation: p2_circle_inner 1s linear 1s infinite;

三个圈的转动延迟分别是1S 2S 3S,这三个数字是怎么来的呢?首先刚进入页面时,等待1S内圈开始转动,这样可以看到从不动到转动的过程,等内圈转动了一个周期后也就是1S后中圈开始转动,这样可以看到先转动内圈,再转动中圈。所以中圈就是延迟2S,就是最开始等待的1S加内圈转动的1S,外圈也是一样,加上中圈转动的1S,所以是等待3S后开始转动。

@keyframes p2_circle_middle {
    0%{
        transform: rotate(0deg);
    }
    100%{
        transform: rotate(720deg);
    }
}

当角度相同时不转动,老师说到了N次元的问题,我没搞懂是什么意思,我自己试了一下,当外圈是720,中圈为-720时,是可以转动的,只不过中圈只转动一个回合就停止了(不知道是不是老师说的N次元的问题),其他的都正常。
animation 参考 CSS3 animation 属性
keyframes 参考CSS3 @keyframes 规则

js效果

<audio src="http://www.imooc.com/activity/project/project1/audio/happynewyear.mp3" autoplay="true"></audio>

audio标签的 autoplay 属性在safari浏览器中会不支持,在apple设备上也是有问题的,所以音乐播放最好是通过点击页面,然后通过js来手动触发一次播放才可以。

<script src="js/script.js" defer></script>

如果js需要对页面元素操作,需要等页面元素加载完毕后才可以执行。如果是在head中引入果,并且js中没有做任何处理就需要对引入的js添加一个 defer属性,这是一个html5的属性。还有一些其他的方式,比喻在页面body标签最后引入js文件,或者把js代码写到window.onload函数内部,就可以解决这种问题,当然也可以采用一些第三方库来处理。
audio 的事件可参考 HTML 事件属性 中的Media 事件
audio标签的样式中 animatePlayState属性可以让动画停止时保持当前状态,但是兼容性不好。

 audio.addEventListener('ended',function(event){
        music.setAttribute('class','');
    },false);

addeventlistener 可以参考 HTML DOM addEventListener() 方法

music.addEventListener('touchstart',function(event){
        if(audio.paused){
            audio.play();
            this.setAttribute('class','play');
        }else{
            audio.pause();
            this.setAttribute('class','');
        }
    },false);

因为 click事件 有300毫秒的延迟,所以在移动端为了提高性能和体验,可以使用 touchstart来代替click事件。

page3.setAttribute('class','page fadeIn');

page3.setAttribute('class','page fadeIn'); 这里为什么是'page fadein' 不是 'fadein'呢?因为page3本身就有一个page的class,如果直接写fadeIn的话,那page3就只有fadeIn的样式,page的class就没有了,所以要一起加上。当然这里也可以用其他的方法,page3.classList.add('fadeIn'); 这样写的话就类似于JQUERY的addClass,不需要考虑之前的class,当然这个也就兼容性问题。 兼容性可以参考classList详解,让你的js方便地操作DOM类

setTimeout(function(){
            page2.setAttribute('class','page fadeOut');
            page3.setAttribute('class','page fadeIn');
            page3.classList.add('fadeIn');
        },5500)

这个5.5S是怎么算出来的?首先 #page2 > .p2_bg_loading 这个loadding有个1S的动画效果,然后就是那个全圈的转动时间,时间最长的是外圈,等待3S转动1S,就耗时4S,加上前面loadding就是5S,因为#page2有个0.5S的过度,所以加起来就是5.5S。

大概就些了,因为我从来不写文章,所以逻辑比较混乱,大家将就着看。这里主要说了一些老师没有说到的知识点。希望对初学者能够就帮助,如果我有理解不恰当或错误的地方,再次希望大家能够指出,谢谢。再过两天就要上班,希望大家玩的开心,最后祝大家新快乐,新的一年能够学到更多知识,工资涨涨涨。

最后帖一下源码
html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="format-detection" content="tetephone=no">
    <title>慕课迎春</title>
    <link rel="stylesheet" href="css/style.css">
    <script src="js/script.js" defer></script>
</head>
<body>

<div class="music">
    <img src="images/music_pointer.png" alt="">
    <img id="music" class="play" src="images/music_disc.png" alt="">
</div>
<div class="page" id="page1">
    <div class="bg"></div>
    <div class="p1_lantern">点击屏幕<br>开启好运2016</div>
    <div class="p1_imooc"></div>
    <div class="p1_words">2016年慕课网新春特献</div>
</div>
<div class="page" id="page2">
    <div class="bg p2_bg_loading"></div>
    <div class="bg"></div>
    <div class="p2_circle"></div>
    <div class="p2_2016"></div>
</div>
<div class="page" id="page3">
    <div class="bg"></div>
    <div class="p3_logo"></div>
    <div class="p3_title"></div>
    <div class="p3_second"></div>
    <div class="p3_first"></div>
    <div class="p3_blessing"></div>
</div>
<audio src="http://www.imooc.com/activity/project/project1/audio/happynewyear.mp3" autoplay="true"></audio>
</body>
</html>

css 兼容性没有添加浏览器前缀

/* all tag*/
*{
    margin: 0;
    padding: 0;
    border: none;
    font-size: 1.5625vw;
    font-family: "Microsoft YaHei";
}
html,
body{
    height: 100%;
    overflow: hidden;
}

/*music*/
.music{
    position: fixed;
    top: 3vh;
    right: 4vw;
    z-index: 5;
    width: 15vw;
    height: 15vw;
    border: 4px solid #ef1639;
    border-radius: 50%;
    background: #fff;
}
.music > img:first-of-type{
    position: absolute;
    top: 24%;
    right: 2.5%;
    width: 28.421%;
    z-index: 1;
}
.music > img:last-of-type{
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    margin: auto;
    width: 79%;
    z-index: 0;
}
.music > img.play{
    animation:music_disc 4s linear infinite;
}
@keyframes music_disc {
    0%{
        transform: rotate(0deg);
    }
    100%{
        transform: rotate(360deg);
    }
}
/*page bg*/
.page{
    position: absolute;
    height: 100%;
    width: 100%;
}
.page > .bg{
    position: absolute;
    z-index: -1;
    height: 100%;
    width: 100%;
}

/* page1 */
#page1{
    display: block;
}
#page1 > .bg{
    background: url("../images/p1_bg.jpg") no-repeat center center;
    background-size: 100%;
}
#page1 > .p1_lantern{
    position: absolute;
    top: -3.4%;
    right: 0;
    left: 0;
    margin: auto;
    background: url("../images/p1_lantern.png") no-repeat center bottom;
    background-size: 100%;
    width: 45vw;
    height: 71.2vh;
    font-size: 3.506rem;
    padding-top: 31vh;
    text-align: center;
    color: #fff;
    box-sizing: border-box;
}
#page1 > .p1_lantern:before{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
    content: "";
    margin: auto;
    width: 30vw;
    height: 30vw;
    background: #d60b3b;
    opacity: .5;
    border-radius: 50%;
    box-shadow: 0 0 10vw 10vw #d60b3b;
    animation: p1_lantern .5s infinite alternate;
}
@keyframes p1_lantern {
    0%{
        opacity: .5;
        transform: scale(.8,.8);
    }
    100%{
        opacity: 1;
    }
}
#page1 >.p1_imooc{
    position: absolute;
    right: 0;
    bottom: 9vh;
    left: 0;
    background: url("../images/p1_imooc.png") no-repeat center center;
    background-size: 100%;
    width: 27.656vw;
    height: 18.63vh;
    margin: auto;
}
#page1 > .p1_words{
    font-size: 2.134rem;
    position: absolute;
    right: 0;
    bottom: 48px;
    left: 0;
    text-align: center;
    color: #231815;
}

/* page2 */
#page2{
    display: none;
    transition: .5s;
}
#page2.fadeOut{
    opacity: .3;
    transform: translate(0,-100%);
}
#page2 > .p2_bg_loading{
    z-index: 4;
    background: #ef1639;
    animation: p2_bg_loading 1s linear forwards;
}
@keyframes p2_bg_loading {
    0%{
        opacity: 1;
    }
    100%{
        opacity: 0;
    }
}
#page2 > .bg{
    background: url("../images/p2_bg.jpg") no-repeat center center;
    background-size: 100%;
}
#page2 > .p2_circle{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    border-radius: 50%;
    background: url("../images/p2_circle_outer.png") no-repeat center center;
    background-size: 100%;
    width: 59.375vw;
    height: 59.375vw;
    animation: p2_circle_outer 1s linear 3s infinite;
}
@keyframes p2_circle_outer {
    0%{
        transform: rotate(0deg);
    }
    100%{
        transform: rotate(-720deg);
    }
}
#page2 > .p2_circle:before{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    border-radius: 50%;
    content: "";
    background: url("../images/p2_circle_middle.png") no-repeat center center;
    background-size: 100%;
    width: 45.625vw;
    height: 45.625vw;

    animation: p2_circle_middle 1s linear 2s infinite;
}
@keyframes p2_circle_middle {
    0%{
        transform: rotate(0deg);
    }
    100%{
        transform: rotate(720deg);
    }
}
#page2 > .p2_circle:after{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    border-radius: 50%;
    content: "";
    background: url("../images/p2_circle_inner.png") no-repeat center center;
    background-size: 100%;
    width: 39.9375vw;
    height: 39.9375vw;

    animation: p2_circle_inner 1s linear 1s infinite;
}
@keyframes p2_circle_inner {
    0%{
        transform: rotate(0deg);
    }
    100%{
        transform: rotate(-1080deg);
    }
}
#page2 > .p2_2016{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    background: url("../images/p2_2016.png") no-repeat center center;
    background-size: 100%;
    width: 27.5vw;
    height: 6.24vh;
}

/* page3 */
#page3{
    display: none;
    transition: .5s;
}
#page3.fadeIn{
    transform: translate(0,-100%);
}
#page3 > .bg{
    background: url("../images/p3_bg.jpg") no-repeat center center;
    background-size: 100%;
}
#page3 > .p3_logo{
    width: 34.6875vw;
    height: 6.3725vh;
    position: absolute;
    top: 7.82vh;
    right: 0;
    left: 0;
    margin: auto;
    background: url("../images/p3_logo.png") no-repeat center center;
    background-size: 100%;
}
#page3 > .p3_title{
    width: 48.125vw;
    height: 50vh;
    position: absolute;
    top: 21vh;
    right: 0;
    left: 0;
    margin: auto;
    background: url("../images/p3_title.png") no-repeat center center;
    background-size: 100%;
}
#page3 > .p3_second{
    width: 22.8125vw;
    height: 41.625vh;
    position: absolute;
    top: 25.48vh;
    left: 3.75vw;
    margin: auto;
    background: url("../images/p3_couplet_second.png") no-repeat center center;
    background-size: 100%;
}
#page3 > .p3_first{
    width: 22.8125vw;
    height: 41.625vh;
    position: absolute;
    top: 25.48vh;
    right: 3.75vw;
    margin: auto;
    background: url("../images/p3_couplet_first.png") no-repeat center center;
    background-size: 100%;
}
#page3 > .p3_blessing{
    width: 32vw;
    height: 32vw;
    position: absolute;
    right: 0;
    left: 0;
    bottom: 10vh;
    margin: auto;
    border-radius: 50%;
    background: url("../images/p3_blessing.png") no-repeat center center;
    background-size: 100%;

    animation: p3_blessing 2s linear infinite;
}
@keyframes p3_blessing {
    0%{
        transform: rotate(0deg);
    }
    0%{
        transform: rotate(360deg);
    }
}

js

window.onload = function(){

    var music = document.getElementById('music');
    var audio = document.getElementsByTagName('audio')[0];

    var page1 = document.getElementById('page1');
    var page2 = document.getElementById('page2');
    var page3 = document.getElementById('page3');

    //当音乐播放完停止的时候,自动停止光盘旋转的效果
    audio.addEventListener('ended',function(event){
        music.setAttribute('class','');
    },false);
    //点击音乐图标 控制音乐的播放效果
    music.addEventListener('touchstart',function(event){
        if(audio.paused){
            audio.play();
            this.setAttribute('class','play');
        }else{
            audio.pause();
            this.setAttribute('class','');
        }
    },false);
    //点击页面
    page1.addEventListener('touchstart',function(event){
        page1.style.display = 'none';
        page2.style.display = 'block';
        page3.style.display = 'block';
        page3.style.top = '100%';
        setTimeout(function(){
            page2.setAttribute('class','page fadeOut');
            page3.setAttribute('class','page fadeIn');
        },5500)
    },false);
};

图片老师都上传 这是mp3的地址 mp3地址

37人推荐
随时随地看视频
慕课网APP

热门评论

用心了!

666

支持大神..........

查看全部评论