手機可以橫拍,直拍
exif資訊裡有角度可以供php判斷
參考 http://php.net/manual/en/function.exif-read-data.php
IFD0 裡的 Orientation
1: 一般照片
2: 水平翻轉
3: 180度往左轉
4: 重直翻轉
5: 重直翻轉 + 90度往右轉
6: 90度往右轉
7: 水平翻轉 + 90度往右轉
8: 90度往左轉
2011年12月16日 星期五
2011年12月7日 星期三
計算MySQL可能用到的記憶體數量
參考: http://dev.mysql.com/doc/refman/5.0/en/memory-use.html
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_additional_mem_pool_size';
SHOW VARIABLES LIKE 'innodb_log_buffer_size';
SHOW VARIABLES LIKE 'thread_stack';
SET @kilo_bytes = 1024;
SET @mega_bytes = @kilo_bytes * 1024;
SET @giga_bytes = @mega_bytes * 1024;
SET @innodb_buffer_pool_size = 2 * @giga_bytes;
SET @innodb_additional_mem_pool_size = 16 * @mega_bytes;
SET @innodb_log_buffer_size = 8 * @mega_bytes;
SET @thread_stack = 192 * @kilo_bytes;
SELECT
( @@key_buffer_size + @@query_cache_size + @@tmp_table_size
+ @innodb_buffer_pool_size + @innodb_additional_mem_pool_size
+ @innodb_log_buffer_size
+ @@max_connections * (
@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size
+ @@join_buffer_size + @@binlog_cache_size + @thread_stack
) ) / @giga_bytes AS MAX_MEMORY_GB;
2011年11月22日 星期二
點選按鈕提示IE9釘選功能
<script type="text/javascript">
function addSite() {
try{
window.external.msAddSiteMode();
}catch(e){
alert("此功能僅適用於 Internet Explorer 9.");
}
}
</script>
<button onclick="addSite();">釘我</button>
2011年11月10日 星期四
2011年11月7日 星期一
2011年10月17日 星期一
css3 翻轉效果
#logo {width:200px; height:64px; background:url('../images/logo.png') top left no-repeat;
-webkit-animation-name: y-spin;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
}
@-webkit-keyframes y-spin {
0% { -webkit-transform: rotateY(0deg); }
50% { -webkit-transform: rotateY(180deg); }
100% { -webkit-transform: rotateY(360deg); }
}
2011年10月13日 星期四
2011年10月12日 星期三
透過google map由地址查詢經緯度
參考文件
http://code.google.com/intl/zh-TW/apis/maps/documentation/javascript/v2/services.html
測試 http://maps.google.com/maps/geo?q=%E5%8F%B0%E5%8C%97%E5%B8%82%E5%8D%97%E6%B8%AF%E5%8D%80%E4%B8%89%E9%87%8D%E8%B7%AF66%E8%99%9F&output=json&sensor=true
回傳
測試 http://maps.google.com/maps/geo?q=%E5%8F%B0%E5%8C%97%E5%B8%82%E5%8D%97%E6%B8%AF%E5%8D%80%E4%B8%89%E9%87%8D%E8%B7%AF66%E8%99%9F&output=json&sensor=true
回傳
{
"name": "台北市南港區三重路66號",
"Status": {
"code": 200,
"request": "geocode"
},
"Placemark": [ {
"id": "p1",
"address": "115台灣台北市南港區三重路66號",
"AddressDetails": {
"Accuracy" : 8,
"Country" : {
"AdministrativeArea" : {
"AdministrativeAreaName" : "台北市",
"Locality" : {
"DependentLocality" : {
"DependentLocalityName" : "三重里",
"PostalCode" : {
"PostalCodeNumber" : "115"
},
"Thoroughfare" : {
"ThoroughfareName" : "三重路66號"
}
},
"LocalityName" : "南港區"
}
},
"CountryName" : "台灣",
"CountryNameCode" : "TW"
}
},
"ExtendedData": {
"LatLonBox": {
"north": 25.0587660,
"south": 25.0560680,
"east": 121.6156030,
"west": 121.6129050
}
},
"Point": {
"coordinates": [ 121.6142540, 25.0574170, 0 ]
}
} ]
}
2011年9月9日 星期五
Facebook app 調整canvas的寬高
Facebook app 調整canvas的寬高
<div id="fb-root">
</div>
<script src="//connect.facebook.net/zh_TW/all.js">
</script>
<script>
FB.init({
appId : 'facebook_app_id',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true // enables OAuth 2.0
});
FB.Canvas.setSize({ width: 760, height: 1000 });
</script>
2011年9月4日 星期日
Facebook API 使用FQL 抓取朋友名字,圖片,生日
以下為使用FQL抓取朋友名字,圖片,生日的範例教學
注意:需先取得相關權限才能抓取資料
權限參考:http://developers.facebook.com/docs/reference/api/permissions/
注意:需先取得相關權限才能抓取資料
權限參考:http://developers.facebook.com/docs/reference/api/permissions/
include('facebook.php');
$facebook = new Facebook(array(
'appId' => $facebook_app_id,
'secret' => $facebook_app_secret,
'cookie' => true
));
$fb_id = $facebook->getUser();
try{
$aFriendList = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select uid, name, pic,birthday_date from user where uid in (select uid2 from friend where uid1 = '.$fb_id.')'
));
}catch (Exception $e) { }
var_dump($aFriendList);
?>
2011年8月25日 星期四
手機網頁,重返瀏覽器時自動重新整理
在手機上離開瀏覽器後再回到瀏覽器通常會看到上一次離開的畫面
如果網頁屬於最新消息之類的訊息,讓使用者回到瀏覽器時自動reload會非常的方便
以下是使用javascript來判斷是否要reload頁面
如果網頁屬於最新消息之類的訊息,讓使用者回到瀏覽器時自動reload會非常的方便
以下是使用javascript來判斷是否要reload頁面
var timenow = new Date().getTime();
timenow = Math.ceil(timenow/1000);
function autoReload(){
var checktime = new Date().getTime();
checktime = Math.ceil(checktime/1000);
if( (checktime - timenow) > 60 ){ //如果這邊超過60秒,應該是離開瀏覽器又回來,所以reload
location.reload();
}
timenow = checktime;
}
setInterval('autoReload();',5*1000); //5秒偵測一次
2011年8月18日 星期四
Firefox 6 網址列無法使用 javascript: function();
一般寫前端頁面如有使用 javascript 會在網址列直接下 javascript: function(); 來做debug的動作
更新到 firefox 6 發現網址列不吃 javascript: 了
原來有更好用的東西
tools -> web developer -> scratchpad
在裡面寫下要做的javascript語法,選取後按右鍵
Run 就可以看到執行結果
更新到 firefox 6 發現網址列不吃 javascript: 了
原來有更好用的東西
tools -> web developer -> scratchpad
在裡面寫下要做的javascript語法,選取後按右鍵
Run 就可以看到執行結果
2011年8月15日 星期一
google weather api
最近某個東西需要用到氣象資料
氣象局有個 FTP 可以抓取資料,但資料不太齊全
FTP位置 ftp://ftpsv.cwb.gov.tw/pub/forecast/
然後找了 http://developer.yahoo.com/weather/
實在是不好用...
網路上翻了翻
看到 http://www.google.com/ig/api?hl=zh-tw&weather=taipei
傳入城市名就可以取得一個xml,真是方便
更方便的是傳入經緯度
http://www.google.com/ig/api?hl=zh-tw&weather=,,,25012085,121465701
真是佛心來得
氣象局有個 FTP 可以抓取資料,但資料不太齊全
FTP位置 ftp://ftpsv.cwb.gov.tw/pub/forecast/
然後找了 http://developer.yahoo.com/weather/
實在是不好用...
網路上翻了翻
看到 http://www.google.com/ig/api?hl=zh-tw&weather=taipei
傳入城市名就可以取得一個xml,真是方便
更方便的是傳入經緯度
http://www.google.com/ig/api?hl=zh-tw&weather=,,,25012085,121465701
真是佛心來得
2011年8月1日 星期一
facebook 啟用測試帳號
使用Facebook API來打造網站功能時如果又有綁一個帳號只能投票一次的功能
開發時通常測試會很困擾 (要一直不斷清資料庫)
Facebook 放出了測試帳號功能 https://developers.facebook.com/docs/test_users/
一個 app 可以有500組測試帳號
建立一個測試帳號
Developer App 裡面有介面可以新增
About->Roles->Testers->Add 然後填資料就可以新增測試帳號
官方文件 http://developers.facebook.com/blog/post/527/
開發時通常測試會很困擾 (要一直不斷清資料庫)
Facebook 放出了測試帳號功能 https://developers.facebook.com/docs/test_users/
一個 app 可以有500組測試帳號
建立一個測試帳號
if( $_POST ){
$url = 'https://graph.facebook.com/'.urlencode($facebook_app_id).'/accounts/test-users?';
$url .= 'installed=false';
$url .= '&name='.urlencode($_POST['name']);
$url .= '&method=post';
$url .= '&access_token='.urlencode($facebook_app_id).'|'.urlencode($facebook_app_secret);
header('Location: '.$url); exit;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form method="post" action="test.php">
測試帳號匿名:<input type="text" name="name"><br>
<input type="submit" value="送出">
</form>
</body>
</html>
Developer App 裡面有介面可以新增
About->Roles->Testers->Add 然後填資料就可以新增測試帳號
官方文件 http://developers.facebook.com/blog/post/527/
2011年7月27日 星期三
iphone safari 電話號碼判斷
iphone會貼心的將電話號碼變成連結
但有時候會誤判,像序號之類的東西在手機上呈現會被iphone加上連結
只要在
<head>裡加上
但有時候會誤判,像序號之類的東西在手機上呈現會被iphone加上連結
只要在
<head>裡加上
<meta name="format-detection" content="telephone=no">
這樣就可以關閉iphone判斷電話號碼的功能
2011年7月26日 星期二
Facebook API 使用 FQL 抓取相簿裡的所有相片 (photo) 實作範例教學
接著 Facebook API 使用 FQL 抓取相簿封面 (album) 實作範例教學
加入
$aPhoto 即為該相簿裡的照片路徑
加入
//將 aid 傳入
try{
$aPhoto = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select src,src_big from photo where aid ="'.$aid.'"'
));
}catch(Exception $e) { }
$aPhoto 即為該相簿裡的照片路徑
Facebook API 使用 FQL 抓取相簿封面 (album) 實作範例教學
PHP部分:
這樣 $aAlbum 會有相簿名稱(name)與圖片路徑(cover_src)
$facebook = new Facebook(
array(
'appId' => $facebook_app_id,
'secret' => $facebook_app_secret,
'cookie' => true,
)
);
//facebook id
$fb_id = $facebook->getUser();
$aLoginParam = array( 'req_perms' => 'user_photos' );
//登入
if( !$fb_id ){
$auth_url = $facebook->getLoginUrl($aLoginParam);
header('Location: '.$auth_url);
exit;
}
//權限
try{
$perm = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select user_photos from permissions where uid='.$fb_id
));
if( $perm[0]['user_photos'] != '1' ){
$url = $facebook->getLoginUrl($aLoginParam);
header('Location: '.$url); exit;
}
}catch (Exception $e) { }
//取得封面的
try{
$aAlbum = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select aid,name,cover_pid from album where owner='.$fb_id
));
}catch(Exception $e){ }
$aId = array();
foreach( $aAlbum as $k => $v ){
$aId[] = $v['aid'];
}
//取得封面圖片路徑
try{
$aPhoto = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select pid,src_big from photo where pid in(select cover_pid from album where owner='.$fb_id.')'
));
}catch(Exception $e){ }
$aCover = array();
foreach( $aPhoto as $k => $v ){
$aCover[$v['pid']] = $v['src_big'];
}
foreach( $aAlbum as $k => $v ){
$aAlbum[$k]['cover_src'] = $aCover[$aAlbum[$k]['cover_pid']];
}
var_dump($aAlbum);
這樣 $aAlbum 會有相簿名稱(name)與圖片路徑(cover_src)
2011年7月7日 星期四
Facebook Graph API Explorer
Facebook Graph API 開發總算有方便的測試工具
https://developers.facebook.com/tools/explorer
點選 "Get Access Token"按鈕後會跳出權限選擇
然後點選右邊的Connections列表就可以看到graph回傳的資料
大幅減少開發與測試的時間
官方簡易使用教學 http://developers.facebook.com/blog/post/517/
https://developers.facebook.com/tools/explorer
點選 "Get Access Token"按鈕後會跳出權限選擇
然後點選右邊的Connections列表就可以看到graph回傳的資料
大幅減少開發與測試的時間
官方簡易使用教學 http://developers.facebook.com/blog/post/517/
2011年7月5日 星期二
facebook 傳送訊息 (facebook message)
facebook 推出了送訊息的對話框
http://developers.facebook.com/docs/reference/dialogs/send/
可以由外部網站直接跳出送訊息的對話框,讓網友可以把資訊直接分享給朋友
實作範例教學:
http://developers.facebook.com/docs/reference/dialogs/send/
可以由外部網站直接跳出送訊息的對話框,讓網友可以把資訊直接分享給朋友
實作範例教學:
<?php
$appid = '117616504920787';
$name = '這是測試';
$link = 'http://'.$server.'/test/?link=1';
$redir = 'http://'.$server.'/test/?link=2';
$to = '100000514502035';
$desc = '敘述';
$img = '圖片';
$dir = 'http://www.facebook.com/dialog/send?';
$dir .= 'app_id='.$appid;
$dir .= '&name='.urlencode($name);
$dir .= '&link='.urlencode($link);
$dir .= '&description='.urlencode($desc);
$dir .= '&picture='.urlencode($img);
$dir .= '&to='.urlencode($to);
$dir .= '&redirect_uri='.urlencode($redir);
header('Location: '.$dir); exit;
?>
2011年7月1日 星期五
facebook 打卡 api 應用 (搭配google map)
偽打卡
使用facebook checkin api,搭配google map
經過facebook connect login後
可神遊到其他地方打卡
展示 http://checkin.978.tw/
facebook打卡範例 : http://blog.978.tw/2011/04/facebook-check-in-api-graph.html
google map部分實作範例教學:
使用facebook checkin api,搭配google map
經過facebook connect login後
可神遊到其他地方打卡
展示 http://checkin.978.tw/
facebook打卡範例 : http://blog.978.tw/2011/04/facebook-check-in-api-graph.html
google map部分實作範例教學:
var map;
var infowindow;
function checkin(id,lat,lng){ //打卡
$.get('facebook_checkin.php',{'id':id,'lat':lat,'lng':lng},function(o){
alert(o);
});
}
function infoWindow(lat,lng){
if( infowindow ){ //關閉上一個對話框
infowindow.close();
}
var place_content = '點選下列地點後打卡<br>';
$.get('facebook_place.php',{'lat':lat,'long':lng},function(o){
for( var i=0; i<o.length; i++ ){ //可打卡地點
if(o[i].name!=undefined){
place_content += '<a href="javascript:checkin('+o[i].id+','+lat+','+lng+');">'+o[i].name+'</a><br>';
}
}
infowindow = new google.maps.InfoWindow(
{ content: place_content,
size: new google.maps.Size(50,50),
position: new google.maps.LatLng(lat,lng)
});
infowindow.open(map);
});
}
function map_init(){ //google map
var myLatlng = new google.maps.LatLng(25.047795,121.516900);
var myOptions = {
zoom: 12,
center: myLatlng,
streetViewControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function(event) {
var lat = event.latLng.Ia;
var lng = event.latLng.Ja;
infoWindow(lat,lng);
});
}
$(document).ready(function(){
$('#map_canvas').css({height:$(window).height()*0.8,width:$(window).width()});
map_init();
});
2011年6月27日 星期一
iphone ios5 開啟 wifi sync
先把手機接上USB,連上itunes後
在Summary的頁面會看到
Sync over Wi-Fi connection
勾選後sync手機一次
之後就可以wifi sync
在Summary的頁面會看到
Sync over Wi-Fi connection
勾選後sync手機一次
之後就可以wifi sync
date 修正系統時間
用date修改系統時間
印象中如下
# date yymmddhhiiss
# date 110627122030
結果發現不能動
後來把秒數拿就可以了
# date yymmddhhii
# date 1106271220
印象中如下
# date yymmddhhiiss
# date 110627122030
結果發現不能動
後來把秒數拿就可以了
# date yymmddhhii
# date 1106271220
2011年6月17日 星期五
facebook requests Dialog 使用 (送出邀請朋友)
facebook 文件 http://developers.facebook.com/docs/reference/dialogs/requests/
運用FQL跟requests Dialog來傳送邀請給線上好友
實作範例教學:
PHP
HTML
運用FQL跟requests Dialog來傳送邀請給線上好友
實作範例教學:
PHP
include('inc/facebook.php');
$facebook = new Facebook(array(
'appId' => $facebook_app_key,
'secret' => $facebook_app_secret,
'cookie' => true
));
$fb_id = $facebook->getUser();
if( !$fb_id ){
echo 'error'; exit;
}
try{
$aFriends = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select uid from user where online_presence in("active") and uid IN (SELECT uid1 FROM friend WHERE uid2 = '.$fb_id.') order by name'
));
}catch(Exception $e){ }
$aF = array();
foreach( $aFriends as $k => $v ){
$aF[] = $v['uid'];
}
HTML
<div id="fb-root"></div>
<script src="http://connect.facebook.net/zh_TW/all.js"></script>
<script>
FB.init({
appId : '<?php echo h($facebook_app_id); ?>',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.ui({ method: 'apprequests'
,message: '可自定文字'
,filters: "[{name: '線上好友', user_ids: [<?php echo join(',',$aF); ?>]}]"
,title:"可自定標題"
,data:o
},function(r){ //回傳request_id
alert(r.request_ids[0]})
});
});
</script>
2011年6月13日 星期一
手機網頁,判斷橫看或是直看
手機可以用直著看,也可以轉橫著看
但如果手機頁面沒做相對應的處理,一轉換方向頁面就會破掉
以下的code為判斷手機翻轉時,對頁面做處理的範例
以iphone為例實作範例教學:
但如果手機頁面沒做相對應的處理,一轉換方向頁面就會破掉
以下的code為判斷手機翻轉時,對頁面做處理的範例
以iphone為例實作範例教學:
<!-- 在 body 裡加上 onorientationchange -->
<body onorientationchange="changePosition();">
<img id="bg_img" src="img/test.png">
<script>
//圖的長寬
var img_width = 320;
var img_height = 416;
var ppm;
function changePosition(){
//每次翻轉就重新把圖長寬設定一次
ppm = window.innerWidth/img_width;
document.getElementById('bg_img').style.width = window.innerWidth;
document.getElementById('bg_img').style.height = img_height*ppm;
//把網址列藏起來
setTimeout('window.scrollTo(0,1);', 5);
}
changePosition();
</body>
使用 facebook api 時,明明正常卻突然不能用
facebook 的 api 有時候跑的好好的
但卻會突然爛掉
這時候別急著改code找問題
先看看 https://developers.facebook.com/live_status
如果是facebook本身出了問題,省點力氣早點睡覺
但卻會突然爛掉
這時候別急著改code找問題
先看看 https://developers.facebook.com/live_status
如果是facebook本身出了問題,省點力氣早點睡覺
flash params 裡的 wmode
遇到一個狀況
wmode:"transparent" 在google chrome輸入中文會有問題
但 wmode:"window" 在ie時沒辦法把facebook加入粉絲的按鈕疊上去
於是...
wmode:"transparent" 在google chrome輸入中文會有問題
但 wmode:"window" 在ie時沒辦法把facebook加入粉絲的按鈕疊上去
於是...
wmode: "<?php echo (strspn("MSIE",$_SERVER["HTTP_USER_AGENT"])==4)?'transparent':'window'; ?>"
2011年6月2日 星期四
Apple Magic Trackpad
http://www.apple.com/tw/magictrackpad/
很天真的以為他會自己進入省電模式
結果要按住電源久一點才會關掉
浪費了很多電,對不起大自然
很天真的以為他會自己進入省電模式
結果要按住電源久一點才會關掉
浪費了很多電,對不起大自然
2011年5月20日 星期五
iphone safari 隱藏網址列
手機畫面很小
運用點小技巧可以讓觀看畫面大一點
說穿了就是當畫面都下載完後,把畫面往下拉一點,讓網址列看不到
參考網址 : http://shaunmackey.com/articles/mobile/how-to-hide-the-address-bar-in-mobilesafari/
一行寫法
運用點小技巧可以讓觀看畫面大一點
<script>
window.addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false);
function hideURLbar(){ window.scrollTo(0,1); }
</script>
說穿了就是當畫面都下載完後,把畫面往下拉一點,讓網址列看不到
參考網址 : http://shaunmackey.com/articles/mobile/how-to-hide-the-address-bar-in-mobilesafari/
一行寫法
<script>window.addEventListener("load", function() { setTimeout('window.scrollTo(0,1);', 1); }, false);</script>
2011年5月16日 星期一
html5 - 3D Engine Physics bullet.js
http://pl4n3.blogspot.com/2010/07/bulletjs-javascript-physics-engine.html
抓了一份簡單的修改側測試了一下
測試實作範例網址 http://excite.978.tw/html5/bullet/
抓了一份簡單的修改側測試了一下
測試實作範例網址 http://excite.978.tw/html5/bullet/
2011年5月10日 星期二
macos 製作一個可開機的usb隨身碟 (freebsd)
#轉成 dmg
% hdiutil convert -format UDRW -o bsd.img FreeBSD-8.2-RELEASE-i386-disc1.iso
#看隨身碟代號
% diskutil list
#unmount隨身碟 (/dev/disk1 為 diskutil list 看到的隨身碟代號)
% diskutil unmountDisk /dev/disk1
#寫入隨身碟
sudo dd if=/Users/excite/Desktop/bsd/bsd.img.dmg of=/dev/rdisk1 bs=1m
% hdiutil convert -format UDRW -o bsd.img FreeBSD-8.2-RELEASE-i386-disc1.iso
#看隨身碟代號
% diskutil list
#unmount隨身碟 (/dev/disk1 為 diskutil list 看到的隨身碟代號)
% diskutil unmountDisk /dev/disk1
#寫入隨身碟
sudo dd if=/Users/excite/Desktop/bsd/bsd.img.dmg of=/dev/rdisk1 bs=1m
macos - iso檔轉成dmg
參考: http://macosx.com/forums/networking-compatibility/28079-iso-img-conversion.html
指令如下
hdiutil convert "/path/to/name.iso" -format UDRW -o "/path/to/output.dmg"
2011年5月9日 星期一
php 使用GD製作圖片時出現 imagecreatefromjpeg() recoverable error: Premature end of JPEG file
使用php GD將一張JPG疊到另一張JPG時出現錯誤訊息
imagecreatefromjpeg() recoverable error: Premature end of JPEG file
解法
在php裡加上 ini_set('gd.jpeg_ignore_warning', 1);
參考網站 : http://worcesterwideweb.com/2008/03/17/php-5-and-imagecreatefromjpeg-recoverable-error-premature-end-of-jpeg-file/
imagecreatefromjpeg() recoverable error: Premature end of JPEG file
解法
在php裡加上 ini_set('gd.jpeg_ignore_warning', 1);
參考網站 : http://worcesterwideweb.com/2008/03/17/php-5-and-imagecreatefromjpeg-recoverable-error-premature-end-of-jpeg-file/
2011年5月4日 星期三
html5 - Javascript 3D Engine three.js 實作範例教學 (三)
再延續上次的立體方塊
將影片貼到方塊上
實作範例教學:
HTML部分
實作 : http://excite.978.tw/html5/3d_cube_video.php
將影片貼到方塊上
實作範例教學:
HTML部分
<video id="video0" autoplay>
<source src="video/1.mp4">
</video>
<video id="video1" autoplay>
<source src="video/2.mp4">
</video>
<video id="video2" autoplay>
<source src="video/3.mp4">
</video>
<video id="video3" autoplay>
<source src="video/4.mp4">
</video>
<video id="video4" autoplay>
<source src="video/5.mp4">
</video>
<video id="video5" autoplay>
<source src="video/6.mp4">
</video>
Javascript部分
var container, camera, scene, projector, renderer,particleMaterial;
var image = new Array();
var imageContext = new Array();
var texture = new Array();
var video = new Array();
var theta = 0;
var radius = 600;
$('body').append(
$('<div id="main"/>').attr(
{width:($(window).width()),height:($(window).height())}
)
);
var aVideoCount = new Array();
var VideoCount = new Array();
var LoadingText = 'Loading';
//preLoad();
init();
function preLoad(){
$('#main').html('<p style="text-align:center;">'+LoadingText+'</p>');
if( VideoCount < 6 ){
LoadingText = LoadingText + '.';
loadVideo();
setTimeout('preLoad();',1000);
}else{
$('#main').html('');
init();
}
}
function loadVideo(){
for( var i = 0 ; i < 6 ; i++ ){
video[i] = $('#video'+i).get(0);
video[i].style.display = 'none';
if( video[i].readyState === video[i].HAVE_ENOUGH_DATA ) {
if(aVideoCount[i] < 1 ){
VideoCount++;
aVideoCount[i] = 1;
}
}
}
}
function init(){
container = $('#main').get(0);
camera = new THREE.Camera( 70, ($(window).width()) / ($(window).height()), 1, 10000 );
camera.position.y = 300;
camera.position.z = 500;
scene = new THREE.Scene();
var materials = [];
for(var i = 0; i < 6; i++){
$('#main').append($('<canvas id="canvas'+i+'"/>').css(
{width:'100px',height:'100px',display:'none'}
)
);
video[i] = $('#video'+i).get(0);
video[i].style.display = 'none';
image[i] = $('#canvas'+i).get(0);
imageContext[i] = image[i].getContext( '2d' );
imageContext[i].fillStyle = '#000000';
imageContext[i].fillRect( 0, 0, 100, 100 );
texture[i] = new THREE.Texture( image[i] );
texture[i].minFilter = THREE.LinearFilter;
texture[i].magFilter = THREE.LinearFilter;
materials.push( [ new THREE.MeshBasicMaterial({map: texture[i]}) ] );
}
var object = new THREE.Mesh( new THREE.Cube( 100, 100, 100, 1, 1, 1, materials ), new THREE.MeshFaceMaterial());
object.position.x = 100;
object.position.y = 100;
object.position.z = 500;
object.rotation.x = ( Math.random() * 360 ) * Math.PI / 180;
object.rotation.y = ( Math.random() * 360 ) * Math.PI / 180;
object.rotation.z = ( Math.random() * 360 ) * Math.PI / 180;
scene.addObject( object );
renderer = new THREE.CanvasRenderer();
renderer.setSize( $(window).width(), $(window).height() );
container.appendChild( renderer.domElement );
animate();
}
function animate() {
setTimeout( 'animate();', 1000 / 60 );
render();
}
function render() {
theta += 0.2;
camera.position.x = radius * Math.sin( theta * Math.PI / 360 );
camera.position.y = radius * Math.sin( theta * Math.PI / 360 );
camera.position.z = radius * Math.cos( theta * Math.PI / 360 );
for(var i = 0 ; i < 6 ; i++ ){
if( video[i].readyState === video[i].HAVE_ENOUGH_DATA ) {
if( video[i].pause == true ){
video[i].play();
}
imageContext[i].drawImage( video[i], 0, 0 );
if ( texture[i] ) texture[i].needsUpdate = true;
}
if( video[i].ended == true ){
video[i].currentTime = 0;
video[i].play();
}
}
renderer.render( scene, camera );
}
實作 : http://excite.978.tw/html5/3d_cube_video.php
2011年4月29日 星期五
html5 - Javascript 3D Engine three.js 實作範例教學 (二)
繼上一篇在空間裡飛行的朋友照
現在將朋友照貼到立體的方塊上
變更Javascript部分
實作範例教學:
實作範例 : http://excite.978.tw/html5/3d_cube.php
現在將朋友照貼到立體的方塊上
變更Javascript部分
實作範例教學:
var container = new Array();
var camera = new Array();
var scene = new Array();
var renderer = new Array();
var cube = new Array();
var plane = new Array();
var targetRotation = new Array();
var targetRotationOnMouseDown = new Array();
var mouseX = new Array();
var mouseXOnMouseDown = new Array();
var windowHalfX = ($(window).width()) / 2;
var windowHalfY = ($(window).height()) / 2;
var cubeSize = Math.floor(($(window).width())/5);
var aImgData = new Array();
var imgStart = 0;
var total = 5;
$('body').append(
$('<div id="main"/>').attr(
{align:'center',width:(cubeSize*3),height:(cubeSize*3)}
)
);
$(window).load(function() {
var count = 0;
$('.img').each(function(index,value){
aImgData[index] = new Image();
aImgData[index].src = value.src;
aImgData[index].onload = function(){
count++;
loadImg(count);
}
});
});
function loadImg(count){
if( count == $('.img').length ){
init();
}
}
function init(){
for(var i=0; i<= total; i++ ){
newCube(i);
}
animate();
}
function newCube(num){
var domId = 'cube'+num;
var cubeTop = cubeSize*Math.floor(num/3);
var cubeLeft = (cubeSize)+cubeSize*(num%3);
cubeTop = cubeTop + 'px';
cubeLeft = cubeLeft + 'px';
$('#main').append(
$('<div id="'+domId+'"/>').css(
{width:cubeSize+'px',height:cubeSize+'px',position:'absolute',top:cubeTop,left:cubeLeft}
)
);
container[num] = $('#'+domId).get(0);
camera[num] = new THREE.Camera( 70, ($(window).width()) / ($(window).width()), 1, 1000 );
camera[num].position.y = 150;
camera[num].position.z = 500;
camera[num].target.position.y = 150;
scene[num] = new THREE.Scene();
//cube
var materials = [];
for ( var i = 0; i < 6; i ++ ) {
materials.push( [ new THREE.MeshBasicMaterial({map: ImageUtils.loadTexture(aImgData[imgStart].src)}) ] );
imgStart++;
}
cube[num] = new THREE.Mesh( new Cube( cubeSize, cubeSize, cubeSize, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() );
cube[num].position.y = 180;
cube[num].overdraw = true;
scene[num].addObject( cube[num] );
//plane
plane[num] = new THREE.Mesh( new Plane( (cubeSize*0.95), (cubeSize*0.95) ), new THREE.MeshBasicMaterial( { color: 0x222222 } ) );
plane[num].rotation.x = - 90 * ( Math.PI / 180 );
plane[num].overdraw = true;
scene[num].addObject( plane[num] );
renderer[num] = new THREE.CanvasRenderer();
renderer[num].setSize( cubeSize, cubeSize );
container[num].appendChild( renderer[num].domElement );
targetRotation[num] = 0;
targetRotationOnMouseDown[num] = 0;
mouseX[num] = 0;
mouseXOnMouseDown[num] = 0;
$('#'+domId).mouseover(function(e){
mouseX[num] = e.clientX - windowHalfX;
targetRotation[num] = targetRotationOnMouseDown[num] + ( mouseX[num] - mouseXOnMouseDown[num] ) * 0.02;
});
}
function animate() {
setTimeout( 'animate();', 1000 / 60 );
render();
}
function render() {
for(var i =0; i <= total; i++ ){
plane[i].rotation.z = cube[i].rotation.y += ( targetRotation[i] - cube[i].rotation.y ) * 0.05;
renderer[i].render( scene[i], camera[i] );
}
}
實作範例 : http://excite.978.tw/html5/3d_cube.php
2011年4月27日 星期三
html5 - Javascript 3D Engine three.js 實作範例教學
three.js 一套 Javascript 3D Engine https://github.com/mrdoob/three.js/
實作將facebook的朋友個人照,在3D的空間裡漂浮
實作範例教學:
PHP & HTML部分
Javascript部分
實作 : http://excite.978.tw/html5/3d_space.php
實作將facebook的朋友個人照,在3D的空間裡漂浮
實作範例教學:
PHP & HTML部分
$facebook = new Facebook(array(
'appId' => $facebook_app_key,
'secret' => $facebook_app_secret,
'cookie' => true
));
if( !$facebook->getSession() ){
$auth_url = $facebook->getLoginUrl();
header('Location: '.$auth_url);
exit;
}else{
$fb_id = $facebook->getUser();
try{
$aFriendList = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select pic_square from user where uid in (select uid2 from friend where uid1 = '.$fb_id.') order by name limit 1000'
));
shuffle($aFriendList);
foreach( $aFriendList as $k => $v ){
if( $k > 100 ){
unset($aFriendList[$k]);
}
}
}catch(Exception $e){ $aFriendList = array(); }
}
<html>
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<!-- 載入 Three.js -->
<script type="text/javascript" src="three/build/Three.js"></script>
<style>
body{
background-color: #000000;
margin: 0px;
overflow: hidden;
}
ul { position:absolute;top:-1000;left:-1000} /* 把圖丟到可視範圍外 */
</style>
</head>
<body>
<ul>
<?php
foreach( $aFriendList as $k => $v ){
?>
<li><img class="img" src="img_proxy.php?i=<?php echo urlencode($v['pic_square']); ?>"></li>
<?php
}
?>
</ul>
Javascript部分
var container,camera, scene, renderer, particle;
var mouseX = 0, mouseY = 0;
var windowHalfX = ($(window).width()) / 2;
var windowHalfY = ($(window).height()) / 2;
var count = 0;
var total = ($('ul li').length) - 1;
var aImgData = new Array();
$(window).load(function() {
var gogo_count = 0;
$('.img').each(function(index,value){
aImgData[index] = new Image();
aImgData[index].src = value.src;
aImgData[index].onload = function(){
gogo_count++;
gogo(gogo_count);
}
});
});
function gogo(gogo_count){
if( gogo_count == $('.img').length ){
init();
animate();
}
}
function init(){
$('body').append(
$('<div id="main"/>')
);
container = $('#main').get(0);
camera = new THREE.Camera( 75, ($(window).width()) / ($(window).height()), 1, 3000 );
camera.position.z = 1000;
scene = new THREE.Scene();
var program = function ( context , color) {
var t1 = color.__styleString.split(/,/);
var t2 = t1[2].replace(')','');
if( aImgData[t2] != undefined ){
if( aImgData[t2].complete == true ){
context.save();
context.translate(12,12);
context.rotate(180 * Math.PI / 180)
context.drawImage(aImgData[t2],0,0,12,12);
context.restore();
context.rotate(180 * Math.PI / 180)
}
}
}
for ( var i = 0; i < total; i++ ) {
count = i;
particle = new THREE.Particle( new THREE.ParticleCanvasMaterial(
{ color: count, program: program }
)
);
particle.position.x = Math.random() * 2000 - 1000;
particle.position.y = Math.random() * 2000 - 1000;
particle.position.z = Math.random() * 2000 - 1000;
particle.scale.x = particle.scale.y = Math.random() * 10 + 5;
scene.addObject( particle );
}
renderer = new THREE.CanvasRenderer();
renderer.setSize( ($(window).width()), ($(window).height()) );
container.appendChild( renderer.domElement );
$('body').mousemove(function(e){
mouseX = e.pageX - windowHalfX;
mouseY = e.pageY - windowHalfY;
});
}
function animate() {
setTimeout( 'animate();', 1000 / 60 );
render();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
renderer.render( scene, camera );
}
實作 : http://excite.978.tw/html5/3d_space.php
2011年4月26日 星期二
html5實作使用opencv進行臉部辨識
使用 open cv javascript 版本 : http://github.com/liuliu/ccv
實作範例教學:
HTML部分:
實作範例教學:
HTML部分:
<canvas id="canvas"/>
<script type="text/javascript" src="ccv.js"></script>
<script type="text/javascript" src="face.js"></script>
javascript部分:
$('#canvas').attr({width:($(window).width())-400,height:$(window).height()});
function face(src){
$('#msg').html('請等待');
//圖片位置
var img_path = 'img_proxy.php?i='+encodeURIComponent(src);
var image = new Image();
image.src = img_path;
var canvas = $('#canvas').get(0);
var ctx = canvas.getContext("2d");
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, $(window).width(), $(window).height());
image.onload = function () {
/* call main detect_objects function */
var elapsed_time = (new Date()).getTime();
var comp = ccv.detect_objects({ "canvas" : ccv.grayscale(ccv.pre(image)),
"cascade" : cascade,
"interval" : 5,
"min_neighbors" : 1 });
ctx.drawImage(image, 0, 0);
ctx.lineWidth = 3;
ctx.strokeStyle = "#f00";
/* draw detected area */
for (var i = 0; i < comp.length; i++){
ctx.strokeRect(comp[i].x, comp[i].y, comp[i].width, comp[i].height);
}
$('#msg').html(' ');
}
}
實作結果: http://excite.978.tw/html5/opencv_js.php
2011年4月22日 星期五
html5實作套用box2d物理引擎效果
使用 https://github.com/jwagner/box2d2-js
實作範例教學:
Javascirpt canvas處理
加上box2d
實作範例教學:
Javascirpt canvas處理
//圖片位置
$('#imgPath').hide();
var img_path = $('#imgPath').attr('src');
//canvas dom
$('body').append(
$('<div id="main"/>').append(
$('<canvas id="canvas"/>').attr(
{width:$(window).width(),height:$(window).height()}
)
)
);
var tmpImg = new Array();
var tmpPosTop = new Array();
var tmpPosLeft = new Array();
var screenTop;
var screenLeft;
var pHeight;
var pWidth;
var imgTop;
var imgLeft;
//抓下圖片貼到canvas
var canvasDom = $('#canvas').get(0);
var ctx = canvasDom.getContext('2d');
ctx.fillStyle= 'FFFFFF';
var img = new Image();
img.src = img_path;
img.onload = function(){
var i = 0;
screenTop = Math.floor(($(window).height())/2) - this.height;
screenLeft = Math.floor(($(window).width())/2) - this.width;
pHeight = Math.floor(this.height/10);
pWidth = Math.floor(this.width/10);
imgTop = screenTop;
imgLeft = screenLeft;
ctx.drawImage(img,imgLeft,imgTop);
//把圖存到array裡
while( imgTop < this.height+screenTop && imgLeft < this.width+screenLeft ){
tmpImg[i] = ctx.getImageData(imgLeft,imgTop,pWidth,pHeight);
tmpPosTop[i] = imgTop;
tmpPosLeft[i] = imgLeft;
i++;
imgLeft += pWidth;
if( imgTop < this.height+screenTop && imgLeft >= this.width+screenLeft ){
imgLeft = screenLeft;
imgTop += pHeight;
}
}
init();
}
加上box2d
var c_width = Math.floor(($(window).width())/10);
var ppm = ($(window).width())/c_width;
var c_height = ($(window).height())/ppm;
var worldAABB = new b2AABB();
worldAABB.lowerBound.Set(-1000.0, -1000.0);
worldAABB.upperBound.Set(1000.0, 1000.0);
var world = new b2World(worldAABB, new b2Vec2(0.0, -9.8), true);
window.world = world;
var groundBodyDef = new b2BodyDef();
groundBodyDef.position.Set(c_width/2.0, 3.0);
var groundBody = world.CreateBody(groundBodyDef);
var groundShapeDef = new b2PolygonDef();
groundShapeDef.restitution = 0.0;
groundShapeDef.friction = 0.5;
groundShapeDef.density = 1.0;
groundBody.w = c_width*1.0
groundBody.h = 5.0
groundShapeDef.SetAsBox(groundBody.w, groundBody.h);
groundBody.CreateShape(groundShapeDef);
groundBody.SynchronizeShapes();
var bodies = [groundBody];
function init(){
ctx.setTransform(ppm, 0, 0, -ppm, 0, $(window).height());
for( i=0; i<tmpImg.length; i++ ){
var bodyDef = new b2BodyDef();
bodyDef.position.Set(tmpPosLeft[i]/ppm, c_height-(tmpPosTop[i]/ppm));
//bodyDef.position.Set(5, 5);
var body = world.CreateBody(bodyDef);
var shapeDef = new b2PolygonDef();
shapeDef.SetAsBox(1.0, 1.0);
body.w = pWidth/ppm;
body.h = pHeight/ppm;
shapeDef.restitution = 0.0;
shapeDef.density = 1.0;
shapeDef.friction = 0.9;
body.CreateShape(shapeDef);
body.SetMassFromShapes();
bodies.push(body);
}
}
var frame = 0;
window.setInterval(function() {
world.Step(1.0/60.0, 10);
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, $(window).width(), $(window).height());
for(var i = 0; i < bodies.length; i++){
var body = bodies[i];
var t = body.m_xf;
var posX = t.position.x;
var posY = t.position.y;
var angle = body.GetAngle();
//if(tmpImg[i] != undefined){
if(i>0){
var x = $(window).width()-($(window).width()-(posX*ppm));
var y = $(window).height()-(posY*ppm);
ctx.putImageData(tmpImg[(i-1)],x,y);
}else{
ctx.fillStyle = 'white';
ctx.translate(posX, posY)
ctx.rotate(angle);
ctx.fillRect(-body.w, -body.h, body.w*2, body.h*2);
ctx.rotate(-angle);
ctx.translate(-posX, -posY)
}
}
}, 1000/30);
實作範例 : http://excite.978.tw/html5/particle_box2d.php
2011年4月21日 星期四
html5實作碎圖效果加上滑鼠座標把碎圖做相對移動
加上滑鼠座標判斷,將破完的圖做相對的移動
實作範例教學:
實作: http://excite.978.tw/html5/particle_v2.php
實作範例教學:
var middleX = Math.floor(($(window).width())/2);
var middleY = Math.floor(($(window).height())/2);
var capX = Math.floor(($(window).width())/20);
var capY = Math.floor(($(window).height())/20);
$('body').mousemove(function(e){
if( doMove ){
for( j=0;j < tmpImg.length; j++ ) {
ctx.fillRect(tmpPosLeft[j],tmpPosTop[j],pWidth,pHeight);
var moveX = Math.floor((middleX-e.pageX)/capX);
var moveY = Math.floor((middleY-e.pageY)/capY);
if( Math.abs(tmpPosLeft[j]-middleX) < capX * 2 ){
moveX = moveX/2;
}
if( Math.abs(tmpPosTop[j]-middleY) < capY * 2 ){
moveY = moveY/2;
}
tmpPosLeft[j] = tmpPosLeft[j] + moveX;
tmpPosTop[j] = tmpPosTop[j] + moveY;
ctx.putImageData(tmpImg[j],tmpPosLeft[j],tmpPosTop[j]);
//console.log(moveX,moveY);
}
}
});
實作: http://excite.978.tw/html5/particle_v2.php
2011年4月20日 星期三
html5碎圖效果
實作範例教學:
HTML部分
參數宣告
canvas處理
實作範例: http://excite.978.tw/html5/particle.php
HTML部分
<html>
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
</head>
<body>
<img id="imgPath" src="img_proxy.php?i=http%3A%2F%2Fprofile.ak.fbcdn.net%2Fhprofile-ak-snc4%2F49062_1041673900_6306_n.jpg">
<script src="particle.js"></script>
</body>
</html>
JS部分
//圖片位置
$('#imgPath').hide();
var img_path = $('#imgPath').attr('src');
//canvas dom
$('body').append(
$('<div id="main"/>').append(
$('<canvas id="canvas"/>').attr(
{width:$(window).width(),height:$(window).height()}
)
)
);
參數宣告
var tmpImg = new Array();
var tmpPosTop = new Array();
var tmpPosLeft = new Array();
var aGoTop = new Array();
var aGoLeft = new Array();
var Flag = new Array();
var screenTop;
var screenLeft;
var pHeight;
var pWidth;
var imgTop;
var imgLeft;
var i = 0;
canvas處理
//抓下圖片貼到canvas
var canvasDom = $('#canvas').get(0);
var ctx = canvasDom.getContext('2d');
ctx.fillStyle= 'FFFFFF';
var img = new Image();
img.src = img_path;
img.onload = function(){
screenTop = Math.floor(($(window).height())/2) - this.height;
screenLeft = Math.floor(($(window).width())/2) - this.width;
pHeight = Math.floor(this.height/15);
pWidth = Math.floor(this.width/15);
imgTop = screenTop;
imgLeft = screenLeft;
ctx.drawImage(img,imgLeft,imgTop);
//把圖存到array裡
while( imgTop < this.height+screenTop && imgLeft < this.width+screenLeft ){
tmpImg[i] = ctx.getImageData(imgLeft,imgTop,pWidth,pHeight);
tmpPosTop[i] = imgTop;
tmpPosLeft[i] = imgLeft;
i++;
imgLeft += pWidth;
if( imgTop < this.height+screenTop && imgLeft >= this.width+screenLeft ){
imgLeft = 0;
imgTop += pHeight;
}
}
var pImg = new Array();
i = 0;
//計算要到達的目的座標
while(i < tmpImg.length){
if( pImg[i] != 1 ){
pImg[i] = 1;
var randLeft = Math.floor(Math.random()*(img.width));
var randTop = Math.floor(Math.random()*(img.height));
var randDir = Math.floor(Math.random()*10);
if( randDir % 4 == 1 ){
randLeft = randLeft * -1;
randTop = randTop * -1;
}else if(randDir % 4 == 2){
randTop = randTop * -1;
}else if(randDir % 4 == 3){
randLeft = randLeft * -1;
}
var goLeft = tmpPosLeft[i] + randLeft;
var goTop = tmpPosTop[i] + randTop;
if( goLeft < 0 ){
goLeft = 0;
}
if( goTop < 0 ){
goTop = 0;
}
if( goLeft >= $(window).width() ){
goLeft = $(window).width();
}
if( goTop >= $(window).height() ){
goTop = $(window).height();
}
aGoTop[i] = goTop;
aGoLeft[i] = goLeft;
i++;
}
}
i = 0;
while( i < tmpImg.length ){
//移動圖片區塊
Flag[i] = setInterval('moveParticle('+i+');',1);
i++;
}
}
移動圖塊var moveParticle = function (i){
if( Math.abs(tmpPosLeft[i] - aGoLeft[i]) < 5 || Math.abs(tmpPosTop[i] - aGoTop[i]) < 5 ){
clearInterval(Flag[i]);
}
ctx.fillRect(tmpPosLeft[i],tmpPosTop[i],pWidth,pHeight);
if( aGoLeft[i] > tmpPosLeft[i] ){
tmpPosLeft[i]++;
}else{
tmpPosLeft[i]--;
}
if( aGoTop[i] > tmpPosTop[i] ){
tmpPosTop[i]++;
}else{
tmpPosTop[i]--;
}
ctx.putImageData(tmpImg[i],tmpPosLeft[i],tmpPosTop[i]);
}
實作範例: http://excite.978.tw/html5/particle.php
2011年4月19日 星期二
2011年4月15日 星期五
mac上使用 open vpn 出現錯誤訊息 Cannot allocate TUN/TAP dev dynamically
64bit的macos使用open vpn 時會出現 Cannot allocate TUN/TAP dev dynamically 的錯誤訊息
Terminal下執行
# ls /dev/tap*
原來是沒有tap device
解法:
http://tuntaposx.sourceforge.net/download.xhtml
安裝這一個open source 即可
Terminal下執行
# ls /dev/tap*
原來是沒有tap device
解法:
http://tuntaposx.sourceforge.net/download.xhtml
安裝這一個open source 即可
2011年4月14日 星期四
facebook製作分享按鈕或是按讚按鈕(like button)測試網址
製作facebook分享按鈕或是按讚的like button時,常常都需要按下去後才會知道分享出去的結果
如果meta tag有下錯,分享出去的圖示或是文字就會跟想像中的不一樣
facebook有提供一個線上的debug tool URL Linter
http://developers.facebook.com/tools/lint/
可以節省很多測試的時間
如果meta tag有下錯,分享出去的圖示或是文字就會跟想像中的不一樣
facebook有提供一個線上的debug tool URL Linter
http://developers.facebook.com/tools/lint/
可以節省很多測試的時間
html5實作蒙太奇(montage)效果
html5有canvas標籤可以繪圖
於是試著把facebook上朋友的照片取下來後組合成蒙太奇效果個人圖
實作範例教學:
Part I. php code 取得facebook權限並抓取朋友的個人照
Part II. HTML部份
CSS
BODY
Part III. Javascript部分
結果圖:
範例結果: http://excite.978.tw/html5/montage.php
於是試著把facebook上朋友的照片取下來後組合成蒙太奇效果個人圖
實作範例教學:
Part I. php code 取得facebook權限並抓取朋友的個人照
$facebook = new Facebook(array(
'appId' => $facebook_app_key,
'secret' => $facebook_app_secret,
'cookie' => true
));
if( !$facebook->getSession() ){
$auth_url = $facebook->getLoginUrl();
header('Location: '.$auth_url);
exit;
}else{
$fb_id = $facebook->getUser();
try{
$aUserData = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select pic_square from user where uid='.$fb_id
));
$UserImg = $aUserData[0]['pic_square'];
}catch(Exception $e){ }
try{ //抓取朋友的圖片
$aFriend = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select uid,pic_square from user where uid in (select uid1 from friend where uid2 = '.$fb_id.') limit 360',
));
shuffle($aFriend);
}catch(Exception $e){ }
}
Part II. HTML部份
CSS
<style>
#friend ul li {list-style-type:none;}
#friend .friendimg{position:absolute;width:10px;top:-1000px;}
#me {position:absolute;top:0px;left:0px;z-index:1;}
#me ul li {list-style-type:none;}
#me .meimg {width:600px;height:600px;position:absolute;top:-1000px;}
#msg {color:#0000FF;}
</style>
BODY
<p>如圖片顯示不正常,重新整理一次即可</p>
<p><span id="msg">正在抓取朋友個人照...請等待</span></p>
<canvas id="img_canvas" width="600" height="600"></canvas><!-- 顯示結果的canvas -->
<canvas id="canvas_me" width="600" height="600"></canvas><!-- 半透明個人用 -->
<div id="me"> <!-- 自己的圖片 -->
<ul>
<li><img class="meimg" src="<?php echo htmlspecialchars($UserImg); ?>"></li>
</ul>
</div>
<div id="friend"> <!-- 朋友的圖片 -->
<ul>
<?php foreach( $aFriend as $k => $v ){
echo '<li><img class="friendimg" src="'.htmlspecialchars($v['pic_square']).'"></li>'."\n";
}
?>
</ul>
</div>
Part III. Javascript部分
$(window).load(function() { //全部的圖載完才開始跑
var canvas = $("#img_canvas").get(0);
if( typeof canvas.getContext == 'undefined' ){
$('#msg').html('組圖失敗,原因:瀏覽器不支援HTML5');
return;
}
//將朋友圖加到canvas裡
var ctx = canvas.getContext("2d");
var img_top = 0;
var img_left = 0;
var total = 3600;
var max = $('#friend .friendimg').length;
var i=0;
while( i<total ){
var seed = Math.floor(Math.random()*max);
var img = new Image();
var img_tmp = $('#friend .friendimg');
var img_tmp_dom = img_tmp[seed];
img.src = img_tmp_dom.src;
if( img.src.length > 3 && img_tmp_dom.complete == true){
ctx.drawImage(img, img_top,img_left,10,10);
img_left += 10;
if( img_left >= 600 ){
img_left = 0;
img_top += 10;
}
i++;
}
}
//取出自己的圖半透明後再疊到之前做好的朋友組圖上
var me_img_src = $('#me .meimg').attr('src');
var img_me = new Image();
img_me.src = me_img_src;
var canvasme = document.getElementById("canvas_me");
var ctx_me = canvasme.getContext("2d");
ctx_me.globalAlpha = 0.75;
ctx_me.drawImage(img_me, 0, 0,600,600);
ctx.drawImage(canvasme, 0,0,600,600);
canvasme.style.display = 'none';
$('#msg').html('');
});
結果圖:
範例結果: http://excite.978.tw/html5/montage.php
2011年4月12日 星期二
在網站上放置 facebook like button
參考 : http://developers.facebook.com/docs/reference/plugins/like/
在<header>裡放入meta tag給facebook讀取
在頁面想要的地方放入 like button 的 iframe
在<header>裡放入meta tag給facebook讀取
<meta property="og:title" content="標題">
<meta property="og:type" content="website">
<meta property="og:url" content="網址">
<meta property="og:image" content="圖片">
<meta property="og:site_name" content="網站名稱">
<meta property="og:description" content="內容文字敘述">
在頁面想要的地方放入 like button 的 iframe
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Ftw.yahoo.com&layout=standard&show_faces=true&width=450&action=like&font&colorscheme=light&height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>
Firefox記憶體設定
參考 : http://forum.moztw.org/viewtopic.php?f=2&t=11431&view=previous
限制一下Firefox記憶體使用量
步驟
1. about:config
2. browser.sessionhistory.max_total_viewers 30 //30個頁面會cache
3. browser.cache.memory.capacity 20480 //記憶體限制
限制一下Firefox記憶體使用量
步驟
1. about:config
2. browser.sessionhistory.max_total_viewers 30 //30個頁面會cache
3. browser.cache.memory.capacity 20480 //記憶體限制
2011年4月6日 星期三
iphone safari 多點觸控實作
參考一
http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safariwebcontent/HandlingEvents/HandlingEvents.html
參考二
http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html#//apple_ref/doc/uid/TP40008193-SW1
來製作一個二指劃開後圖片隨二指距離而變化
製作多點觸控,為避免瀏覽器的zoom in zoom out干擾所以要先將zoom的功能關閉
實作範例教學:
圖片替換用的 div
加上感應觸控的 div
css
javascript
結果展示:http://excite.978.tw/iphone/mtouch.php
(要用iphone的Safari開啟)
然後二指左右劃開就可以看到效果
http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safariwebcontent/HandlingEvents/HandlingEvents.html
參考二
http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html#//apple_ref/doc/uid/TP40008193-SW1
來製作一個二指劃開後圖片隨二指距離而變化
製作多點觸控,為避免瀏覽器的zoom in zoom out干擾所以要先將zoom的功能關閉
實作範例教學:
<meta name="viewport" content="width=device-width,height=420, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=0"/>
圖片替換用的 div
<div id="img"><img src="1.png" width="320"></div>
加上感應觸控的 div
<div id="touch" ontouchstart="touchStart(event);" ontouchmove="touchMove(event);" ontouchend="touchEnd(event);" ontouchcancel="touchCancel(event);"></div>
css
html body{
overflow: hidden;
}
#touch{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-color:#AAAAAA;
opacity: 0;
}
#img{
position:absolute;
top:0;
left:0;
}
javascript
//預先載入五張圖片
var img1 = new Image(); img1.src = '1.png';
var img2 = new Image(); img2.src = '2.png';
var img3 = new Image(); img3.src = '3.png';
var img4 = new Image(); img4.src = '4.png';
var img5 = new Image(); img5.src = '5.png';
var x_percent = 1; //二點距離指數
//加入觸控event
element.addEventListener("touchstart", touchStart, false);
element.addEventListener("touchmove", touchMove, false);
element.addEventListener("touchend", touchEnd, false);
element.addEventListener("touchcancel", touchCancel, false);
function touchStart(event){
//event 開時換第一張圖
x_percent = 1;
changeImg(x_percent);
}
function touchMove(event){
//依二指距離替換五張圖
var x1 = event.touches[0].pageX;
var y1 = event.touches[0].pageY;
var x2 = event.touches[1].pageX;
var y2 = event.touches[1].pageY;
var x_diff = Math.abs(x1-x2);
x_percent = Math.ceil((x_diff/32)/2);
changeImg(x_percent);
}
function touchEnd(event){
//結束換回第一張圖
x_percent = 1;
changeImg(x_percent);
}
function touchCancel(event){
//取消也是換回第一張圖
x_percent = 1;
changeImg(x_percent);
}
function changeImg(screen){
if(screen > 5){
screen = 5;
}
if(screen < 1){
screen = 1;
}
document.getElementById("img").innerHTML = '<img src="'+screen+'.png" width="320">';
}
結果展示:http://excite.978.tw/iphone/mtouch.php
(要用iphone的Safari開啟)
然後二指左右劃開就可以看到效果
facebook check in API (graph) 實作範例教學
facebook在台灣開放打卡後,graph裡的checkin API可以來玩玩
搭配手機定位來做應用 (手機瀏覽器取得geolocation)
以下為使用facebook php SDK 的實作範例教學
搭配手機定位來做應用 (手機瀏覽器取得geolocation)
以下為使用facebook php SDK 的實作範例教學
include('inc/facebook.php');
$facebook = new Facebook(
array(
'appId' => $facebook_app_key,
'secret' => $facebook_app_secret,
'cookie' => true,
)
);
$lat = filter_input(INPUT_GET, 'lat', FILTER_VALIDATE_FLOAT);
$long = filter_input(INPUT_GET, 'long', FILTER_VALIDATE_FLOAT);
$fb_id = $facebook->getUser();
//檢查登入
if( !$fb_id ){
echo 'Please login facebook.'; exit;
}
//檢查經緯度
if( !$lat || !$long ){
echo 'latitude or longitude is null'; exit;
}
//search place
try{
$place = $facebook->api('/search?type=place¢er='.$lat.','.$long.'&distance=1000');
}catch(Exception $e){ var_dump($e); }
//checkin
try{
$checkin_res = $facebook->api('/me/checkins'
,'post'
,array(
'message' => '手機綁app來check in,除了阿賢其他人都可以被tag'
,'coordinates' => '{"latitude":"'.$lat.'", "longitude": "'.$long.'"}'
,'place' => $place['data'][0]['id']
,'application' => '{"name":"bruce test","id":"'.$facebook_app_id.'"}'
,'tags' => '朋友id1,朋友id2,朋友id3,朋友id4,朋友id5'
)
);
echo 'check in success.';
}catch(Exception $e){ var_dump($e); }
vim 去除多餘的空白
複製貼上程式碼時,尤其由ssh client複製時會有多餘的空白在每一行後面
這時用vim可簡單快速將空白移除
1. 按 : 進入命令模式
2. 在命令模式裡輸入 % s/\ *$//g
3. 按下enter
這時用vim可簡單快速將空白移除
1. 按 : 進入命令模式
2. 在命令模式裡輸入 % s/\ *$//g
3. 按下enter
手機瀏覽器取得geolocation
多數智慧手機都有gps,內建的瀏覽器也大多支援html5 navigator.geolocation
以下為簡單的javascript code來取得手機裝置目前的經緯度
實作範例教學:
以下為簡單的javascript code來取得手機裝置目前的經緯度
實作範例教學:
if( navigator.geolocation == undefined ){
alert('裝置不支援');
}else{
navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{maximumAge:60});
}
function successCallback(position) {
lat = position.coords.latitude;
long = position.coords.longitude;
alert('lat:'+lat+' long:'+long);
}
function errorCallback(error) {
alert('無法取得位置');
}
facebook php sdk "SSL certificate problem" 解法
使用 facebook php sdk時
有些機器會出現
SSL certificate problem 的錯誤訊息
只要加上以下二行即可
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYHOST] = 2;
範例:
有些機器會出現
SSL certificate problem 的錯誤訊息
只要加上以下二行即可
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYHOST] = 2;
範例:
include('inc/facebook.php');
$facebook = new Facebook(
array(
'appId' => $facebook_app_key,
'secret' => $facebook_app_secret,
'cookie' => true,
)
);
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYHOST] = 2;
2011年4月1日 星期五
手機瀏覽器上使用facebook登入與請求權限
手機瀏覽器畫面大小與一般螢幕不同
只要在login上傳入 display=touch 就可以換成手機版的頁面
display=wap 也可以,以下的code專給大螢幕的手機使用,像iphone
實作範例教學:
只要在login上傳入 display=touch 就可以換成手機版的頁面
display=wap 也可以,以下的code專給大螢幕的手機使用,像iphone
實作範例教學:
include('inc/facebook.php');
$facebook = new Facebook(
array(
'appId' => $facebook_app_key, //appid
'secret' => $facebook_app_secret, //appsecret
'cookie' => true,
)
);
$aLoginParam = array(
'display' => 'touch' //手機模式畫面
,'req_perms' => 'user_checkins' //打卡權限
,'cancel_url' => 'http://'.$server.'/facebook/index.php'
);
if( $session = $facebook->getSession() ){
$fb_id = $facebook->getUser();
//檢查權限
try{
$perm = $facebook->api(array(
'method' => 'fql.query',
'query' => 'select user_checkins from permissions where uid='.$fb_id
));
if( $perm[0]['user_checkins'] != '1' ){ //有權限
$url = $facebook->getLoginUrl($aLoginParam);
header('Location: '.$url); exit;
}
}catch (Exception $e) { }
}else{
$url = $facebook->getLoginUrl($aLoginParam);
header('Location: '.$url); exit;
}
2011年3月30日 星期三
ios開發經驗談 (一)
發開ios的application需要申請apple 的ios developer program
才能將開發的app放到iphone或ipad上測試 (當然可以採用jb方式)
我在申請ios developer program發生了一些滿機車的事情
打了很多電話,寫了很多Email後權限才被開啟
ios developer program申請流程大致如下:
1. 填寫資料
2. 刷卡付保護費
3. 點選認證Email
重點來了
填寫資料的英文名
刷卡信用卡上的英文名
必須一樣
如果不一樣就會Email認證失敗
然後就會跟我一樣打很多電話寫很多Email後帳號才會開通
才能將開發的app放到iphone或ipad上測試 (當然可以採用jb方式)
我在申請ios developer program發生了一些滿機車的事情
打了很多電話,寫了很多Email後權限才被開啟
ios developer program申請流程大致如下:
1. 填寫資料
2. 刷卡付保護費
3. 點選認證Email
重點來了
填寫資料的英文名
刷卡信用卡上的英文名
必須一樣
如果不一樣就會Email認證失敗
然後就會跟我一樣打很多電話寫很多Email後帳號才會開通
Firefox 4 歷史紀錄保留天數設定
Firefox4 沒有歷史紀錄的設定頁面
需透過 about:conifg 設定
browser.history_expire_days 保留幾天
browser.history_expire_days_min 最少留幾天
browser.history_expire_days.mirror coding用?
我的設定保留 90天
browser.history_expire_days 90
browser.history_expire_days_min 90
browser.history_expire_days.mirror 90
參考文章: http://www.jenssegers.be/blog/20/Firefox-4-history-setting-browser.history_expire_days
需透過 about:conifg 設定
browser.history_expire_days 保留幾天
browser.history_expire_days_min 最少留幾天
browser.history_expire_days.mirror coding用?
我的設定保留 90天
browser.history_expire_days 90
browser.history_expire_days_min 90
browser.history_expire_days.mirror 90
參考文章: http://www.jenssegers.be/blog/20/Firefox-4-history-setting-browser.history_expire_days
2011年3月29日 星期二
mac git client
http://code.google.com/p/git-osx-installer/
下載安裝後
$ git: Command not found
我的mac之前改用csh
$ vim ~/.cshrc
set path = ($path /usr/local/git/bin)
使用bash 的
$ vim ~/.profile
PATH="/usr/local/git/bin:$PATH"
下載安裝後
$ git: Command not found
我的mac之前改用csh
$ vim ~/.cshrc
set path = ($path /usr/local/git/bin)
使用bash 的
$ vim ~/.profile
PATH="/usr/local/git/bin:$PATH"
Special device UUID= does not exist
ubuntu將分隔區重新format後uuid會變
如果 /etc/fstab 裡面沒有修改
重開機會卡在開機畫面,要按 S 去 skip mount的動作
好家在有console server...不然為了這個 "S" 得跑機房真的會幹死...
如何找 uuid
$ ls -la /dev/disk/by-uuid
然後修改 /etc/fstab
$ sudo mount /srv/cache1 ; sudo mount /srv/cache2
如果 /etc/fstab 裡面沒有修改
重開機會卡在開機畫面,要按 S 去 skip mount的動作
好家在有console server...不然為了這個 "S" 得跑機房真的會幹死...
如何找 uuid
$ ls -la /dev/disk/by-uuid
然後修改 /etc/fstab
$ sudo mount /srv/cache1 ; sudo mount /srv/cache2
2011年3月25日 星期五
mac ramdisk作法
參考 http://blog.markseinn.idv.tw/?p=504
AppleScript
-----
do shell script "
if ! test -e /Volumes/RamDisk ; then
diskutil erasevolume HFS+ RamDisk `hdiutil attach -nomount ram://$((3*1024*1024*2))`
fi
"
-----
AppleScript
-----
do shell script "
if ! test -e /Volumes/RamDisk ; then
diskutil erasevolume HFS+ RamDisk `hdiutil attach -nomount ram://$((3*1024*1024*2))`
fi
"
-----
Firefox ramdisk
中午跟Jon吃飯時,聊到Firefox用ramdisk當cache
Firefox 加速使用 RamDisk(Windows, Linux)
找了半天沒發現mac上免費又好用的ramdisk軟體或作法
不過Jon的文章裡已經有提到把cache放到ram裡 (如圖)
於是我對我的FireFox做了設定
1. 網址列打上 about:config
2. 搜尋 browser.cache
3. browser.cache.disk.capacity: 0
4. browser.cache.disk.enable: false
5. browser.cache.memory.capacity: 50000
6. browser.cache.memory.enable: true
Firefox 加速使用 RamDisk(Windows, Linux)
找了半天沒發現mac上免費又好用的ramdisk軟體或作法
不過Jon的文章裡已經有提到把cache放到ram裡 (如圖)
於是我對我的FireFox做了設定
1. 網址列打上 about:config
2. 搜尋 browser.cache
3. browser.cache.disk.capacity: 0
4. browser.cache.disk.enable: false
5. browser.cache.memory.capacity: 50000
6. browser.cache.memory.enable: true
訂閱:
文章 (Atom)