Simple Works Gallery

起源

鄰近要大學推研究所的時刻,自己做過什麼作品來說,對於推甄時相當重要,一直都沒有好好整理過自己做過什麼,有多少能拿出檯面的項目,現在發現除了 ACM 解題和曾經幫別人寫的作業以外,沒有幾項可以吸引到人的。一樣做一個 hexo tag plugin,將作品展示櫃用一個 generator.js 的方式,將展示櫃內容呈現出來,傳入的方式為 json。同樣地,你可以在這個部落格上方的 Works 看到相關作品介紹。

下載

Download on Github

使用

仍然以 github 上的 project 為優先版本。以下的內容也許不是最新版本。

html

當前採用 json 的原因是因為可以藉由較簡單的方式,以及往後可能使用 ajax 的方式運作。這樣彈性也許會比較大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<script type="text/works-gallery">
{
"works" : [
{
"title": "Chat Room Application",
"cover": "http://i.imgur.com/oUO30I6.jpg",
"description": "計算機網路-一個簡單的網路聊天室<br/> Socket programming practice (Java)",
"download": ["https://github.com/morris821028/hw-ChatRoom"],
"demo": [],
"video": ["https://www.youtube.com/watch?v=7ExCn1ipKeg"]
},
{
"title": "Magic Circle",
"cover": "http://i.imgur.com/Fv8ebBY.jpg",
"description": "jquery-magic-circle, write funny for friends",
"download": ["https://github.com/morris821028/jquery-magic-circle"],
"demo": ["http://morris821028.github.io/jquery-magic-circle"],
"video": ["https://www.youtube.com/watch?v=TWqmGeuIJLo"]
},
{
"title": "Hex Image Gallery",
"cover": "http://i.imgur.com/VMf2G1v.png",
"description": "create beautiful hexagon shapes with CSS3, jquery, write funny for friends",
"download": ["https://github.com/morris821028/jquery-hex-gallery"],
"demo": ["http://morris821028.github.io/jquery-hex-gallery/"],
"video": []
}
]
}
</script>

css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
.wg-container
{
background: none repeat scroll 0% 0% #2d2d2d;
border-color: #ddd;
border-style: solid;
border-width: 1px 0;
color: #ccc;
line-height: 25.6px;
margin: 0 -20px;
overflow: auto;
padding: 15px 20px;
position: relative;
text-align: center;
width: 100%;
z-index: 0;
}
.wg-container hr
{
background: #333;
background-image: -moz-linear-gradient(to right, #333, #ccc, #333);
background-image: -ms-linear-gradient(to right, #333, #ccc, #333);
background-image: -o-linear-gradient(to right, #333, #ccc, #333);
background-image: -webkit-linear-gradient(to right, #333, #ccc, #333);
border: 0;
height: 5px;
}
.wg-item
{
list-style: none;
}
.wg-item .inner
{
height: 160px;
}
.wg-item li
{
display: block;
float: left;
margin: 16px;
width: 45%;
}
.wg-item li .header
{
border: 4px solid #b4b4b4;
box-shadow: 1px 1px 1px 1px #ccc;
cursor: pointer;
float: left;
height: 256px;
margin: 5px;
moz-box-shadow: 1px 1px 1px 1px #ccc;
overflow: hidden;
position: relative;
webkit-box-shadow: 1px 1px 1px 1px #ccc;
width: 100%;
}
.wg-item li .header:hover a
{
moz-transform: scale(1.2);
ms-transform: scale(1.2);
o-transform: scale(1.2);
transform: scale(1.2);
webkit-transform: scale(1.2);
}
.wg-item li .header a
{
left: 0;
moz-transition: all 300ms ease-out;
ms-transition: all 300ms ease-out;
o-transition: all 300ms ease-out;
position: absolute;
transition: all 300ms ease-out;
webkit-transition: all 300ms ease-out;
}
.wg-item li .image
{
background-size: cover;
display: block;
height: 95%;
moz-background-size: cover;
padding: .5em;
webkit-background-size: cover;
width: 100%;
}
.wg-item li h3
{
font-size: 24px;
font-weight: normal;
line-height: 22px;
margin-bottom: 10px;
margin-top: 10px;
text-align: center;
}
.wg-item li h3 a:hover
{
text-decoration: none;
}
.wg-item li ul.links
{
float: right;
}
.wg-item li .links li
{
display: block;
margin-left: 5px;
margin-right: 0 !important;
width: initial;
}
.wg-item li .links li a
{
background: #65a9d7;
border-radius: 5px;
box-shadow: 0 1px 0 #000;
color: #fff;
font-family: Georgia,Serif;
font-size: 16px;
padding: 5.5px 11px;
text-decoration: none;
text-shadow: 0 1px 0 rgba(0,0,0,0.4);
vertical-align: middle;
webkit-border-radius: 5px;
webkit-box-shadow: 0 1px 0 #000;
}
.wg-item .description
{
font-size: 16px;
margin: .2em 0;
text-align: left;
}

hexo plugin

我已經把產生方式寫在 hexo-tag-oj 裡頭,下載使用 hexo-tag-plugin

不過相關的 js 還有 css 要自己擺放,請參考上面的描述項目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{\% ojblock works \%}
{
"works" : [
{
"title": "Chat Room Application",
"cover": "http://i.imgur.com/oUO30I6.jpg",
"description": "計算機網路-一個簡單的網路聊天室<br/> Socket programming practice (Java)",
"download": ["https://github.com/morris821028/hw-ChatRoom"],
"demo": [],
"video": ["https://www.youtube.com/watch?v=7ExCn1ipKeg"]
},
{
"title": "Fuzzy System",
"cover": "http://i.imgur.com/C44Hbrg.png",
"description": "計算型智慧-廣義型演算法最佳化<br/>Car simulation implements PSO, GA, and fuzzy system (Java)",
"download": ["https://github.com/morris821028/hw-FuzzySystem"],
"demo": [],
"video": ["https://www.youtube.com/watch?v=kt2mu679elU"]
},
{
"title": "UML Editor",
"cover": "http://i.imgur.com/JCCweao.png",
"description": "物件導向程式設計-UML 編輯器架構設計<br/>OO design practice & make UML Editor (Java)",
"download": ["https://github.com/morris821028/hw-UML-Editor"],
"demo": [],
"video": ["https://www.youtube.com/watch?v=DKDFy6uFk8Y"]
},
{
"title": "MapleStory 遊戲仿作",
"cover": "http://i.imgur.com/i62nNgG.png",
"description": "由於硬碟損壞代碼沒有救回來,只剩下舊版,收錄於 chat room 製作中的一環,由於課程時間不夠,沒有做完。 (Java)",
"download": ["https://github.com/morris821028/hw-ChatRoom"],
"demo": [],
"video": ["https://www.youtube.com/watch?v=TWqmGeuIJLo"]
},
{
"title": "Magic Circle",
"cover": "http://i.imgur.com/Fv8ebBY.jpg",
"description": "jquery-magic-circle, write funny for friends",
"download": ["https://github.com/morris821028/jquery-magic-circle"],
"demo": ["http://morris821028.github.io/jquery-magic-circle"],
"video": ["https://www.youtube.com/watch?v=TWqmGeuIJLo"]
},
{
"title": "Hex Image Gallery",
"cover": "http://i.imgur.com/VMf2G1v.png",
"description": "create beautiful hexagon shapes with CSS3, jquery, write funny for friends",
"download": ["https://github.com/morris821028/jquery-hex-gallery"],
"demo": ["http://morris821028.github.io/jquery-hex-gallery/"],
"video": []
}
]
}
{\% endojblock \%}
Read More +

Jquery Hex Image Gallery

起源

六角形的圖片廊道,一開始給定的是提案是做出一個圖片展示櫃,可是想到要放在這個 hexo 部落格,要做到類似的相簿功能其實是很麻煩的,還有必須要關聯 generator 的產生方式,才能製作出相對的 static website,那只好將項目弄成單獨一頁,而這一頁要怎麼製作其實很難捉摸。失敗的設計總是這樣子開始的。

由於圖片量太大的話,變成一開始載入速度會太慢,因此找來了 lazyload.js,但是跟展示窗口銜接上仍有一些問題,無法適時地反映操作,所以需要 call back 操作,否則圖片會載入失敗。再者是原本六角 CSS 問題,找來網路上提供的 CSS,發現更換大型圖片的時候,會造成圖片顯示不正常,因此在這一塊費時了相當長的時間來符合預期的操作。

此項目已經放在我的 Github 上面,同時你也可以在這個 blog 上方的 Picture 中看到 demo,萬萬沒想到居然有人願意 Star 標記,真的是相當令人動容啊,從來沒想過有人對於這樣的蠢製作感興趣。

下載

Download on Github

Demo

使用

仍然以 github 上的 project 為優先版本。以下的內容也許不是最新版本。

html

為了方便產生器運行,產生方式採用 json 的生成方式。相關的動畫製作引入

  • jquery.lazyload.js 圖片動態載入
  • jquery.als.link-1.6.js 幻燈片的展示窗口 (經過修改,來完成跳轉操作)

當前採用 json 的原因是因為可以藉由較簡單的方式,以及往後可能使用 ajax 的方式運作。這樣彈性也許會比較大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script src="js/jquery.hex.gallery.js" type="text/javascript"></script>
<script src="js/jquery.lazyload.js" type="text/javascript"></script>
<script src="js/jquery.als.link-1.6.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
...
<script type="text/hex-gallery">
{
"album" : [
{
"cover": {"title": "<h4>THEME</h4><hr /><p>Stephanie Dola</p>", "class": "hex-1"},
"photo": [
{"imgur": "http://i.imgur.com/yIoACHc.gif"},
{"imgur": "http://i.imgur.com/uINck6K.gif"},
{"imgur": "http://i.imgur.com/zOZJEex.gif"}
]
},
{
"cover": {"title": "<h4>THEME</h4><hr /><p>萌~萌~哒~</p>", "class": "hex-2"},
"photo": [
{"imgur": "http://i.imgur.com/YSmWA3g.gif"},
]
},
{
"cover": {"title": "<h4>THEME</h4><hr /><p>其他</p>", "class": "hex-3"},
"photo": [
{"imgur": "http://i.imgur.com/vpKzynV.gif"},
{"imgur": "http://i.imgur.com/rctEEyS.gif"}
]
}
]
}
</script>

...
</body>
</html>

css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
.hex-container
{
display: block;
height: 320px;
position: relative;
width: 800px;
}
.hex
{
animation: animatedBackground 10s linear infinite;
background-color: #ccc;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: cover;
float: left;
font-family: Georgia,"Microsoft YaHei","Times New Roman",serif;
font-weight: bold;
height: 86px;
margin: 25px 5px;
moz-animation: animatedBackground 10s linear infinite;
moz-background-size: cover;
ms-animation: animatedBackground 10s linear infinite;
position: relative;
text-align: center;
webkit-animation: animatedBackground 10s linear infinite;
webkit-background-size: cover;
width: 150px;
zoom: 1;
}
.hex.hex-gap
{
margin-left: 86px;
}
.hex a
{
display: block;
height: 100%;
left: 0;
position: absolute;
text-indent: -9999em;
top: 0;
width: 100%;
}
.hex .corner-1
{
moz-transform: rotate(60deg);
ms-transform: rotate(60deg);
o-transform: rotate(60deg);
transform: rotate(60deg);
webkit-transform: rotate(60deg);
}
.hex .corner-1:before
{
moz-transform: rotate(-60deg) translate(-87px,0);
moz-transform-origin: 0 0;
ms-transform: rotate(-60deg) translate(-87px,0);
ms-transform-origin: 0 0;
o-transform: rotate(-60deg) translate(-87px,0);
o-transform-origin: 0 0;
transform: rotate(-60deg) translate(-87px,0);
transform-origin: 0 0;
webkit-transform: rotate(-60deg) translate(-87px,0);
webkit-transform-origin: 0 0;
}
.hex .corner-2
{
moz-transform: rotate(-60deg);
ms-transform: rotate(-60deg);
o-transform: rotate(-60deg);
transform: rotate(-60deg);
webkit-transform: rotate(-60deg);
}
.hex .corner-2:before
{
bottom: 0;
moz-transform: rotate(60deg) translate(-44px,-12px);
ms-transform: rotate(60deg) translate(-44px,-12px);
o-transform: rotate(60deg) translate(-44px,-12px);
transform: rotate(60deg) translate(-44px,-12px);
webkit-transform: rotate(60deg) translate(-44px,-12px);
}
.hex .corner-3
{
moz-transform: rotate(0);
ms-transform: rotate(0);
o-transform: rotate(0);
transform: rotate(0);
webkit-transform: rotate(0);
}
.hex .corner-3:before
{
moz-transform: rotate(0) translate(-12px,-44px);
ms-transform: rotate(0) translate(-12px,-44px);
o-transform: rotate(0) translate(-12px,-44px);
transform: rotate(0) translate(-12px,-44px);
webkit-transform: rotate(0) translate(-12px,-44px);
}
.hex .inner
{
color: #eee;
position: absolute;
right: 0;
top: 0;
display: inline;
float: left;
width: 98.3333%;
margin: 0px 0.833333%;
}
.hex .inner a
{
color: #fff;
text-indent: 0;
}
.hex h4
{
margin: 0;
}
.hex hr
{
border: 0;
border-top: 1px solid #eee;
margin: 15px auto;
width: 60%;
}
.hex p
{
font-size: 22px;
margin: 0 auto;
width: 80%;
}
.hex.hex-1
{
background: #74cddb;
}
.hex.hex-2
{
background: #f00;
}
.hex.hex-3
{
background: #80b971;
}
.hex.hex-back
{
background: #80b971;
}
.hex.hex-back a
{
padding: 0 4px;
}
.hex .corner-1,.hex .corner-2,.hex .corner-3
{
backface-visibility: hidden;
background: inherit;
height: 100%;
left: 0;
moz-backface-visibility: hidden;
ms-backface-visibility: hidden;
o-backface-visibility: hidden;
overflow: hidden;
position: absolute;
top: 0;
webkit-backface-visibility: hidden;
width: 100%;
}
.hex .corner-1:before,.hex .corner-2:before,.hex .corner-3:before
{
backface-visibility: hidden;
background: inherit;
background-repeat: no-repeat;
content: '';
height: 173px;
left: 0;
moz-backface-visibility: hidden;
ms-backface-visibility: hidden;
o-backface-visibility: hidden;
position: absolute;
top: 0;
webkit-backface-visibility: hidden;
width: 173px;
}
.hex-caption
{
background-color: rgba(0,0,0,0.5);
color: #fff;
left: 0;
moz-transition: all 300ms ease-out;
ms-transition: all 300ms ease-out;
o-transition: all 300ms ease-out;
position: absolute;
transition: all 300ms ease-out;
webkit-transition: all 300ms ease-out;
}
.hex:hover .hex-simple-caption
{
moz-transform: translateY(-100%);
ms-transform: translateY(-100%);
o-transform: translateY(-100%);
transform: translateY(-100%);
visibility: visible;
webkit-transform: translateY(-100%);
}
.hex-simple-caption
{
bottom: -60px;
display: block;
height: 30px;
line-height: 25pt;
text-align: center;
visibility: hidden;
width: 100%;
}
.hex-background
{
left: -80px;
position: absolute;
top: -136px;
width: 900px;
z-index: -1;
}
.hex-background .hex
{
background-color: #708090;
}
.als-viewport
{
height: 390px;
margin: 0 auto;
overflow: hidden;
position: relative;
}
.als-wrapper
{
list-style: none;
position: relative;
}
.als-item
{
cursor: pointer;
display: block;
float: left;
position: relative;
text-align: center;
}
.als-prev,.als-next
{
clear: both;
cursor: pointer;
position: absolute;
}
.als-container
{
background: none repeat scroll 0% 0% #2d2d2d;
border-color: #ddd;
border-style: solid;
border-width: 1px 0;
color: #ccc;
line-height: 25.6px;
margin: 0 -20px;
overflow: auto;
padding: 15px 20px;
position: relative;
text-align: center;
width: 100%;
z-index: 0;
}
.als-container .als-item
{
display: block;
margin: 0 5px;
margin: 0 auto;
min-height: 120px;
min-width: 100px;
padding: 4px 0;
text-align: center;
vertical-align: middle;
}
.als-container .als-prev
{
font-size: 30px;
left: 30px;
}
.als-container .als-next
{
font-size: 30px;
right: 30px;
}
.als-container .als-prev,.als-container .als-next
{
top: 175px;
}
.icon-arrow-left
{
display:inline-block;
width:32px;
height:32px;
line-height:32px;
border-top:3px solid #aaa;
border-right:3px solid #aaa;
-ms-transform:rotate(225deg);
-moz-transform:rotate(225deg);
-webkit-transform:rotate(225deg);
transform:rotate(225deg);
}
.icon-arrow-right
{
display:inline-block;
width:32px;
height:32px;
line-height:32px;
border-top:3px solid #aaa;
border-right:3px solid #aaa;
-ms-transform:rotate(45deg);
-moz-transform:rotate(45deg);
-webkit-transform:rotate(45deg);
transform:rotate(45deg);
}

架構

hex page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="hex-container">
<div class="hex-background">
<div class="hex hex-gap" style="background-image: url();">
<div class="corner-1"></div>
<div class="corner-2"></div>
<div class="corner-3"></div>
<div class="inner"></div>
</div>
<div class="hex" style="background-image: url();">
<div class="corner-1"></div>
<div class="corner-2"></div>
<div class="corner-3"></div>
<div class="inner"></div>
</div>
...
</div>
</div>

原本網路提供 hex 只有 corner-1corner-2,這樣的做法無法產生 cover 的圖示,因此這裡增加 corner-3,但仍然會看到一條一條格線在斜邊上,不過已經相當足夠。

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="als-container" id="als-container_0" data-id="als-container_0">
<div class="als-viewport" data-id="als-viewport_0" style="width: 800px; height: 328px;">
<ul class="als-wrapper" data-id="als-wrapper_0" style="width: 4800px; height: 328px;">
<li class="als-item" data-linkid="-6" id="als-item_0_0" style="left: 0px;">
insert hex page
</li>
<li class="als-item" data-linkid="-1" id="als-item_0_0" style="left: 0px;">
insert hex page
</li>
...
</ul>
</div>
</div>

根據原本的 jquery.als-1.6.js 並沒有提供跳轉的操作,也就是說不能直接 shift 到指定位置,只能倚靠往左和往右的觸發,因此特別自己增加了 data-linkid 為操作手段。

hexo blog plugin

我已經把產生方式寫在 hexo-tag-oj 裡頭,下載使用 hexo-tag-plugin

不過相關的 js 還有 css 要自己擺放,請參考上面的描述項目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{\% ojblock hex \%}
{
"album" : [
{
"cover": {"title": "<h4>THEME</h4><hr /><p>Stephanie Dola</p>", "class": "hex-1"},
"photo": [
{"imgur": "http://i.imgur.com/yIoACHc.gif"},
{"imgur": "http://i.imgur.com/4pzxseN.jpg"}
]
},
{
"cover": {"title": "<h4>THEME</h4><hr /><p>萌~萌~哒~</p>", "class": "hex-2"},
"photo": [
{"imgur": "http://i.imgur.com/YSmWA3g.gif"},
{"imgur": "http://i.imgur.com/5IHR8bQ.gif"}
]
},
{
"cover": {"title": "<h4>THEME</h4><hr /><p>其他</p>", "class": "hex-3"},
"photo": [
{"imgur": "http://i.imgur.com/vpKzynV.gif"},
{"imgur": "http://i.imgur.com/rctEEyS.gif"}
]
}
]
}
{\% endojblock \%}

#

Read More +

JQuery 魔法陣製作 Magic Circle

製作起源

魔法陣字型出處

也是因為在 2014-04-17 出了一款魔法陣字型,在藉由惡友們的催促下,不,是誘導下嘗試做了 jquery 的插件來完成魔法陣的製作。當然沒有網址中做得那麼好看。

不過具體下也努力去完成了。附圖如下:

製作

前置作業

  • JQuery
  • CSS 旋轉和陰影配置

開始

  • 配置多層圓,可以參考 這裡,先將內容拆成 <span>A</span> 的形式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    h1 span {
    font: 24px myFirstFont, Monaco, MonoSpace;
    height: 300px;
    position: absolute;
    width: 20px;
    left: 50%;
    top: 0;
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    -ms-transform-origin: 50% 50%;
    -o-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    }
  • 將每個 <span> 設置成絕對座標配置,乍看下是一個長條形,並且使用 transform-origin 50% 50% 設置旋轉中心,也就是長條形的正中間。rgba(177, 17, 22, 1) 為血紅色

更新

  • 接著要計算字距,來方便每一個字符偏轉角度。而且每一層圓的偏轉角度還有所不同,這裡我並沒有詳細去計算。

  • transform rotate(50 deg) 用來旋轉

  • 光暈效果呈現 box-shadow 0px 0px 10px rgba(177, 17, 22, 1) 於外部產生陰影。

    • 至於內部效果沒有做得很好看。

山田かみら 的建議下,進行的大幅度地修改,同時也發現之前的版本有過度延遲的問題,原因都發生於過多的 for each 計算。

  • 先修正過於愚蠢的 CSS,加入比較好的 class 處理,來達到可以物件化。
  • 原本文字的處理仍需要使用旋轉的方式運作,而考慮將每一個圈放到同一個正方形內,直接對正方形作旋轉即可,剩下的操作交給瀏覽器去進行計算。因此,做了架構上的分層。

關於代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
$(function() {
$("#test1").magicsquare('fire', {radius: 500, radius_padding: 150,
radius_center: 200, duration: 10});

$("#test2").magicsquare('fire', {radius: 300, radius_padding: 50,
radius_center: 50, duration: 30});

$("#test1").draggable();
$("#test2").draggable();
$(".center-content").click(function() {
$("#test1").magicsquare('boom');
$("#test2").magicsquare('boom');
});
});
</script>

不知道 CSS3 穩定了沒有,在動畫處理引用 animate.css。

但是如果要完成連續型的動畫播放,單純 CSS 目前不想去研究能不能寫腳本。所以在定秒處理之後呼叫 callback() 去進行下一個動畫放置 (仍以 jquery 為主)。

剩下的交給 山田君 了。

Demo & 下載

very old version demo gif
demo link

repo jquery-magic-circle on Github

Reference

Read More +

網站看板娘製作

簡介

仿製偽春菜,用於網站小幫手,或者象徵物般的存在,高階可以引入對話 AI。 原版偽春菜,常見的別名又稱伺か、何か、任意、さくら。是一種電腦的桌面程式。視其功能的不同,從站在那陪使用者聊聊天解解悶,或報時對時收郵件,甚至處理電腦中大大小小的事都有可能辦到 而網站移植版有許多版本,看到大部分為php 版本、以WordPress Blog插件為大宗。 移植版常有的功能縮減為顯示公告、賣萌、統計上站人數等。跟電腦版不同較少出現會隨互動顯著成長的類型,另外在技術層面上,很多牽扯到資料庫的運用,相當複雜。

在靜態頁面上,如何簡單運用外連資料庫就是本次課題,決定開始偷偷動手腳了。

對了,Jquery 的模組化單純是老尼克推坑,接著朝向 AI 系統發展,就以目前情況來看,可能沒有時間去完成或了解。但是有一個關鍵詞 AIML 網址內附程式,可能會幫助興趣者從零開始建造,如果要有中文可能要去調用翻譯機就是了。還是要說明一下,這裡偷偷用了 google 提供的服務,所以沒有完善的資料庫語法,算是邪門歪道。

製作開始

前置作業

  • 獲取自己的 Google Spreadsheet 的 key 和 formkey。
  • 建立方式
    • 製作 Google 表單,也就是問卷。
    • 放出一個選項命名為 ‘store_data_base’ (預設,否則您將要修改 json)
    • 之後您將會得到表單對應的試算表。
    • 分別找到 key 和 formkey 還有表單欄位的 html tag id.
      • key - 在相對的試算表中,查閱當前網址
        https://docs.google.com/spreadsheet/ccc?key=0ArRwmWo93u-mdG93a2dkSWxIbHEzZjRIeDdxZXdsU1E&usp=drive_web#gid=0
        
        key=後面一串便是您需要的,您可以檢查以上的值和代碼中的預設值。
      • formkey - 在您開啟問卷的網址中
        https://docs.google.com/forms/d/1xADUIiBq1ksH7lxwSch1Nz_p2gSxdJttmv5OJOxJye0/viewform
        
        會發現 d/formkey/viewform 就在其中。
      • html tag id - 對問卷頁面查閱原始碼,找到輸入欄位類似於 entry.2030600456 的格式。
  • 本站使用的 My Google Spreadsheet 如有表單建立疑慮可參考。

  • 以下代碼可能會與 GitHub 上不同,會盡可能去兩邊更新。

JQuery Code

jquery.morris.ukagaka.resource.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
(function($){   // 封裝起來, 以免和外界js 變數衝突到
$.fn.extend({
//plugin name - animatemenu // 定義 plugin 名稱
ukagaka: function(options) {

//Settings list and the default values // 設定plugin input parameters 的預設值
var defaults = {
googleKey: '0ArRwmWo93u-mdG93a2dkSWxIbHEzZjRIeDdxZXdsU1E',
googleFormkey: '1xADUIiBq1ksH7lxwSch1Nz_p2gSxdJttmv5OJOxJye0',
googleSheet: "od6",
googleSheetField: "entry.2030600456",
talkTime: 10000
};

// 把預設值和實際輸入值比對, 如果有傳入值的則以傳入值為主
// 如此便得到輸入值 options (在此匿名函式中存在之變數)
var options = $.extend(defaults, options);
// 執行此 plugin 的實際動作, 對其作用對象的陣列迭代(iterate over), 例如說對$(".class_name") 呼叫此plugin, 則 this.each 就代表所有帶有 class_name 為 class 屬性的DOM element
return this.each(function() {
var o = options;

//Assign current element to variable, in this case is UL element
var obj = $(this); // obj 代表迭代到的單一物件

var key = o.googleKey;
var sheet = o.googleSheet;
var formkey = o.googleFormkey;
var sheetfield = o.googleSheetField;

var talking = [];

var innerSettingHTML = "";
innerSettingHTML += "<div id='ukagaka_img'></div>";
innerSettingHTML += "<div class='ukagaka_box'>";
innerSettingHTML += "<div class='ukagaka_msg' id='ukagaka_msgbox'>汝 先看看周遭</div>";
innerSettingHTML += "<div class='ukagaka_msg' id='ukagaka_menubox' style='display:none'>使用選單功能&#65292;吾才不需要汝教。<br/><br/><span id='ukagaka_menu_btn_addstring'>$ 學習</span><span id='ukagaka_menu_btn_renewlist'>$ 日誌</span><span id='ukagaka_menu_btn_exit'>$ 結束</span></div>";
innerSettingHTML += "<div class='ukagaka_msg' id='ukagaka_stringinput' style='display:none'>請輸入讓偽春菜學的句子<br/><br/><input id='ukagaka_addstring' type='text'/><span id='ukagaka_addmenu_add'>$ 增加</span><span id='ukagaka_btn_menu'>$ 取消</span></div>";
innerSettingHTML += "<div class='ukagaka_msg' id='ukagaka_renewlist' style='display:none'>更新日誌<br/><br/>Morris 修正<br/><br/>找尋 AI 系統<br/>找尋 AI 對話<br/><br/><span id='ukagaka_btn_menu'>$ 取消</span></div>";
innerSettingHTML += "<input id='ukagaka_sheetfield' type='hidden' value='" + sheetfield + "'>";
innerSettingHTML += "</div>";
obj.html(innerSettingHTML);

var footerMenuHTML = "";
footerMenuHTML += "<div id='ukagaka_controlpanel'>";
footerMenuHTML += "<span id='ukagaka_btn_display'>Display</span> ";
footerMenuHTML += "<span id='ukagaka_btn_menu'>Menu</span>";
footerMenuHTML += "</div>";
obj.after(footerMenuHTML);

function reloadtalking(){
/* JSON / load string from database */
$.getJSON("https://spreadsheets.google.com/feeds/list/" + key + "/" + sheet + "/public/values?alt=json", function(JData){
for (var i = 0; i < JData.feed.entry.length; i++) {
talking[i] = JData.feed.entry[i].gsx$storedatabase.$t;
// console.log("talk stmt : " + talking[i]);
}
$('input#ukagaka_addstring').attr('placeholder', '目前春菜學會了' + JData.feed.entry.length + '個字彙');
});
};

$(window).load(function(){
var talk_timer = setInterval(talkingbox, o.talkTime);
function talkingbox() {
if($("#ukagaka_msgbox").css("display") != 'none')
$("#ukagaka_msgbox").fadeOut(500, function(){
$(this).html(talking[Math.floor(Math.random() * talking.length)]).fadeIn(500)});
}
});
reloadtalking();
obj.draggable();
$(document).on('click', "span#ukagaka_btn_display", function(event) {
$("#ukagaka_panel").fadeToggle(1000);
});
$(document).on('click', "span#ukagaka_menu_btn_exit", function(event) {
$(".ukagaka_box div").fadeOut(500);
$("#ukagaka_msgbox").delay(500).fadeIn(500);
});
$(document).on('click',"span#ukagaka_btn_menu", function(event) {
$(".ukagaka_box div").fadeOut(500);
$("#ukagaka_menubox").delay(500).fadeIn(500);
});
$(document).on('click',"span#ukagaka_menu_btn_addstring", function(event) {
$(".ukagaka_box div").fadeOut(500);
$("#ukagaka_stringinput").delay(500).fadeIn(500);
});
$(document).on('click',"span#ukagaka_menu_btn_renewlist", function(event) {
$(".ukagaka_box div").fadeOut(500);
$("#ukagaka_renewlist").delay(500).fadeIn(500);
});
$(document).on('click',"span#ukagaka_addmenu_add", function(event) {
var add = $("input#ukagaka_addstring").val();
var googleSheetField = $('input#ukagaka_sheetfield').val();
var sendData = {};
sendData[googleSheetField] = add;
if(!((add.length <= 1) || add.indexOf('script') > -1|| add.indexOf('body') > -1 ||
add.indexOf('style') > -1 || add.indexOf('link') > -1 || add.indexOf('iframe') > -1 || add.indexOf('head') > -1 ||
add.indexOf('nav')>-1||add.indexOf('object')>-1||add.indexOf('embed')>-1)){
$.ajax({
type: 'POST',
url: 'https://docs.google.com/forms/d/' + formkey + '/formResponse',
data: sendData,
dataType: "xml",
statusCode: {
0: function() {
$("input#ukagaka_addstring").attr("value","");
$(".ukagaka_box div").fadeOut(500);
$("#ukagaka_msgbox").fadeOut(500, function(){
$(this).html("偽春菜學習了 !").fadeIn(1000)});
},
200: function() {
$("input#ukagaka_addstring").attr("value","");
$(".ukagaka_box div").fadeOut(500);
$("#ukagaka_msgbox").fadeOut(500, function(){
$(this).html("偽春菜學習了 !").fadeIn(1000)});
}
}
});
} else {
alert("OOPS!偽春菜不接受這個字串喔!");
}
});

});
}
});
})(jQuery);

CSS

以下 CSS 為原作設定。

ukagaka.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ukagaka_controlpanel {
background:white;padding:8px;
box-shadow:#555 0px 0px 4px;
text-shadow: #555 0px 0px 1px;
margin-bottom:-3px;
border-radius:5px 5px 0 0;
position:fixed;
right:40px;
bottom:0px;
font-size:10pt;
z-index:101;
}

#ukagaka_controlpanel span, #ukagaka_panel span {
padding:5px;
cursor:pointer;
height:0px;
}
#ukagaka_panel {
position: fixed;
right: 10px;
bottom: 10px;
width: 88.2px;
height: 230.3px;
z-index:10;
}
/* ukagaka msgbox */
.ukagaka_box{
position: absolute;
bottom: 117px;
right: 97px;
font-size: 10pt;
}
.ukagaka_msg{
width:195px;
background: white;
padding:10px;
word-wrap: break-word;
word-break: normal;
color:black;
box-shadow:rgba(15,15,15,0.8) 0px 0px 8px;
}
.ukagaka_msg::after {
width:10px;
height:10px;
-moz-transform:rotate(45deg);
-webkit-transform:rotate(45deg);
-o-transform:rotate(45deg);
-ms-transform:rotate(45deg);
transform:rotate(45deg);
background:white;
content: '';
float: right;
margin-right: -14px;
margin-top:7px;
box-shadow:rgba(15,15,15,0.8) 3px -3px 8px -3px;
}
/* */
#ukagaka_img {
background: url(./img/ukagaka_img.png) no-repeat;
width: 126px;
height: 329px;
transform: scale(0.7);
-ms-transform: scale(0.7);
-webkit-transform: scale(0.7);
-o-transform: scale(0.7);
-moz-transform: scale(0.7);
position: absolute;
top: -49px;
right: -19px;
}
#ukagaka_stringinput input {
width:95%;
}

Stylus

  • 如果你在 Nodejs 下想使用,這裡提供本站使用的 ukagaka.styl。
  • 最後在 theme/xxxx/source/css/style.styl 進行匯入。
    1
    @import '_partial/ukagaka'
theme/xxxx/source/css/_partial/ukagaka.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ukagaka_controlpanel 
font-size 1.1em
padding 0 0 0.3125em 0
position fixed
right 40px
bottom 0px
background color-section
span
font-family font-custom-family
color color-blue
border-radius 10px
border-width 5px
border-style solid solid solid
&:hover
color color-theme2
transition color .5s

#ukagaka_panel
padding 0.5em 2% 1em
width 88.2px
height 230.3px
position fixed
right 40px
bottom 40px
span
padding 5px
cursor pointer
height 0px

.ukagaka_box
border-radius 10px
border-width 5px
border-style solid dashed dashed
position absolute
bottom 150px
right 120px
font-size 100%
background color-section
color gray

.ukagaka_msg
border-radius 10px
padding 0.5em 2% 1em
color color-white
width 195px
font-family font-custom-family, font-default
&::before
font-smoothing()
padding-right 0.5em
span#ukagaka_menu_btn_addstring, span#ukagaka_menu_btn_renewlist,
span#ukagaka_menu_btn_exit
border-radius 5px
border-width 1px
border-style solid solid solid
display inline
color color-blue
&:hover
color color-theme2
&::before
font-smoothing()
padding-right 0.5em
span#ukagaka_btn_menu, span#ukagaka_addmenu_add
border-radius 5px
border-width 1px
border-style solid solid solid
display inline
color color-blue
&:hover
color color-theme2
&::before
font-smoothing()
padding-right 0.5em

#ukagaka_img
background url(/img/ukagaka_img.png) no-repeat
width 150px
height 350px
transform scale(0.7)
-ms-transform scale(0.7)
-webkit-transform: scale(0.7)
-o-transform scale(0.7)
-moz-transform scale(0.7)
position absolute
top -49px
right -19px

#ukagaka_stringinput
>input
width 95%

如何使用 How to use

一般網頁

  • 記得要使用 utf-8 的網頁,否則中文將會炸掉。
  • 記的要使用 jquery-ui.js。
  • 記得要使用 jquery-x.x.x.js。
  • 最後引入咱們的 ukagaka.resource.js 和 ukagaka.css。
  • 然後與一般的 jquery 綁定相同,請參考以下代碼。
  • 如果您要客製化,請傳入 $(element).ukagaka(options);
  • options 的操作,請詳見 $(element).ukagaka({xxx:yyy, zzz:www});
main.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script src='jquery.morris.ukagaka.resource.js' type='text/javascript'></script>

<link type="text/css" rel="stylesheet" href="ukagaka.css">
<!-- ukagaka start -->
<script>
$(document).ready(function() {
$('#ukagaka_panel').ukagaka();
});
</script>
<div id='ukagaka_panel'>

</div>
<!-- ukagaka end -->
</body>
</html>

Hexo Blog

萬里花

  • 如果您希望每一頁都能見到
    • 在 footer.ejs 下插入 HTML TAG 代碼。
    • 在 after_footer.ejs 進行綁定
  • 反之,請自行摸索
theme/xxxx/layout/_partial/post/after_footer.ejs
1
2
3
4
5
6
7
<% if (config.ukagaka) { %>
<script src="<%- config.root %>js/jquery-ui.js"></script>
<script src="<%- config.root %>js/jquery.morris.ukagaka.resource.js"></script>
<script type="text/javascript">
$('#ukagaka_panel').ukagaka();
</script>
<% } %>
  • 插入位置看您的造化
theme/xxxx/layout/_partial/post/footer.ejs
1
2
3
4
5
<!-- ukagaka BEGIN -->
<div id='ukagaka_panel'>

</div>
<!-- ukagaka END -->

學習與撰寫過程

第一次寫 JQuery 和 Google Spreadsheet 相關,然後將 CSS 修改成 Stylus。

  • Stylus 是 CSS 的前置處理,有點類似 .cpp 產出 .exe 的關係。
  • 改寫時一堆問題,Stylus 默認縮排 2 個空白,編譯上一堆問題沒發現,導致浪費時間。
  • Google Spreadsheet 由於現在比較新版,每個表單的輸入欄位 id 也有所不同,所以可能會比較特別一點。
  • 什麼是靜態網頁的定義越來越模糊,javascript 帶你引入一堆外部資料庫,用低廉免錢重新審視。
  • 學習用 ajax 調用 Google Spreadsheet 資料。
  • Track code 能力訓練。

GitHub

Reference

Read More +