上篇文章和大家介紹了需求情況和難點分析,大家可以看這個鏈接了解詳細

=================正文開始=====================================
這些天一直在忙,抽空把代碼完成了。和大家分享一下實現。
大家先在chorme上看一下DEMO吧,在線DEMO地址 http://codepen.io/arfeizhang/full/liIHa
(DEMO只是為了說明原理,所以沒做瀏覽器兼容,請大家在chrome上體驗下)
DEMO看着還可以吧,我們開始分析啦~
1 <div id="faceoff">
2 <div id="person1" class="pic_wrap">
3 <div class="pic">
4 <div class="desc">
5 <div class="content">
6 Raised in Bloomfield Hills, Michigan, by his parents George and Lenore Romney, Mitt Romney spent two and a half years in France as a Mormon missionary starting in 1966. In 1969 he married Ann Davies, with whom he has had five sons. By 1971, Romney had participated in the political campaigns of both of his parents. He earned a Bachelor of Arts at Brigham Young and in 1975. 7 </div>
8 <div class="title">Mitt Romney</div>
9 </div>
10 </div>
11 </div>
12 <div id="faceoffIcon">FACEOFF</div>
13 <div id="person2" class="pic_wrap">
14 <div class="pic">
15 <div class="desc">
16 <div class="title">Barack Obama</div>
17 <div class="content">
18 Born in Honolulu, Hawaii, Obama is a graduate of Columbia University and Harvard Law School, where he served as president of the Harvard Law Review. He was a community organizer in Chicago before earning his law degree. He worked as a civil rights attorney and taught constitutional law at the University of Chicago Law School from 1992 to 2004. 19 </div>
20 </div>
21 </div>
22 </div>
23 </div>
接着來解決直角梯形UI,我想着可以這樣實現:把一個矩形進行沿x軸歪斜(skew),這個矩形就會變成個棱形(如下圖),然后我們把左尖角或右尖角遮住,就變成直角梯形了(相當於切掉左/右角)。不過在過程中發現了一個問題:形狀達到我們要求了,但隨之而來的問題是,里面的圖像也扭曲了,就像下面這樣。


直角梯形的原理,如下圖所示:


PS.還可以用webkit clip來實現非常規形狀,大家可以查下它的用法。
做好了形狀,接着來完成文字部分,這種非常規排版方式,adobe有過提議(CSS Shape),但目前CSS Shape只能在Webkit Nightly和Chrome Canary瀏覽器中實現,等以后等普及后,我們可以做出類似於這種效果。




上面最后一張圖,為了方便大家看,我把介紹內容給移了一下。大家應該看出來了吧,我是利用一些透明的占位元素(這里加了紅色邊框是為了使大家看得清楚),將介紹給擠成我們要的形狀。
這種做法需要解決的是,這些占位元素的寬度各是多少?這里我們借助程序來實現。
1 //依據角的鄰邊算對邊長度
2 function getWidth(height) { 3 return Math.tan(deg * Math.PI / 180) * height; 4 } 5 // 依據行數得到角的鄰邊長度,進而算得對邊長度
6 function getWidthByLineIndex(i) { 7 return getWidth(i * lineHeight); 8 }
這個程序的作用是,依據索引值生成一些依次遞增或遞減的span並把它加入到介紹div內。我們需要預定好角度值deg,這里我定義的是13度,和頁面上的直角梯形角度一致。

1 #person1>.pic:hover>.desc {
2 -webkit-animation: left-show 0.8s 0s normal forwards;
3 -webkit-animation-timing-function: ease-in;
4 }
5 #person1>.pic>.desc {
6 -webkit-animation: left-hide 0.8s 0s normal forwards;
7 -webkit-animation-timing-function: ease-out;
8 }
9 #person2>.pic:hover>.desc {
10 -webkit-animation: right-show 0.8s 0s normal forwards;
11 -webkit-animation-timing-function: ease-in;
12 }
13 #person2>.pic>.desc {
14 -webkit-animation: right-hide 0.8s 0s normal forwards;
15 -webkit-animation-timing-function: ease-out;
16 }
17 @-webkit-keyframes left-show {
18 from { 19 margin-top: -440px;
20 }
21 to {
22 margin-top: 0px;
23 }
24 } 25 @-webkit-keyframes left-hide {
26 from { 27 margin-top: 0px;
28 }
29 to {
30 margin-top: -440px;
31 }
32 } 33 @-webkit-keyframes right-show {
34 from { 35 margin-top: 440px;
36 }
37 to {
38 margin-top: 0px;
39 }
40 } 41 @-webkit-keyframes right-hide {
42 from { 43 margin-top: 0px;
44 }
45 to {
46 margin-top: 440px;
47 }
48 }
恩,上下滑動功能正常,鼠標響應區域和文本內容也是直角梯形。好了,我們把它完成了!!!活動下手~~~~~~~ 等等,有個問題,被我們旋轉的左右部分div,斜邊出現了鋸齒,還是比較明顯的。


所有代碼如下:

1 <!DOCTYPE HTML>
2 <html manifest="" lang="en-US">
3 <head>
4 <meta charset="UTF-8">
5 <title>Faceoff</title>
6 <style type="text/css">
7 div#faceoff {
8 overflow: hidden;
9 width: 710px;
10 }
11 .pic>.desc {
12 background-color: rgba(0, 0, 0, 0.5);
13 color: white;
14 }
15 .pic>.desc>.content {
16 font-size: 22px;
17 line-height: 26px;
18 word-break: break-all;
19 }
20 .pic>.desc>.title {
21 font-size: 30px;
22 margin-bottom: 20px;
23 }
24 .pic_wrap {
25 -webkit-transform: skewX(-13deg) translateZ(0);
26 overflow: hidden;
27 width: 353px;
28 height: 480px;
29 position: relative;
30 }
31 #person1 {
32 left: -87px;
33 float: left;
34 }
35 #person1>.pic {
36 width: 461px;
37 height: 480px;
38 background: url("resources/1.jpg") no-repeat;
39 background-position: -51px 0px;
40 background-size: 620px 480px;
41 -webkit-transform: skewX(13deg);
42 }
43 #person1>.pic>.desc {
44 width: 312px;
45 float: left;
46 margin-left: 90px;
47 margin-top: -440px;
48 }
49 #person1>.pic>.desc>.title {
50 text-align: left;
51 padding-left: 5px;
52 }
53 #person1>.pic>.desc>.content {
54 padding: 2px;
55 height: 440px;
56 }
57 #person2 {
58 left: -57px;
59 }
60 #person2>.pic {
61 width: 361px;
62 height: 480px;
63 background: url("resources/2.jpg") no-repeat;
64 background-position: 20px -25px;
65 background-size: 376px 540px;
66 -webkit-transform: skewX(13deg);
67 margin-left: -100px;
68 }
69 #person2>.pic>.desc {
70 width: 320px;
71 float: right;
72 }
73 #person2>.pic>.desc>.title {
74 text-align: right;
75 padding-right: 5px;
76 }
77 #person2>.pic>.desc>.content {
78 padding-right: 2px;
79 height: 440px;
80 }
81 .space {
82 /* border: 1px solid red;*/
83 height: 22px;
84 }
85 .space.left {
86 float: left;
87 clear: left;
88 }
89 .space.right {
90 float: right;
91 clear: right;
92 }
93 #faceoffIcon {
94 width: 80px;
95 height: 80px;
96 position: absolute;
97 background-color: red;
98 border: 3px solid white;
99 border-radius: 40px;
100 top: 194px;
101 left: 247px;
102 z-index: 2;
103 color: white;
104 line-height: 80px;
105 text-align: center;
106 font-weight: bold;
107 }
108 #faceoff:hover>#faceoffIcon {
109 display: none;
110 }
111 #person1>.pic:hover>.desc {
112 -webkit-animation: left-show 0.8s 0s normal forwards;
113 -webkit-animation-timing-function: ease-in;
114 }
115 #person1>.pic>.desc {
116 -webkit-animation: left-hide 0.8s 0s normal forwards;
117 -webkit-animation-timing-function: ease-out;
118 }
119 #person2>.pic:hover>.desc {
120 -webkit-animation: right-show 0.8s 0s normal forwards;
121 -webkit-animation-timing-function: ease-in;
122 }
123 #person2>.pic>.desc {
124 -webkit-animation: right-hide 0.8s 0s normal forwards;
125 -webkit-animation-timing-function: ease-out;
126 }
127 @-webkit-keyframes left-show {
128 from { 129 margin-top: -440px;
130 }
131 to {
132 margin-top: 0px;
133 }
134 } 135 @-webkit-keyframes left-hide {
136 from { 137 margin-top: 0px;
138 }
139 to {
140 margin-top: -440px;
141 }
142 } 143 @-webkit-keyframes right-show {
144 from { 145 margin-top: 440px;
146 }
147 to {
148 margin-top: 0px;
149 }
150 } 151 @-webkit-keyframes right-hide {
152 from { 153 margin-top: 0px;
154 }
155 to {
156 margin-top: 440px;
157 }
158 } 159
160 </style>
161 </head>
162 <body>
163 <div id="faceoff">
164 <div id="person1" class="pic_wrap">
165 <div class="pic">
166 <div class="desc">
167 <div class="content">
168 Raised in Bloomfield Hills, Michigan, by his parents George and Lenore Romney, Mitt Romney spent two and a half years in France as a Mormon missionary starting in 1966. In 1969 he married Ann Davies, with whom he has had five sons. By 1971, Romney had participated in the political campaigns of both of his parents. He earned a Bachelor of Arts at Brigham Young and in 1975. 169 </div>
170 <div class="title">Mitt Romney</div>
171 </div>
172 </div>
173 </div>
174 <div id="faceoffIcon">FACEOFF</div>
175 <div id="person2" class="pic_wrap">
176 <div class="pic">
177 <div class="desc">
178 <div class="title">Barack Obama</div>
179 <div class="content">
180 Born in Honolulu, Hawaii, Obama is a graduate of Columbia University and Harvard Law School, where he served as president of the Harvard Law Review. He was a community organizer in Chicago before earning his law degree. He worked as a civil rights attorney and taught constitutional law at the University of Chicago Law School from 1992 to 2004. 181 </div>
182 </div>
183 </div>
184 </div>
185 </div>
186
187 <script type="text/javascript">
188 //角度為13度
189 var deg = 13, 190 //占位元素的高
191 lineHeight = 22, 192 //元素高
193 contentHeight = 460, 194 //占位元素個數(行數)
195 lineCount = Math.ceil(contentHeight / lineHeight), 196 //相鄰兩個占位元素的寬度偏移量
197 lineOffset = getWidth(lineHeight), 198 //最大占位容器寬度,右側的占位容器從大到小遞減,左側的占位元素從小到大遞增
199 lineMaxWidth = getWidth(contentHeight); 200
201 //用占位容器來填充形狀
202 function SetShape(isRight) { 203 var oFrag = document.createDocumentFragment(); 204 if (isRight) { 205 for (var i = 0; i < lineCount; i++) { 206 var op = document.createElement("span"); 207 op.classList.add("space"); 208 op.classList.add("left"); 209 // 右側的占位容器從大到小遞減
210 op.style.width = (lineMaxWidth - i * lineOffset) + "px"; 211 oFrag.appendChild(op); 212 } 213 document.querySelector("#person2 .desc").insertBefore(oFrag, document.querySelector("#person2 .content")); 214 } else { 215 for (var i = 0; i < lineCount; i++) { 216 var op = document.createElement("span"); 217 op.classList.add("space"); 218 op.classList.add("right"); 219 // 左側的占位元素從小到大遞增
220 op.style.width = (i * lineOffset) + "px"; 221 oFrag.appendChild(op); 222 } 223 document.querySelector("#person1 .desc").insertBefore(oFrag, document.querySelector("#person1 .content")); 224 } 225
226 } 227 //依據角的鄰邊算對邊長度
228 function getWidth(height) { 229 return Math.tan(deg * Math.PI / 180) * height; 230 } 231 // 依據行數得到角的鄰邊長度,進而算得對邊長度
232 function getWidthByLineIndex(i) { 233 return getWidth(i * lineHeight); 234 } 235 SetShape(false); 236 SetShape(true); 237 </script>
238
239 </body>
240 </html>
素材兩張(尺寸已縮小,可右鍵下載源圖):
本文是博主Arfei Zhang原創,歡迎轉載。轉載請注明轉自博客園,並附上本文鏈接http://www.cnblogs.com/arfeizhang/p/faceoffdemo.html,謝謝!