forked from Franslee/lucky-card
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
feifanli
committed
Sep 14, 2015
1 parent
6387e32
commit ab5399e
Showing
11 changed files
with
692 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# PageSlider # | ||
|
||
PageSlider 是一个基于zepto.js用于实现H5单页面跟随手指上下滑动切换的组件,支持通过transform3D启动GPU加速,目前仅支持移动端touch设备。 | ||
|
||
## DEMO ## | ||
|
||
请用手机扫描以下二维码,在打开的页面上下滑动查看效果 | ||
# | ||
|
||
## 用法 ## | ||
|
||
HTML结构 | ||
|
||
```html | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<!-- styles, scripts, etc --> | ||
</head> | ||
<body> | ||
<div class="section sec1"></div> | ||
<div class="section sec2"></div> | ||
<div class="section sec3"></div> | ||
<div class="section sec4"></div> | ||
</body> | ||
</html> | ||
``` | ||
|
||
在页面中引入组件所需样式表文件pageSlider.css | ||
|
||
```html | ||
<link rel="stylesheet" href="../dist/pageSlider.css"> | ||
``` | ||
|
||
本组件基于zepto,需要在页面中引入zepto.js文件 | ||
|
||
```html | ||
<script src='http://cdn.bootcss.com/zepto/1.1.4/zepto.min.js'></script> | ||
``` | ||
|
||
引入pageSlider.js/pageSlider.min.js文件 | ||
|
||
```html | ||
<script src='../dist/pageSlider.js'></script> | ||
``` | ||
|
||
在页面DOM加载完毕之后,初始化组件 | ||
|
||
```js | ||
$(function() { | ||
var pageSlider = PageSlider.case(); | ||
}); | ||
``` | ||
|
||
## 设置 settings ## | ||
|
||
初始化PageSlider组件时,支持传入一个参数,用于配置组件功能 | ||
|
||
```js | ||
PageSlider.case(optOrIndex); | ||
``` | ||
|
||
* 参数optOrIndex可以是一个数字(number),用于设置初始显示的页码 | ||
* 参数optOrIndex也可以是一个json对象,允许的keys见下表 | ||
|
||
<table> | ||
<tr> | ||
<th>key</th> | ||
<th>类型</th> | ||
<th>默认值</th> | ||
<th>描述</th> | ||
</tr> | ||
<tr> | ||
<td>startPage</td> | ||
<td>number</td> | ||
<td>1</td> | ||
<td>初始化时显示页面的页码</td> | ||
</tr> | ||
<tr> | ||
<td>range</td> | ||
<td>number</td> | ||
<td>70</td> | ||
<td>页面回弹的最大距离(像素),小于该值页面回弹,超过该值页面将切换</td> | ||
</tr> | ||
<tr> | ||
<td>duration</td> | ||
<td>number</td> | ||
<td>200</td> | ||
<td>页面回弹动画持续的时间(毫秒)</td> | ||
</tr> | ||
<tr> | ||
<td>loop</td> | ||
<td>boolean</td> | ||
<td>false</td> | ||
<td>是否循环切换</td> | ||
</tr> | ||
<tr> | ||
<td>elastic</td> | ||
<td>boolean</td> | ||
<td>true</td> | ||
<td>位于顶部(底部)时,是否依然可以向上(向下)拉动</td> | ||
</tr> | ||
<tr> | ||
<td>translate3d</td> | ||
<td>boolean</td> | ||
<td>true</td> | ||
<td>是否使用translate3d(在支持translate3d的设备上),使用translate3d会使一些设备开启GPU加速,滑动更流畅</td> | ||
</tr> | ||
<tr> | ||
<td>callback</td> | ||
<td>object</td> | ||
<td>{}</td> | ||
<td>页面切换回调函数集合。该json对象每个键为一个数值,对应一个页码,值为一个function,滑动到该页面时触发。如:{2:function(){alert('滑动到了第二页');},4:function(){alert('滑动到了第四页');}} 滑动到第二和第四页时将触发对应的回调函数</td> | ||
</tr> | ||
</table> | ||
|
||
```js | ||
PageSlider.case({loop:true}); | ||
``` | ||
|
||
## 切换到指定页面 ## | ||
|
||
在页面初始化后,可调用组件的go方法跳转到指定页面。 | ||
|
||
```js | ||
//PageSlider初始化 | ||
var pageSlider = PageSlider.case(); | ||
//跳转到第3页 | ||
pageSlider.go(3); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<title>lucky-card.js demo</title> | ||
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, width=device-width"> | ||
<style> | ||
html, | ||
body { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
|
||
body { | ||
background: #FFFFFF; | ||
} | ||
|
||
#card { | ||
height: 100%; | ||
font-weight: bold; | ||
font-size: 36px; | ||
line-height: 100px; | ||
text-align: center; | ||
background: #FAFAFA; | ||
} | ||
|
||
#scratch { | ||
width: 300px; | ||
height: 100px; | ||
margin: 50px auto 0; | ||
border: 1px solid #ccc; | ||
} | ||
</style> | ||
<link rel="stylesheet" href="./dist/lucky-card.css"> | ||
<script src="./dist/lucky-card.min.js"></script> | ||
</head> | ||
|
||
<body> | ||
<div id="scratch"> | ||
<div id="card">¥1000.00万</div> | ||
</div> | ||
<script> | ||
LuckyCard.case({ | ||
ratio: .6 | ||
}, function() { | ||
alert('至于你信不信,我反正不信!'); | ||
this.clearCover(); | ||
}); | ||
</script> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#scratch{ position: relative;} | ||
#cover{ position: absolute; top:0; left:0;} | ||
#card{ -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none;} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/* | ||
* lucky-card.js - Scratch CARDS based on HTML5 Canvas | ||
* | ||
* Copyright (c) 2015 Frans Lee dmon@foxmail.com | ||
* | ||
* https://github.com/Franslee/lucky-card | ||
* | ||
* Licensed under the MIT license: | ||
* http://www.opensource.org/licenses/mit-license.php | ||
* | ||
* Version: 1.0 | ||
* | ||
*/ | ||
; | ||
(function(window, document, undefined) { | ||
'use strict'; | ||
|
||
/** | ||
* Instantiate parameters | ||
* | ||
* @constructor | ||
*/ | ||
function LuckyCard(settings, callback) { | ||
this.cover = null; | ||
this.ctx = null; | ||
this.scratchDiv = null; | ||
this.cardDiv = null; | ||
this.cHeight = 0; | ||
this.cWidth = 0; | ||
this.supportTouch = false; | ||
this.events = []; | ||
this.startEventHandler = null; | ||
this.moveEventHandler = null; | ||
this.endEventHandler = null; | ||
|
||
this.opt = { | ||
coverColor: '#C5C5C5', | ||
coverImg: '', | ||
ratio: .8, | ||
callback: null | ||
}; | ||
|
||
this.init(settings, callback); | ||
}; | ||
|
||
function _calcArea(ctx, callback, ratio) { | ||
var pixels = ctx.getImageData(0, 0, 300, 100); | ||
var transPixels = []; | ||
_forEach(pixels.data, function(item, i) { | ||
var pixel = pixels.data[i + 3]; | ||
if (pixel === 0) { | ||
transPixels.push(pixel); | ||
} | ||
}); | ||
|
||
if (transPixels.length / pixels.data.length > ratio) { | ||
callback && typeof callback === 'function' && callback(); | ||
} | ||
} | ||
|
||
function _forEach(items, callback) { | ||
return Array.prototype.forEach.call(items, function(item, idx) { | ||
callback(item, idx); | ||
}); | ||
} | ||
|
||
/** | ||
* touchstart/mousedown event handler | ||
*/ | ||
function _startEventHandler(event) { | ||
this.moveEventHandler = _moveEventHandler.bind(this); | ||
this.cover.addEventListener(this.events[1],this.moveEventHandler,false); | ||
this.endEventHandler = _endEventHandler.bind(this); | ||
document.addEventListener(this.events[2],this.endEventHandler,false); | ||
event.preventDefault(); | ||
}; | ||
|
||
/** | ||
* touchmove/mousemove event handler | ||
*/ | ||
function _moveEventHandler(event) { | ||
var evt = this.supportTouch?event.touches[0]:event; | ||
var coverPos = this.cover.getBoundingClientRect(); | ||
var mouseX = evt.pageX - coverPos.left; | ||
var mouseY = evt.pageY - coverPos.top; | ||
|
||
this.ctx.beginPath(); | ||
this.ctx.fillStyle = '#FFFFFF'; | ||
this.ctx.globalCompositeOperation = "destination-out"; | ||
this.ctx.arc(mouseX, mouseY, 10, 0, 2 * Math.PI); | ||
this.ctx.fill(); | ||
|
||
event.preventDefault(); | ||
}; | ||
|
||
/** | ||
* touchend/mouseup event handler | ||
*/ | ||
function _endEventHandler(event) { | ||
if (this.opt.callback && typeof this.opt.callback === 'function') _calcArea(this.ctx, this.opt.callback, this.opt.ratio); | ||
this.cover.removeEventListener(this.events[1],this.moveEventHandler,false); | ||
document.removeEventListener(this.events[2],this.endEventHandler,false); | ||
event.preventDefault(); | ||
}; | ||
|
||
/** | ||
* Create Canvas element | ||
*/ | ||
LuckyCard.prototype.createCanvas = function() { | ||
this.cover = document.createElement('canvas'); | ||
this.cover.id = 'cover'; | ||
this.cover.height = this.cHeight; | ||
this.cover.width = this.cWidth; | ||
this.ctx = this.cover.getContext('2d'); | ||
if (this.opt.coverImg) { | ||
var _this = this; | ||
var coverImg = new Image(); | ||
coverImg.src = this.opt.coverImg; | ||
coverImg.onload = function() { | ||
_this.ctx.drawImage(coverImg, 0, 0, _this.cover.width, _this.cover.height); | ||
} | ||
} else { | ||
this.ctx.fillStyle = this.opt.coverColor; | ||
this.ctx.fillRect(0, 0, this.cover.width, this.cover.height); | ||
} | ||
this.scratchDiv.appendChild(this.cover); | ||
} | ||
|
||
/** | ||
* To detect whether support touch events | ||
*/ | ||
LuckyCard.prototype.eventDetect = function() { | ||
if('ontouchstart' in window) this.supportTouch = true; | ||
this.events = this.supportTouch ? ['touchstart', 'touchmove', 'touchend'] : ['mousedown', 'mousemove', 'mouseup']; | ||
this.addEvent(); | ||
}; | ||
|
||
/** | ||
* Add touchstart/mousedown event listener | ||
*/ | ||
LuckyCard.prototype.addEvent = function() { | ||
this.startEventHandler = _startEventHandler.bind(this); | ||
this.cover.addEventListener(this.events[0],this.startEventHandler,false); | ||
}; | ||
|
||
/** | ||
* Clear pixels of canvas | ||
*/ | ||
LuckyCard.prototype.clearCover = function() { | ||
this.ctx.clearRect(0, 0, this.cover.width, this.cover.height); | ||
}; | ||
|
||
|
||
/** | ||
* LuckyCard initializer | ||
* | ||
* @param {Object} settings Settings for LuckyCard | ||
* @param {function} callback callback function | ||
*/ | ||
LuckyCard.prototype.init = function(settings, callback) { | ||
var _this = this; | ||
_forEach(arguments, function(item) { | ||
if (typeof item === "object") { | ||
for (var k in item) { | ||
if (k === 'callback' && typeof item[k] === 'function') { | ||
_this.opt.callback = item[k].bind(_this); | ||
} else { | ||
_this.opt[k] && (_this.opt[k] = item[k]); | ||
} | ||
} | ||
} else if (typeof item === "function") { | ||
_this.opt.callback = item.bind(_this); | ||
} | ||
}); | ||
this.scratchDiv = document.getElementById('scratch'); | ||
this.cardDiv = document.getElementById('card'); | ||
if (!this.scratchDiv || !this.cardDiv) return; | ||
this.cHeight = this.cardDiv.clientHeight; | ||
this.cWidth = this.cardDiv.clientWidth; | ||
this.createCanvas(); | ||
this.eventDetect(); | ||
}; | ||
|
||
/** | ||
* To generate an instance of object | ||
* | ||
* @param {Object} settings Settings for LuckyCard | ||
* @param {function} callback callback function | ||
*/ | ||
LuckyCard.case = function(settings, callback) { | ||
return new LuckyCard(settings, callback); | ||
}; | ||
|
||
|
||
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { | ||
define(function() { | ||
return LuckyCard; | ||
}); | ||
} else if (typeof module !== 'undefined' && module.exports) { | ||
module.exports = LuckyCard.case; | ||
module.exports.LuckyCard = LuckyCard; | ||
} else { | ||
window.LuckyCard = LuckyCard; | ||
} | ||
|
||
})(window, document); |
Oops, something went wrong.