分類
Javascript

線上幸運抽獎-手機版

之前一直要找時間做一個手機用的版本, 終於昨天花點時間寫好了, 有需要的朋友們歡迎多加利用, 網址如下:

http://sample.diary.tw/lucky-draw/m

功能與原來的版本相同, 只是介面用了 jQuery mobile 的方式呈現, 分別將說明、名單、獎項與抽獎放在4個分開的介面上, 利用下方的切換功能來進行切換, 一樣可以隨時加碼. 抽獎結果的部分, 考慮手機介面較小, 所以最後抽出的放在最上面, 而且上方會出現目前待抽的獎項與剩餘人數, 剩餘獎項與已得獎組數等資訊.

最後還是希望大家能多多利用, 也提供建議, 謝謝.

原來的電腦版介紹: https://diary.tw/archives/1187

分類
Javascript

將瀏覽器進入全螢幕的方法(requestFullscreen)

有時在一些網站看到可以將特定的內容進行全螢幕的檢視, 早期僅有 video 可以有這樣的功能, 現在也可以透過瀏覽器擴充方法來進行特定內容的全螢幕檢視.

程式碼如下:

function launchFullscreen(element) {
    if (element.requestFullscreen) {
        element.requestFullscreen();
    } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
    } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFullscreen();
    } else if (element.msRequestFullscreen) {
        element.msRequestFullscreen();
    }
}

function exitFullscreen() {
    if (document.exitFullscreen) {
        document.exitFullscreen();
    } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
    } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    }
}

其中 launchFullscreen 傳入指定的容器物件, 如 div 就可以利用擴充方法 requestFullscreen 來進行全螢幕檢視, 而 exitFullscreen 則不用傳入物件, 使用 document 的擴充方法 exitFullscreen 即可離開全螢幕檢視.

範例:
http://sample.diary.tw/40/index.htm

參考資料:
http://xuhong.github.io/2014/05/23/fullscreen/
https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/device/fullscreen-api/

[2020/09/02 17:41]

由於 requestFullscreen() 是只針對特定 element , 所以在轉換網址時, 會恢復沒有全螢幕的狀況, 若是希望能持續有全螢幕效果, 可以使用 iframe 方式進行, 可以參考範例: https://codepen.io/timhuang/pen/KKzXWKa

分類
Javascript

雙北Youbike租借站即時資訊地圖

因為介紹 open data 與 google maps javascript sdk 的使用與實作 , 利用了台北市的 open data 與 新北市 的 open data 來進行雙北 Youbike 租借站即時資訊.

台北市的 Youbike 資料:
http://data.taipei/opendata/datalist/datasetMeta?oid=8ef1626a-892a-4218-8344-f7ac46e1aa48

新北市的 Youbike 資料:
http://data.ntpc.gov.tw/od/detail?oid=71CD1490-A2DF-4198-BEF1-318479775E8A

資料來源分別為(JSON type):
http://data.taipei/youbike
http://data.ntpc.gov.tw/od/data/api/54DDDC93-589C-4858-9C95-18B2046CC1FC?$format=json

其中台北市的資料 SERVER還有支援 CORS .

接下來就利用這些資料與 Google Maps Javascript SDK 來實作這個地圖了. 資料欄位都很容易理解, 其中使用不同顏色來表示租借站的狀態, 區分為可借可還 / 可借不可還 / 不可借可還 / 暫無營運, 而為能更容易借還, 目前可借為超過 2台, 可還也以超過 2個空位為基礎, 實際數字可點擊站點得知.

可以參考看看:
http://sample.diary.tw/youbike/

[2020/12/13 13:44]

由於原本的 data source 有問題, 已無法正常取得內容, 查找一下更新後的 data source, 調整如下:

台北市的由: http://data.taipei/youbike 改為 https://tcgbusfs.blob.core.windows.net/blobyoubike/YouBikeTP.gz , 而新北市的由: http://data.ntpc.gov.tw/od/data/api/54DDDC93-589C-4858-9C95-18B2046CC1FC?$format=json 改為 https://data.ntpc.gov.tw/api/datasets/71CD1490-A2DF-4198-BEF1-318479775E8A/json/?size=10000

調整 data source 後, 原範例頁的資料就能正常呈現囉:

https://sample.diary.tw/youbike/

分類
Javascript

實做使用Google Maps API進行指定位置是否在指定區域內

有個需求是要檢查某地址是否在某特定區域內, 於是思考使用 Google Maps API 來實做, 判斷的部分可以不需要 Google Maps 顯示, 但在測試或開發時, 若有可視的地圖會比較容易理解狀況, 也比較明白指定區域與指定位置的關係, 以下分為幾個部分來進行.

首先需要能繪製指定區域, 這個和程式沒有直接關係, 但透過 Google 的 MyMaps 比較好進行:

http://mymaps.google.com/

進入後, 建立新地圖, 出現 Google Maps 之後, 使用”畫一條線”的”新增內容或形狀”工具來進行區域的繪製:

一點一點地把區域點好後, 點回起點, 就可以產生一個封閉區域了, 再給予命名, 如以下範例:

這個部分可以隨時再進行區域的調整, 到自己滿意為止, 之後我們需要的其實是這個區域的多邊形座標點, 如何取得呢? 點擊新增圖層邊的三個點, 出現選單後, 選匯出成 KML:

就可以取得對應的 KML 檔案了, 打開 KML 檔中, 最重要的是找到座標點, 內容會是這樣的文字:
<coordinates>121.5437222,25.0416515,0.0 …… </coordinates>
這些座標點就是用來做這個指定區域的座標位置了, 接下來才真正要準備實作程式.

寫了一個小程式, 把這些座標點輸出成一串之後 Google Maps API Geometry 會用到的格式:

http://sample.diary.tw/36/tools.htm

我們將上面的 <coordinates> 中的字串, 填入上面小程式的 textarea 之後, 按下”產生區域多邊形座標”, 就可以得到像是這樣的內容:

{lat: 25.0416515, lng:121.5437222},
{lat: 25.0333111, lng:121.543529},
.....

先準備好到這裡, 之後參考這個部分可以進行多邊形繪製:

https://developers.google.com/maps/documentation/javascript/examples/polygon-simple

可以看到其中會需要的陣列就由上面小程式產生的內容填入即可, 記得, 在參考 google maps 的範例程式時, 在 initMap 中, 有個 center 參數和 zoom 參數, 要填入實際上你地圖的位置附近, 不然不會出現在地圖上, 如 google maps 範例內, 是百幕達三角洲地帶, 而且 zoom 是 5, 若是以台北市來看, 大約 zomm 是在 15或16 左右.

如範例: http://sample.diary.tw/36/map1.htm

主要程式碼為:

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: 25.037828, lng: 121.547204},
  zoom: 16,
});

var testAreaCoords = [
    {lat: 25.0416515, lng:121.5437222},
    {lat: 25.0333111, lng:121.543529},
    {lat: 25.033116700000004, lng:121.5526271},
    {lat: 25.036052399999996, lng:121.55267000000002},
    {lat: 25.0374716, lng:121.55146840000002},
    {lat: 25.038016, lng:121.5513396},
    {lat: 25.0415348, lng:121.5474987},
    {lat: 25.0416515, lng:121.5437222}, 
];

testArea = new google.maps.Polygon({
    paths: testAreaCoords,
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: '#FF0000',
    fillOpacity: 0.05
    
});
testArea.setMap(map);

接下來就是由指定的地址查找座標, 這個部分會用到 Google Maps API 中的 geocoder, 只需要將地址傳入, 就可以取得對應的座標了, 參考資料:

https://developers.google.com/maps/documentation/javascript/geocoding#GeocodingStatusCodes

程式碼不多, 參考範例:

http://sample.diary.tw/36/map2.htm

輸入地址就可以取得座標(經緯度)

主要程式碼如下(注意, geocoder 是用 callback 方式回傳):

function initMap() {
    geocoder = new google.maps.Geocoder();
}

function codeAddress() {
    var address = document.getElementById("address").value;
    geocoder.geocode({
        'address': address
    }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            alert("lat=" + results[0].geometry.location.lat() + ",lng=" + results[0].geometry.location.lng());
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    });
}

最後就是利用一個很重要的判斷式來判斷某地址(已取得座標)是否在指定區域內, containsLocation() 參考:

https://developers.google.com/maps/documentation/javascript/examples/poly-containsLocation

上面的範例是用點擊地圖的方式, 看點擊的位置是否在百幕達三角洲內, 是的話就是紅色 marker, 不是的話, 就用綠色 marker.

來改寫一下程式碼, 就可以達成判斷指定的地址是否在指定的區域內了, 如範例:

http://sample.diary.tw/36/map3.htm

主要程式碼:

// check if position in polygon
if(google.maps.geometry.poly.containsLocation(results[0].geometry.location, testArea)){
    alert("在指定區域內");
}else{
    alert("不在指定區域內");
}

總結一下:

  1. 先製作指定區域座標陣列(多邊形用)
  2. 使用 geocoder 取得指定的地址轉換為座標
  3. 使用 google.maps.geometry.poly.containsLocation 來判斷2.是否在1.裡面

PS. 記得要先到 https://console.developers.google.com/ 建立一個可以使用 Google Maps API 的應用程式, 並建立對應的 browser key 放到上面的程式碼中, 以順利執行你的 web 應用程式.

分類
Javascript

像Firebase的雲端即時資料庫-deployd

之前對於 Firebase 的時互動性有很強烈的應用想法, 主要是像類似線上聊天室的應用需求, 可以透過線上指令直接做控制客戶端的介面與功能操作, 接下來就想找一些類似的平台來做這件事.

其實背後應該都是走 socket.io 才能有這麼好的即時性與效果, 再加上同步性的資料庫, 哪個是最方便適合的呢? 有一些討論在這裡:

https://www.quora.com/Whats-the-closest-open-source-alternative-to-Firebase

接下來來看看這個好用的 deployd 服務, 他組合了 node.js / socket.io / mongodb 服務, 將這樣一個像 Firebase 的功能實作出來了, 並且也有很強大的管理介面功應用, 把資料庫操作, 即時性, 資料驗證與事件整理的十分簡捷方便, 要快速的建立出一組即時同步資料庫, 似乎就是這些最快了, 來看看他的影片介紹, 相信很快就能上手:

https://www.youtube.com/watch?v=I_Jq1BVj6D0

(影片引用自: https://www.youtube.com/watch?v=I_Jq1BVj6D0)

另外, 下面還有許多案例可供參考應用, 即時互動功能, 隨時建立, 隨時開發, 十分方便.

http://docs.deployd.com/examples/

以下為建立測試環境的方式:

  1. windows, 直接下載安裝包: https://bintray.com/artifact/download/deployd/dpd-win-installer/deployd-win-0.8.0.exe
  2. mac / 其他 linux 環境: https://github.com/deployd/deployd#install-from-npm 從 npm 開始

下面將要說明一個從頭開始的方式:

1. 準備一台主機, 這裡以 CentOS 為例, 可以利用 digital ocean 建立一台主機, 若還沒有帳號, 可以從這裡取得: https://diary.tw/archives/1434

2. 建立完成後, 開始安裝 nodejs 與 npm, 指令如下: (其中 epel-release 是為了安裝 nodejs的前置作業, 將 epel-release 資料庫安裝進來)

yum install epel-release
yum install nodejs
yum install npm

3. 接下來安裝 mongodb-server :

yum install mongodb-server

4. 最後安裝 deployd (使用 npm 安裝即可)

npm install deployd -g

5. 起動 mongodb-server

service mongod start

若希望之後重新開機也可以啟動, 可以再下:

chkconfig mongod on

接下來建立一個 deployd 應用程式專案,

cd /home
mkdir dev
cd dev
dpd create hello
cd hello
dpd

就建立完成一個空的專案了, 訪問: http://[ip]:2403/dashboard 即可順利看到已啟動的專案.

分類
Javascript

querySelector – Javascript的查詢選擇器

在有 jQuery 環境下, 操作選擇器很直覺, 不過沒有 jQuery 時, 如何進行相關的作業呢? 以下幾組為可能會用到的指令:

  1. document.getElementById 指定 id 來取得該物件 (唯一)
  2. document.getElementsByTagName 指定 html tag 來取得該物件陣列 (通常為多個)
  3. document.getElementsByClassName 指定 class name (可多組 class name 一起) 來取得該物件陣列 (通常為多個)
  4. document.querySelector 使用 css selector 來取得該物件 (注意, 僅傳回符合條件的第一筆)
  5. document.querySelectorAll 使用 css selector 來取得該物件陣列 (符合條件的多筆)

當物件被選擇出來後, 就可以進行操作了, 操作的方式可以再參考這裡:

http://www.w3schools.com/jsref/dom_obj_all.asp

在沒有 jQuery 的狀況下, 也能順利選擇物件, 並進行操作了.

分類
Javascript

有趣的trackingjs javascript framework

這個利用 javascript 寫的 tracking js 用來做許多視訊與圖形辨識上的應用, 官方介紹在這裡:

http://trackingjs.com/

來看看他的應用有哪些:

  1. 相片裡的人臉辨識 http://trackingjs.com/examples/face_tag_friends.html 像 facebook 裡的標記朋友那樣的功能.
  2. 人臉的眼、口辨識: http://trackingjs.com/examples/face_hello_world.html
  3. 動態的人臉追蹤, 這是從 webcam 動態追蹤人臉: http://trackingjs.com/examples/face_camera.html
  4. 相片的顏色辨識: http://trackingjs.com/examples/color_hello_world.html
  5. 從 webcam 的影像做顏色辨識: http://trackingjs.com/examples/color_camera.html
  6. 從 video 中的影像做顏色辨識: http://trackingjs.com/examples/color_video.html

還有很多其他型式的應用, 簡單來說, 這個 framework 把原本是在應用程式中才能做的特殊影像辨識技術應用在 browser 裡的 javascript 來達來, 目前比較會有問題的是在效率的問題, 不過若是未來 browser 強化與隨著 cpu 等級提升, 相對這些也就都不會是問題了.

快來玩看看吧.

分類
Javascript

CSS寬度問題

今天在修正一個瀏覽器相容性問題時, 在使用 css 中的 calc(100%- 10px) 這樣的語法時, 由於 ie8 不支援, 所以改用 jQuery 的 obj.parent().width() 來進行設置.

測試後發現有一點落差, 起用 browser 的 box model 來檢查, 發現其中 parent 有設定左右的 padding, 導致 parent width 和原來的 css calc(100% -10px) 的 100% 會有落差, 所以查了一下 jQuery 語法, 使用 obj.parent().outerWidth() 就能順利取得和原來 css calc(100% -10px) 的 100% 寬度相同了.

如此一來就解決了在 ie8 下寬度使用 calc(100% -10px) 語法的問題.

分類
Javascript

可愛的ClockPicker-用時鐘方式來選取時間

這個專案組件很可愛, 是一個時間選取器, 呈現的介面就是一個時鐘, 操作起來還蠻方便的, 另外也在手機上測試操作看看, 也是一樣方便順手, 蠻有意思的.

有需要使用到 timepicker 的場合, 可以試看看這組 clockpicker , 很不錯.

有 bootstrap版本: http://weareoutman.github.io/clockpicker/
還有 jQuery 版本: http://weareoutman.github.io/clockpicker/jquery.html

分類
Javascript

[json]如何讀取含有減號的json key

剛在撰寫程式碼時, 發現要取回 aws cloudsearch 中的搜尋使用時間, 其傳回的 json 參數中, 使用了減號, 該鍵值為 time-ms , 其實很直覺地要使用, 但又覺得怪怪的, 一執行馬上就有問題.

因為原來的 jsonObj.time-ms 會被視為 jsonObj.time – ms , 所以必須調整寫法, 正確寫法如下:

jsonObj["time-ms"]

這樣就可以了, 當然, 該回應的 json 中, 該鍵值(key)也必須是使用引號包起來的, 否則該 json 物件也會有問題.

測試程式碼如下:

var a = { 
  "mykey": "value1", 
  "my-key": "value2",
}
alert(a["my-key"]);

會回應 value2 這樣就對了.

參考資料:
http://stackoverflow.com/questions/13869627/unable-to-access-json-property-with-dash