js實現的手機介面拼圖解鎖效果
本章節分享一段程式碼例項,它模擬實現了一個常見的功能。
那就是使用滑動方式拼圖解鎖,程式碼例項如下:
[HTML] 純文字檢視 複製程式碼<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> </head> <body> <script> var CANVAS_WIDTH = 310; var CANVAS_HEIGHT = 520; var OUTER_RADIUS = 35; var INNER_RADIUS = 10; var OUTER_STROKE_COLOR_NORMAL = "rgba(63, 164, 223, 0.7)"; var OUTER_FILL_COLOR_NORMAL = "rgba(94, 211, 229, 0.7)"; var INNER_STROKE_COLOR_NORMAL = "rgba(84, 169, 228, 0.7)"; var INNER_FILL_COLOR_NORMAL = "rgba(71, 167, 215, 0.7)"; var OUTER_STROKE_COLOR_TOUCH = "rgba(109, 222, 92, 0.7)"; var OUTER_FILL_COLOR_TOUCH = "rgba(172, 236, 162, 0.7)"; var INNER_STROKE_COLOR_TOUCH = "rgba(83, 209, 102, 0.7)"; var INNER_FILL_COLOR_TOUCH = "rgba(113, 217, 129, 0.7)"; var OUTER_STROKE_COLOR_ERROR = "rgba(255, 45, 45, 0.7)"; var OUTER_FILL_COLOR_ERROR = "rgba(255, 81, 81, 0.7)"; var INNER_STROKE_COLOR_ERROR = "rgba(255, 45, 45, 0.7)"; var INNER_FILL_COLOR_ERROR = "rgba(255, 81, 81, 0.7)"; var LINE_STROKE_COLOR_NORMAL = "rgba(109, 222, 92, 0.7)"; var LINE_STROKE_COLOR_ERROR = "rgba(255, 81, 81, 0.7)"; var CIRCLE_INTERVAL = 30; var CIRCLE_MARGIN_HORIZONTAL_BORDER = (CANVAS_WIDTH - OUTER_RADIUS * 2 * 3 - 2 * CIRCLE_INTERVAL) / 2; var CIRCLE_MARGIN_VERTICAL_BORDER = 170; function Circle(x, y, id) { this.x = x; this.y = y; this.id = id, this.outer_stroke_color = OUTER_STROKE_COLOR_NORMAL; this.outer_fill_color = OUTER_FILL_COLOR_NORMAL; this.inner_stroke_color = INNER_STROKE_COLOR_NORMAL; this.inner_fill_color = INNER_FILL_COLOR_NORMAL; this.is_finish = false, this.setColor = function (outer_stroke_color, outer_fill_color, inner_stroke_color, inner_fill_color) { this.outer_stroke_color = outer_stroke_color; this.outer_fill_color = outer_fill_color; this.inner_stroke_color = inner_stroke_color; this.inner_fill_color = inner_fill_color; } this.checkTouch = function (m_x, m_y) { var distance = Math.sqrt(Math.pow(this.x - m_x, 2) + Math.pow(this.y - m_y, 2)); if (distance < OUTER_RADIUS) { return true; } else { return false; } } this.draw = function (ctx) { ctx.save(); ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = this.outer_stroke_color; ctx.fillStyle = this.outer_fill_color; ctx.arc(this.x, this.y, OUTER_RADIUS, 2 * Math.PI, 0, false); ctx.closePath(); ctx.stroke(); ctx.fill(); ctx.beginPath(); ctx.strokeStyle = this.inner_stroke_color; ctx.fillStyle = this.inner_fill_color; ctx.arc(this.x, this.y, INNER_RADIUS, 2 * Math.PI, 0, false); ctx.closePath(); ctx.stroke(); ctx.fill(); ctx.restore(); } } function Line(x, y) { this.start_x = x; this.start_y = y; this.end_x = x; this.end_y = y; this.stroke_color = LINE_STROKE_COLOR_NORMAL; this.is_finish = false; this.setEndXY = function (x, y) { this.end_x = x; this.end_y = y; } this.draw = function (ctx) { ctx.save(); ctx.lineWidth = 3; ctx.lineJoin = "round"; ctx.strokeStyle = this.stroke_color; ctx.beginPath(); ctx.moveTo(this.start_x, this.start_y); ctx.lineTo(this.end_x, this.end_y); ctx.closePath(); ctx.stroke(); ctx.restore(); } } function StatusBar() { this.draw = function (ctx) { ctx.save(); ctx.fillStyle = "rgba(1, 1, 1, 0.7)"; ctx.fillRect(0, 0, CANVAS_WIDTH, 25); ctx.restore(); } } function Tip(x, y) { this.x = x; this.y = y; this.text = "解鎖失敗,請重試"; this.draw = function (ctx) { ctx.save(); ctx.font = "14px 微軟雅黑"; ctx.textAlign = "center"; ctx.textBaseline = "top"; ctx.fillStyle = "#FF5151"; ctx.fillText(this.text, x, y); ctx.restore(); } } var canvas = document.createElement("canvas"); canvas.width = CANVAS_WIDTH; canvas.height = CANVAS_HEIGHT; canvas.style.display = "block"; canvas.style.margin = "20px auto"; canvas.style.backgroundImage = "url('demo/js/img/phone.jpeg')"; canvas.style.backgroundSize = CANVAS_WIDTH + "px " + CANVAS_HEIGHT + "px"; document.body.appendChild(canvas); var ctx = canvas.getContext("2d"); var is_finish = false; var is_mouse_down = false; // 鬆開滑鼠後,啟動一個計數器,相當於結果的顯示時間,這裡為50 * 20 = 1000ms var wait_count_total = 50; var wait_count = 0; var correct_id_arr = [0, 4, 8, 5, 2, 1, 3, 6, 7]; // 正確的序列 var line_id_arr = []; // 用於儲存連線節點的序列 var statusbar = new StatusBar(); var tip = new Tip(CANVAS_WIDTH / 2, 120); // 初始化連線線和節點圓列表 var line_list = []; var circle_list = []; for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { var x = CIRCLE_MARGIN_HORIZONTAL_BORDER + CIRCLE_INTERVAL * j + OUTER_RADIUS * (2 * j + 1); var y = CIRCLE_MARGIN_VERTICAL_BORDER + CIRCLE_INTERVAL * i + OUTER_RADIUS * (2 * i + 1); circle_list.push(new Circle(x, y, i * 3 + j)); } } this.reset = function () { tip.text = "解鎖失敗,請重試"; line_id_arr = []; line_list = []; for (var i = 0; i < circle_list.length; i++) { circle_list[i].setColor(OUTER_STROKE_COLOR_NORMAL, OUTER_FILL_COLOR_NORMAL, INNER_STROKE_COLOR_NORMAL, INNER_FILL_COLOR_NORMAL); circle_list[i].is_finish = false; } } this.checkIsCorrect = function () { var is_correct = false; if (correct_id_arr.length == line_id_arr.length) { var i; for (i = 0; i < correct_id_arr.length; i++) { if (correct_id_arr[i] != line_id_arr[i]) { break; } } if (i == correct_id_arr.length) { is_correct = true; } } if (!is_correct) { // 設定解鎖失敗時的顏色 for (var i = 0; i < correct_id_arr.length; i++) { circle_list[i].setColor(OUTER_STROKE_COLOR_ERROR, OUTER_FILL_COLOR_ERROR, INNER_STROKE_COLOR_ERROR, INNER_FILL_COLOR_ERROR); } for (var i = 0; i < line_list.length; i++) { line_list[i].stroke_color = LINE_STROKE_COLOR_ERROR; } } else { tip.text = "解鎖成功"; } } this.addEventListener("mouseup", function (event) { if (is_mouse_down) { is_finish = true; is_mouse_down = false; line_list.pop();// 刪除最後一根線 checkIsCorrect(); } }, false); this.addEventListener("mousedown", function (event) { if (is_finish) return; var start_x = event.pageX - canvas.offsetLeft; var start_y = event.pageY - canvas.offsetTop; for (var i = 0; i < circle_list.length; i++) { if (circle_list[i].checkTouch(start_x, start_y)) { line_id_arr.push(circle_list[i].id); circle_list[i].is_finish = true; circle_list[i].setColor(OUTER_STROKE_COLOR_TOUCH, OUTER_FILL_COLOR_TOUCH, INNER_STROKE_COLOR_TOUCH, INNER_FILL_COLOR_TOUCH); is_mouse_down = true; line_list.push(new Line(circle_list[i].x, circle_list[i].y)); break; } } }, false); this.addEventListener("mousemove", function (event) { if (is_mouse_down) { var curr_x = event.pageX - canvas.offsetLeft; var curr_y = event.pageY - canvas.offsetTop; line_list[line_list.length - 1].setEndXY(curr_x, curr_y); for (var i = 0; i < circle_list.length; i++) { if (false == circle_list[i].is_finish && circle_list[i].checkTouch(curr_x, curr_y)) { line_id_arr.push(circle_list[i].id); circle_list[i].is_finish = true; circle_list[i].setColor(OUTER_STROKE_COLOR_TOUCH, OUTER_FILL_COLOR_TOUCH, INNER_STROKE_COLOR_TOUCH, INNER_FILL_COLOR_TOUCH); line_list[line_list.length - 1].is_finish = true; line_list[line_list.length - 1].setEndXY(circle_list[i].x, circle_list[i].y); line_list.push(new Line(circle_list[i].x, circle_list[i].y)); } } } }, false); // 更新函式,繪製所有圖形 this.setInterval(function () { ctx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); statusbar.draw(ctx); for (var i = 0; i < circle_list.length; i++) { circle_list[i].draw(ctx); } for (var i = 0; i < line_list.length; i++) { line_list[i].draw(ctx); } if (is_finish) { tip.draw(ctx); wait_count++; if (wait_count >= wait_count_total) { wait_count = 0; is_finish = false; reset(); } } }, 20, false); </script> </body> </html>
相關文章
- Android實現拼圖解鎖Android圖解
- 原生JS實現輪播圖的效果JS
- javascript實現文字拼寫動畫效果JavaScript動畫
- CSS + JS 實現打字機效果CSSJS
- WPF實現手勢解鎖
- JS實現馬賽克圖片效果JS
- canvas拼圖功能實現Canvas
- 手機直播原始碼,實現圖片瀑布流式滑動效果原始碼
- JS實現有點炫的圖片展示效果-圖片解體和組合JS
- 手機端上傳照片實現 壓縮、拖放、縮放、裁剪、合成拼圖等功能
- 用js(hover )+css實現下拉框效果(有效果圖)JSCSS
- 用 canvas 實現 Web 手勢解鎖CanvasWeb
- 原生 JavaScript 實現手勢解鎖元件JavaScript元件
- Vue.js 滑動拼圖驗證碼實現筆記Vue.js筆記
- 基於Nuxt.js實現滑動拼圖驗證碼UXJS
- 悲觀鎖與樂觀鎖的實現(詳情圖解)圖解
- Html5實現手機九宮格密碼解鎖功能HTML密碼
- js實現打字效果JS
- js拖動實現左右圖片對比效果JS
- JS實現 類似圖片3D效果JS3D
- css3實現手機效果的“切換標籤”CSSS3
- 用 JavaScript 實現簡單拼圖遊戲JavaScript遊戲
- Canvas drag 實現拖拽拼圖小遊戲Canvas遊戲
- javascript實現的焦點圖輪播效果詳解JavaScript
- js實現手機網頁滑動JS網頁
- asp.net+js方式實現的幻燈圖片效果展示ASP.NETJS
- JS實現輪播圖效果(有詳細註釋)JS
- HTML5實現螢幕手勢解鎖HTML
- 防手機鎖屏解鎖自定義ViewView
- 圖片放大鏡效果實現過程詳解
- 實現網頁中的搜尋輸入框效果 onfocuse onblur js 驗證手機號 座機區號網頁JS
- JS互動 點選WKWebView中的圖片實現預覽效果JSWebView
- js如何實現手機呼叫震動功能JS
- js滑鼠移動實現圖片立體滾動效果JS
- JS和Css實現紅包雨的效果JSCSS
- 那些不用js也能實現的效果JS
- css模擬實現手機通訊錄佈局效果CSS
- JS實現動態瀑布流及放大切換圖片效果(js案例)JS