如何用css3制作相册翻页效果

html-css030

如何用css3制作相册翻页效果,第1张

用css3制作纸张效果

一、中规中矩的效果

所谓“中规中矩的效果”就是加个投影,贴个胶带什么的。效果如下:

CSS3的box-shadow投影效果,相关代码如下:

代码如下:

-moz-box-shadow: 0 2px 10px 1px rgba(0, 0, 0, 0.2)-webkit-box-shadow: 0 2px 10px 1px rgba(0, 0, 0, 0.2)box-shadow: 0 2px 10px 1px rgba(0, 0, 0, 0.2)

反而是上面的胶带纸效果有点说头,这些微微倾斜的胶带是CSS写出来的,大部分效果源自CSS3,主要有RGBA显示半透明背景色,box-shadow显示淡淡的投影,transform做旋转效果;元素使用after伪类生成,完整代码如下:

代码如下:

.page:after { width: 180pxheight: 30pxcontent: " "margin-left: -90pxborder: 1px solid rgba(200, 200, 200, .8)background: rgba(254, 254, 254, .6)-moz-box-shadow: 0px 0 3px rgba(0, 0, 0, 0.1)-webkit-box-shadow: 0px 0 3px rgba(0, 0, 0, 0.1)box-shadow: 0px 0 3px rgba(0, 0, 0, 0.1)-moz-transform: rotate(-5deg)-webkit-transform: rotate(-5deg)-o-transform: rotate(-5deg)transform: rotate(-5deg)position: absoluteleft: 50%top: -15px}

老外似乎很喜欢使用before和after伪类,国外最近的些教程,技术点等经常见到此玩意。我个人感觉有跟风之嫌,就像是狂热的经济泡沫,不需 要太久,大家会冷静下来重新审视这些曾经上手简单,自我感觉不错的方法。由于目前IE6/7不支持before/after类,所以,某种意义上来说,伪 类的使用少了些兼顾IE下显示的烦恼。

二、外翻卷角纸张效果

纸张一般都是有卷角的,所以,我们可以更近一步,模拟卷角效果来使得纸张的感觉更逼真,这里就要借助于投影了,且是曲线投影。

我们还可以给纸张增加渐变(gradient)效果,以模拟纸张的曲度。

同时,可以给文字增加投影,可以让文字有书写的凹陷感,可以进一步让纸张效果更逼真。

于是,在“中规中矩”纸张基础上,我们做点小手术,结果得到下面的效果:

您可以狠狠地点击这里:渐变卷边纸张效果demo

目前貌似opera浏览器还不支持CSS3渐变,同时webkit核心下浏览器下的gradient渐变的写法已经开始向FireFox浏览器靠拢了。确实,都是CSS3,有必要搞得五花八门吗?

相关渐变CSS代码如下:

代码如下:

background:-moz-linear-gradient(top, #f4f39e, #f5da41 60%, #fe6)background:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#f4f39e), to(#fe6), color-stop(.6, #f5da41))

在60%的位置有个颜色拐点。

关于弧形的投影,也是使用:before/:after伪类实现的,相关代码如下:

代码如下:

.page:before { -webkit-transform: skew(-15deg) rotate(-5deg)-moz-transform: skew(-15deg) rotate(-5deg)-o-transform: skew(-15deg) rotate(-5deg)transform: skew(-15deg) rotate(-5deg)left: 15px} .page:after { -webkit-transform: skew(15deg) rotate(5deg)-moz-transform: skew(15deg) rotate(5deg)-o-transform: skew(15deg) rotate(5deg)transform: skew(15deg) rotate(5deg)right: 15px} .page:before, .page:after { width: 90%height: 20%content: ' '-webkit-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3)-moz-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3)box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3)position: absolutebottom: 22pxz-index: -1}

要想查看效果的完整代码,demo页面查看源文件即可,脱光光,一览无遗。

这里的曲线投影卷角效果支持Opera浏览器,如下截图:

三、带分隔线的卷纸纸张效果

上面的纸张卷角效果是通过曲线投影效果来模拟的,而这里,纸张的卷边效果是纸张真的“曲线化”了,而且,还是带隔线的纸张效果哦,您可以参见下面的效果截图(Chrome 9):

这里,Firefox浏览器下的纸张隔线使用的是重复渐变(Repeating Gradients)实现的,对于webkit浏览器,使用的是background-size实现的。实际上,Firefox3.6+已经支持background-size属性了(-moz-background-size), 所以,对于Firefox浏览器,这里使用重复渐变与渐变+background-size是等效的。在FireFox4以及IE9浏览器中 background-size属性已经没有私有属性了,Opera浏览器在9.5版本时候就已经支持background-size属性了,但是存在一 些bug。

这里分隔线实现的相关CSS如下:

代码如下:

background: -moz-repeating-linear-gradient( top, #fcf59b, #fcf59b 29px, #81cbbc 30px )background: -webkit-gradient( linear, left top, left bottom, from(#81cbbc), color-stop(2%, #fcf59b) )background: repeating-linear-gradient( top, #fcf59b, #fcf59b 29px, #81cbbc 30px )-webkit-background-size: 100% 30px

而对于曲边的实现,使用的是border-radius圆角,这里展示下示意的代码:

代码如下:

border-bottom-left-radius: 20px 500pxborder-bottom-right-radius: 500px 30pxborder-top-right-radius: 5px 100px

当然,FireFox浏览器下的写法不是如此,其bottom, left是连起来的,而不是”-”分隔,这里仅仅是示意,这里的微曲线是如何实现的。相信看到上面的代码就知道意思了,这里就不啰嗦了。

还有其他些细节,如如何控制行高让文字与隔线一一对应,这些您要是有兴趣可以去demo页面,通过查看元素等方法一看究竟。

四、最后点老生常谈

难免的,本文的重点在于CSS3,所以就本文而言,IE6/IE7/IE8浏览器就是过来打酱油的,且三个纸张效果从一而终,都是下面这副模样:

虽然没有透明胶效果,没有投影,没有卷边,更没有分隔线,但是,就功能上来讲,一点都不影响使用。所以,无论你是渐进增强还是退求其次,纸张投影效果在实际项目中的应该也不是不可以的,这就要看个人和团队的抉择了

文字在图片上显示

<!DOCTYPE html>

<html>

<head>

<title></title>

<meta charset="UTF-8">

<style>

#abox{

position:relative/*容器相对定位*/

width:300px/*宽度300px*/

margin:0 auto/*横向居中*/

}

#abox img{

width:300px/*宽度300px*/

}

span{

position:absolute/*文字容器绝对定位*/

display:block/*span转为块元素*/

width:100%/*宽度相对于父容器100%*/

text-align:center/*文字居中*/

top:0/*距离父容器顶部0*/

left:0/*距离父容器左侧0*/

color:red/*文字颜色红色*/

font-size:18px/*文字大小既文字高度18px*/

font-weight:bold/*文字加粗*/

}

</style>

</head>

<body>

<div id="abox"><!--容器,相对定位-->

  <img src="123.jpg"><!--图片-->

  <span>我要显示文字</span><!--文字,绝对定位-->

</div>

</body>

</html>

首先需要引用 js 和css

 <!--上传控件-->

2     <script src="query.form.min.js"></script>

3     <link href="Img_List.css" rel="stylesheet" />

4     <script src="Img_List.js"></script>

Img_List.js 如下:

/// <reference path="../../script/jquery-1.8.0.min.js" />

//显示

function imgshow(obj) {

    //$(obj).find("a").show()

}

//隐藏

function imghide(obj) {

    //$(obj).find("a").hide()

}

//上传

function upload() { 

    $("#FileLoad").click()

}

//删除

function imgdel(listId, FileId, hfId) {

    

    $.post("/CommonModule/ashx/public.ashx?action=DelMessageImg&Files=" + $("#" + hfId).val(), function (result) {

        if (result != "ok")

            $.messager.alert("消息提示", "删除失败!")

     })

    var html = "<li><img src=\"/Themes/Images/jia.jpg\" style=\"height: 80px width: 80px\" /><input type=\"file\" id=\""+FileId+"\" class=\"input\" onchange=\"ImgUpload('"+FileId+"','"+hfId+"','"+listId+"')\" name=\""+FileId+"\" /></li>"

    $("#"+listId).html(html)

}

//添加成功

function imgaddhtml(data, code,listId,fileId,hfId) {

    var list = data.split(',')

    var html = "<li onmouseover=\"imgshow(this)\" onmouseout=\"imghide(this)\">"

    html += "<a style=\"height:80pxwidth:80px\" href=\"" + list[0] + "\" target=\"_blank\"><img src=\"" + list[0] + "\" imgs=\"" + list[0] + "\" code=\"" + code + "\" /></a><span  onclick=\"imgdel('"+listId+"','"+fileId+"','"+hfId+"')\"></span></li>"

    $("#" + listId).html(html)

}

//图片文件上传

//uppath 上传空间id 

//上传成功存放的图片路径的隐藏域id

//listId 显示图片的区域id

function ImgUpload(uppath, hndimg,listId) {

    var sendUrl = "/CommonModule/ashx/Upload_Ajax.ashx?action=SingleFile&IsThumbnail=1&UpFilePath=" + uppath

    //开始提交

    $("#form1").ajaxSubmit({

        beforeSubmit: function (formData, jqForm, options) {

            //alert(1)

        },

        success: function (data, textStatus) {

            var list = $("#" + hndimg).val()

            $("#" + hndimg).val(data.msgbox)

            imgaddhtml(data.msgbox, 0,listId,uppath,hndimg)

        },

        error: function (data, status, e) {

            alert("上传失败!")

        },

        url: sendUrl,

        type: "post",

        dataType: "json",

        timeout: 600000

    })

}

Img_List.css 如下:

.img_list{ margin:0px padding:0px  overflow:hidden}

.img_list ul,.img_list ul li{ margin:0px padding:0px} 

.img_list ul li{ float:left list-style:none position:relative margin:5px 0px 0px 5px}

.img_list ul li span

{ position:absolutetop:3px right:3px width: 16px height: 16px opacity: 0.6filter: alpha(opacity=60) margin: 0 0 0 2px

vertical-align: top background: url('/Themes/Images/panel_tools.png') no-repeat -16px 0px}

.img_list ul li img{ width:80px height:80px cursor:pointer position:relative z-index:0}

.img_list ul li .input{ width:80px height:80px cursor:pointer position:relative left:-100pxvertical-align: top margin:0px padding:0px opacity:0filter: alpha(opacity=0) }

panel_tools.png 如下:

jia.jpg 如下:

前台页面代码:

<tr>

                        <th>图片1:</th>

                        <td>

                            <asp:Literal ID="ltrimg_list" runat="server"></asp:Literal>

                            <input type="hidden" runat="server" id="ImgPath" name="ImgPath" />

                            <span style="color:blue">建议尺寸(243*150)</span>

                        </td>

                    </tr>

<tr>

                        <th>图片2:</th>

                        <td>

                            <asp:Literal ID="Literal1" runat="server"></asp:Literal>

                          

                            <input type="hidden" runat="server" id="hkImgPath" name="hkImgPath" />

                             <span style="color:blue">建议尺寸(243*150)</span>

                        </td>

                    </tr>

后台初始化代码:

protected void Page_Load(object sender, EventArgs e)

        {

          

            if (!IsPostBack)

            {

               ltrimg_list.Text = UpLoad.showUploadFile("File1", "ImgPath", mfmodel.ImgPath, "img_list1")

                Literal1.Text = UpLoad.showUploadFile("File2", "hkImgPath", mfmodel.hkImgPath, "img_list2")

                   

            }

        }

        /// <summary>

        /// 生成一个上传插件信息

        /// </summary>

        /// <param name="fileId">上传控件id</param>

        /// <param name="hfId">隐藏域id用来保存上传的图片路径</param>

        /// <param name="imgUrl">初始化显示的图片地址</param>

        /// <param name="listId">上传成功之后用来显示上传图片的标签id</param>

        /// <returns></returns>

        public static string showUploadFile(string fileId, string hfId, string imgUrl, string listId)

        {

            string result = ""

            if (!string.IsNullOrEmpty(imgUrl))

            {

                result = "<div class=\"img_list\"><ul id=\"" + listId + "\"><li onmouseover=\"imgshow(this)\" onmouseout=\"imghide(this)\"><a style=\"height:80pxwidth:80px\" href=\"" + imgUrl + "\" target=\"_blank\"><img src=\"" + imgUrl + "\" imgs=\"" + imgUrl + "\" code=\"0\" /></a><span onclick=\"imgdel('" + listId + "','" + fileId + "','" + hfId + "')\"></span></li></ul></div>"

            }

            else

            {

                result = "<div class=\"img_list\"><ul id=\"" + listId + "\"><li><img src=\"/Themes/Images/jia.jpg\" style=\"height: 80px width: 80px\" /><input type=\"file\" id=\"" + fileId + "\"class=\"input\" onchange=\"ImgUpload('" + fileId + "','" + hfId + "','" + listId + "')\" name=\"" + fileId + "\" /></li></ul></div>"

            }

            return result

        }

上传方法:

#region 上传单文件处理===================================

 46         private void SingleFile(HttpContext context)

 47         {

 48 

 49             string _refilepath = context.Request.QueryString["ReFilePath"] //取得返回的对象名称

 50             string _upfilepath = context.Request.QueryString["UpFilePath"] //取得上传的对象名称

 51             string _delfile = context.Request.QueryString[_refilepath]

 52             HttpPostedFile _upfile = null

 53             try

 54             {

 55                 _upfile = context.Request.Files[_upfilepath]

 56             }

 57             catch (Exception e)

 58             {

 59                 context.Response.Write("{\"msg\": \"0\", \"msgbox\": \"上传文件过大!\"}")

 60                 context.Response.End()

 61             }

 62             bool _iswater = false //默认不打水印

 63             bool _isthumbnail = false //默认不生成缩略图

 64             bool _isimage = false

 65 

 66             if (context.Request.QueryString["IsWater"] == "1")

 67                 _iswater = true

 68             if (context.Request.QueryString["IsThumbnail"] == "1")

 69                 _isthumbnail = true

 70             if (context.Request.QueryString["IsImage"] == "1")

 71                 _isimage = true

 72 

 73             if (_upfile == null)

 74             {

 75                 context.Response.Write("{\"msg\": \"0\", \"msgbox\": \"请选择要上传文件!\"}")

 76                 return

 77             }

 78             UpLoad upFiles = new UpLoad()

 79             string msg = upFiles.fileSaveAs(_upfile, _isthumbnail, _iswater, _isimage)

 80             //删除已存在的旧文件

 81             Utils.DeleteUpFile(_delfile)

 82             //返回成功信息

 83             context.Response.Write(msg)

 84 

 85             context.Response.End()

 86         }

 87         #endregion

 

101         public string fileSaveAs(HttpPostedFile postedFile, bool isThumbnail, bool isWater, bool _isImage, bool _isReOriginal)

102         {

103             try

104             {

105                 string fileExt = Utils.GetFileExt(postedFile.FileName) //文件扩展名,不含“.”

106                 string originalFileName = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf(@"\") + 1) //取得文件原名

107                 string fileName = Utils.GetRamCode() + "." + fileExt //随机文件名

108                 string dirPath = GetUpLoadPath() //上传目录相对路径

109 

110                 //检查文件扩展名是否合法

111                 if (!CheckFileExt(fileExt))

112                 {

113                     return "{\"msg\": \"0\", \"msgbox\": \"不允许上传" + fileExt + "类型的文件!\"}"

114                 }

115                 //检查是否必须上传图片

116                 if (_isImage && !IsImage(fileExt))

117                 {

118                     return "{\"msg\": \"0\", \"msgbox\":  \"对不起,仅允许上传图片文件!\"}"

119                 }

120                 //检查文件大小是否合法

121                 if (!CheckFileSize(fileExt, postedFile.ContentLength))

122                 {

123                     return "{\"msg\": \"0\", \"msgbox\":  \"文件超过限制的大小啦!\"}"

124                 }

125                 //获得要保存的文件路径

126                 string serverFileName = dirPath + fileName

127                 string serverThumbnailFileName = dirPath + "small_" + fileName

128                 string returnFileName = serverFileName

129                 //物理完整路径                    

130                 string toFileFullPath = Utils.GetMapPath(dirPath)

131                 //检查有该路径是否就创建

132                 if (!Directory.Exists(toFileFullPath))

133                 {

134                     Directory.CreateDirectory(toFileFullPath)

135                 }

136                 //保存文件

137                 postedFile.SaveAs(toFileFullPath + fileName)

138                 //如果是图片,检查图片尺寸是否超出限制

139                 if (IsImage(fileExt))

140                 {

141                     Thumbnail.MakeThumbnailImage(toFileFullPath + fileName, toFileFullPath + fileName, 3000, 3000)

142                 }

143                 //是否生成缩略图

144                 if (IsImage(fileExt) && isThumbnail)

145                 {

146                     Thumbnail.MakeThumbnailImage(toFileFullPath + fileName, toFileFullPath + "small_" + fileName, 150, 150, "R")

147                    // returnFileName += "," + serverThumbnailFileName //返回缩略图,以逗号分隔开

148                 }

149              

166                 /

171                 return "{\"msg\": \"1\", \"msgbox\": \"" + returnFileName + "\"}"

172             }

173             catch

174             {

175                 return "{\"msg\": \"0\", \"msgbox\":  \"上传过程中发生意外错误!\"}"

176             }

177         }