Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First import

  • Loading branch information...
commit 6fde7336f4c68342c42db2d0bacae32cab6586de 1 parent b7ad7a7
@wassimchegham wassimchegham authored
View
47 android-pattern-lockScreen.App.js
@@ -0,0 +1,47 @@
+window.addEventListener('load', function() {
+ var app = (new PatternLockScreen("lock-screen")).start();
+ var unlockButton = document.getElementById('unlock-button');
+ var savePatternButton = document.getElementById('save-pattern-button');
+ var resetButton = document.getElementById('reset-button');
+ var showHint = true;
+
+ savePatternButton.addEventListener('click', function(){
+ var span = this.getElementsByClassName('gray');
+ if( span.className==='red' ){
+ this.innerHTML = '<span class="gray"></span>Record Pattern';
+ span.className = 'gray';
+ app.stopRecordPattern();
+ unlockButton.style.display = 'inline';
+ }
+ else {
+ this.innerHTML = '<span class="red"></span>Recording...';
+ span.className = 'red';
+ app.startRecordPattern();
+ unlockButton.style.display = 'none';
+ }
+ }, false);
+ unlockButton.addEventListener('click', function(){
+ var btn = this;
+ if( !app.unlock() ){
+ this.className = "button red";
+ setTimeout(function(){
+ btn.className = "button blue";
+ }, 1000);
+ }
+ else {
+ btn.className = "button green";
+ alert('Access Granted!');
+ }
+ }, false);
+ resetButton.addEventListener('click', function(){
+ app.reset();
+ });
+ document.addEventListener('keyup', function(e){
+ app.showHint(showHint);
+ var code = e.keyCode || e.which;
+ if( code === 72 ){
+ showHint = !showHint;
+ }
+ });
+
+}, false);
View
102 android-pattern-lockScreen.Dot.js
@@ -0,0 +1,102 @@
+function Dot(o){
+ var self = this;
+ this.x = o.x;
+ this.y = o.y;
+ this.dotInnerLayer = o.innerLayer;
+ this.listenerLayer = o.listenerLayer;
+ this.pattern = o.pattern;
+
+ this.innerCircleRadius = 5;
+ this.strokeWidth = 4;
+ this.innerCircleFill = "rgba(255,255,255,0)";
+ this.innerCircleStroke = "#aaa";
+
+ var stage = this.dotInnerLayer.getStage();
+ var m = Math.min(
+ stage.getWidth(),
+ stage.getHeight()
+ );
+ this.outerCircleConfig = {
+ radius : m/10,
+ fill : "rgba(255,255,255,0)",
+ stroke : "lime",
+ strokeWidth : self.strokeWidth,
+ };
+
+ this.innerCircle = new Kinetic.Circle({
+ x: self.x,
+ y: self.y,
+ radius: self.innerCircleRadius,
+ fill: self.innerCircleFill,
+ stroke: self.innerCircleStroke,
+ strokeWidth: self.strokeWidth
+ });
+ this.listenerCircle = new Kinetic.Circle({
+ x: self.x,
+ y: self.y,
+ radius: self.outerCircleConfig.radius,
+ fill: 'transparent'
+ });
+ this.listenerCircle.on("mousedown mousemove touchmove", this.addOuterCircle.bind(this));
+ this.listenerCircle.on("mouseout", this.mouseout.bind(this));
+ this.listenerCircle.on("mouseup touchend", this.isValid.bind(this));
+ this.listenerLayer.add(this.listenerCircle);
+ this.dotInnerLayer.add(this.innerCircle);
+ this.dotInnerLayer.draw();
+
+ return this;
+};
+Dot.prototype.isValid = function(){
+ if( this.pattern.isRecording ){
+ return;
+ }
+
+ var event;
+ if (document.createEvent) {
+ event = document.createEvent("HTMLEvents");
+ event.initEvent("click", true, true);
+ } else {
+ event = document.createEventObject();
+ event.eventType = "click";
+ };
+
+ var btn = document.getElementById('unlock-button');
+ if( btn.dispatchEvent ){
+ btn.dispatchEvent(event);
+ }
+ else if( btn.fireEvent ){
+ btn.fireEvent('on'+event.eventTye, event);
+ }
+};
+Dot.prototype.addOuterCircle = function(e) {
+
+ document.body.style.cursor = 'pointer';
+
+ // hide the inner circle
+ this.innerCircle.setStrokeWidth(2);
+ this.dotInnerLayer.draw();
+
+ // add an outer circle if needed
+ var self = this;
+ var outerCircle = new Kinetic.Circle({
+ x: self.innerCircle.getX(),
+ y: self.innerCircle.getY(),
+ radius: 0,
+ fill: self.outerCircleConfig.fill,
+ stroke: self.outerCircleConfig.stroke,
+ strokeWidth: self.outerCircleConfig.strokeWidth
+ });
+ this.pattern.addDot(outerCircle, this.outerCircleConfig);
+
+};
+Dot.prototype.mouseover = function() {
+ document.body.style.cursor = 'pointer';
+};
+Dot.prototype.mouseout = function() {
+ document.body.style.cursor = 'default';
+};
+Dot.prototype.clear = function(){
+ this.innerCircle.setFill(this.innerCircleFill);
+ this.innerCircle.setRadius(this.innerCircleRadius);
+ this.dotInnerLayer.draw();
+};
View
176 android-pattern-lockScreen.Pattern.js
@@ -0,0 +1,176 @@
+function Pattern(o){
+ this.userDots = [];
+ this.savedPattern = [];
+ var stage = o.patternLayer.getStage();
+ var mousePos = stage.getMousePosition() || {x: stage.getWidth()/2, y: stage.getHeight()/2};
+ this._x0 = mousePos.x;
+ this._y0 = mousePos.y;
+ this._x = this._x0 ;
+ this._y = this._y0;
+ this.patternLayer = o.patternLayer;
+ this.lineLayer = o.lineLayer;
+ this.hintLayer = o.hintLayer;
+ this.isRecording = false;
+ this.toBeClearedOnNextUse = false;
+};
+Pattern.prototype.setRecording = function(state){
+ this.isRecording = state;
+};
+Pattern.prototype.setToBeClearedOnNextUse = function(state){
+ this.toBeClearedOnNextUse = state;
+};
+Pattern.prototype.show = function(){
+ this.hintLayer.show();
+ this.hintLayer.draw();
+};
+Pattern.prototype.hide = function(){
+ this.hintLayer.hide();
+ this.hintLayer.draw();
+};
+Pattern.prototype.buildHint = function(){
+ line = this.getLine(this.savedPattern);
+ this.lineLayer.removeChildren();
+ this.hintLayer.add(line);
+};
+Pattern.prototype.addDot = function(dot, config){
+ if( this.toBeClearedOnNextUse ){
+ this.clear();
+ this.toBeClearedOnNextUse = false;
+ }
+
+ if( this.shouldDrawDot(dot) ){
+
+ if( this.isRecording ){
+ this.savePatternDot(dot);
+ }
+ else {
+ if( this.shouldDrawDot(dot) ){
+ this.saveUserDot(dot);
+ }
+ }
+
+ this.patternLayer.add(dot);
+ this.setTransition(dot, config);
+ this.patternLayer.draw();
+ }
+
+};
+Pattern.prototype.shouldDrawDot = function(dot){
+ var dots = this.isRecording ? this.savedPattern : this.userDots;
+ for(var i=0; i<dots.length; i+=1){
+ var o = dots[i];
+ if( o.getX() === dot.getX() && o.getY() === dot.getY() ){
+ return false;
+ }
+ };
+ return true;
+};
+Pattern.prototype.setTransition = function(dot, config){
+ var self = this;
+ dot.transitionTo({
+ radius: config.radius,
+ duration: 0.1,
+ callback: self.drawLine()
+ });
+};
+Pattern.prototype.saveUserDot = function(dot){
+ this.userDots.push(dot);
+};
+Pattern.prototype.drawLine = function(){
+ var line;
+ var dot1;
+ var dot2;
+ var dots = this.isRecording ? this.savedPattern : this.userDots;
+ var l = dots.length;
+ if( l >= 2 ){
+ line = this.getLine(dots);
+ this.lineLayer.removeChildren();
+ this.lineLayer.add(line);
+ this.lineLayer.draw();
+ }
+};
+Pattern.prototype.getLine = function(dots){
+ return new Kinetic.Shape({
+ drawFunc: function() {
+ var ctx = this.getContext();
+ var dot1 = dots[0];
+ var dot;
+ ctx.beginPath();
+ ctx.moveTo(dot1.getX(), dot1.getY());
+ for(var i=1; i<dots.length; i+=1){
+ dot = dots[i];
+ ctx.lineTo(dot.getX(), dot.getY());
+ }
+ ctx.lineJoin = "round";
+ ctx.lineCap = "round";
+ ctx.strokeStyle = "rgba(255,255,255,0.5)";
+ ctx.lineWidth = 5;
+ ctx.stroke();
+ ctx.closePath();
+ },
+ stroke: "rgba(255,255,255,0.5)",
+ strokeWidth: 5
+ });
+};
+Pattern.prototype.isValid = function(){
+ if( this.savedPattern.length !== this.userDots.length ){
+ return false;
+ };
+ for(var i=0; i<this.savedPattern.length; i++){
+ var savedDot = this.savedPattern[i];
+ var userDot = this.userDots[i];
+ if( savedDot.getX() !== userDot.getX() || savedDot.getY() !== userDot.getY() ){
+ return false;
+ }
+ };
+ return true;
+};
+Pattern.prototype.getDots = function(){
+ return this.userDots;
+};
+Pattern.prototype.clear = function(){
+ this.clearUserDots();
+ this.clearLayers();
+ return this;
+};
+Pattern.prototype.clearUserDots = function(){
+ this.userDots = [];
+};
+Pattern.prototype.clearLayers = function(){
+ var self = this;
+ var dots = this.patternLayer.getChildren();
+ var l = dots.length;
+ for(var i=0; i<l; i+=1){
+ var dot = dots[i];
+ dot.transitionTo({
+ radius: 0,
+ duration: 0.1,
+ callback: function(){
+ if( l-1 === i ){
+ self.patternLayer.clear();
+ self.patternLayer.removeChildren();
+ self.patternLayer.draw();
+ }
+ }
+ });
+ };
+
+ self.lineLayer.clear();
+ self.lineLayer.removeChildren();
+ self.lineLayer.draw();
+
+};
+Pattern.prototype.savePatternDot = function(dot){
+ this.savedPattern.push({
+ x: dot.getX(),
+ y: dot.getY(),
+ getX: function(){ return this.x; },
+ getY: function(){ return this.y; }
+ });
+};
+Pattern.prototype.clearSavedPattern = function(){
+ this.savedPattern = [];
+ this.hintLayer.removeChildren();
+ this.hintLayer.clear();
+ this.hintLayer.draw();
+};
View
121 android-pattern-lockScreen.PatternLockScreen.js
@@ -0,0 +1,121 @@
+function PatternLockScreen(container){
+ var config = {
+ width: 400,
+ height: 400
+ };
+ this.stage = new Kinetic.Stage({
+ container: container,
+ width: config.width,
+ height: config.height
+ });
+ this.dots = [];
+ this.dotsInnerLayer = new Kinetic.Layer();
+ this.dotsOuterLayer = new Kinetic.Layer();
+ this.lineLayer = new Kinetic.Layer();
+ this.hintLayer = new Kinetic.Layer();
+ this.listenerLayer = new Kinetic.Layer();
+ this.hintLayer.setAlpha(0.1);
+ this.stage.add(this.dotsInnerLayer);
+ this.stage.add(this.dotsOuterLayer);
+ this.stage.add(this.lineLayer);
+ this.stage.add(this.hintLayer);
+ this.stage.add(this.listenerLayer);
+
+ this.pattern = new Pattern({
+ patternLayer : this.dotsOuterLayer,
+ lineLayer : this.lineLayer,
+ hintLayer : this.hintLayer,
+ });
+};
+PatternLockScreen.prototype.start = function(){
+ var i;
+ var w = this.stage.getWidth();
+ var h = this.stage.getHeight();
+ var mW = Math.floor((w/2));
+ var mH = Math.floor((h/2));
+ var offsetW = Math.floor(w/3);
+ var offsetH = Math.floor(h/3);
+ var points = [
+ { x: mW - offsetW, y: mH - offsetH },
+ { x: mW, y: mH - offsetH },
+ { x: mW + offsetW, y: mH - offsetH },
+
+ { x: mW - offsetW, y: mH },
+ { x: mW, y: mH },
+ { x: mW + offsetW, y: mH },
+
+ { x: mW - offsetW, y: mH + offsetH },
+ { x: mW, y: mH + offsetH },
+ { x: mW + offsetW, y: mH + offsetH },
+ ];
+ for( i = 0; i < points.length; i+=1 ){
+ var options = {
+ pattern : this.pattern,
+ innerLayer : this.dotsInnerLayer,
+ listenerLayer : this.listenerLayer,
+ x : points[i].x,
+ y : points[i].y
+ }
+ this.dots.push(new Dot(options));
+ };
+ return this;
+};
+PatternLockScreen.prototype.getPattern = function(){
+ return this.pattern;
+};
+PatternLockScreen.prototype.clear = function(){
+ this.pattern.clear();
+ for(var i=0; i<this.dots.length; i+=1){
+ this.dots[i].clear();
+ };
+};
+PatternLockScreen.prototype.reset = function(){
+ this.clear();
+ this.pattern.clearSavedPattern();
+};
+PatternLockScreen.prototype.unlock = function(){
+ if( this.pattern.isValid() ){
+ this.validatePattern();
+ return true;
+ }
+ else {
+ this.invalidatePattern();
+ return false;
+ }
+};
+PatternLockScreen.prototype.validatePattern = function(){
+
+};
+PatternLockScreen.prototype.invalidatePattern = function(){
+ var dots = this.dotsOuterLayer.getChildren();
+ var line = this.lineLayer.getChildren();
+ line[0].setFill("rgba(255,0,0,0.5)");
+ var self = this;
+ for(var i=0; i<dots.length; i+=1){
+ var dot = dots[i];
+ var radius = dot.getRadius();
+ dot.setStroke("rgba(255,0,0,0.8)");
+ };
+ this.dotsOuterLayer.draw();
+ this.lineLayer.draw();
+ this.pattern.setToBeClearedOnNextUse(true);
+};
+PatternLockScreen.prototype.startRecordPattern = function(){
+ this.clear();
+ this.pattern.clearSavedPattern();
+ this.pattern.setRecording(true);
+ this.pattern.setToBeClearedOnNextUse(false);
+};
+PatternLockScreen.prototype.stopRecordPattern = function(){
+ this.clear();
+ this.pattern.setRecording(false);
+ this.pattern.buildHint();
+};
+PatternLockScreen.prototype.showHint = function(show){
+ if( show ){
+ this.pattern.show();
+ }
+ else {
+ this.pattern.hide();
+ }
+};
View
134 android-pattern-lockScreen.css
@@ -0,0 +1,134 @@
+body {
+ background: #181818;
+ color: #fff;
+ position: relative;
+}
+h1 {
+ font-family: 'Sansita One', cursive;
+}
+#lock-screen-container {
+ position: relative;
+}
+.buttons {
+ padding: 0 0 0 58px;
+}
+.button {
+ display: inline-block;
+ zoom: 1; /* zoom and *display = ie7 hack for display:inline-block */
+ *display: inline;
+ vertical-align: baseline;
+ height: 33px;
+ margin: 0 2px;
+ outline: none;
+ cursor: pointer;
+ text-align: center;
+ text-decoration: none;
+ font: 14px/100% Arial, Helvetica, sans-serif;
+ padding: 0 10px;
+ text-shadow: 0 1px 1px rgba(0,0,0,.3);
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ border-radius: .5em;
+ -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
+ -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
+ box-shadow: 0 1px 2px rgba(0,0,0,.2);
+}
+.button:hover {
+ text-decoration: none;
+}
+.button:active {
+ position: relative;
+ top: 1px;
+}
+/* red */
+.red {
+ color: #faddde;
+ border: solid 1px #980c10;
+ background: #d81b21;
+ background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24), to(#aa1317));
+ background: -moz-linear-gradient(top, #ed1c24, #aa1317);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ed1c24', endColorstr='#aa1317');
+}
+.red:hover {
+ background: #b61318;
+ background: -webkit-gradient(linear, left top, left bottom, from(#c9151b), to(#a11115));
+ background: -moz-linear-gradient(top, #c9151b, #a11115);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c9151b', endColorstr='#a11115');
+}
+.red:active {
+ color: #de898c;
+ background: -webkit-gradient(linear, left top, left bottom, from(#aa1317), to(#ed1c24));
+ background: -moz-linear-gradient(top, #aa1317, #ed1c24);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#aa1317', endColorstr='#ed1c24');
+}
+
+/* blue */
+.blue {
+ color: #d9eef7;
+ border: solid 1px #0076a3;
+ background: #0095cd;
+ background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5));
+ background: -moz-linear-gradient(top, #00adee, #0078a5);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5');
+}
+.blue:hover {
+ background: #007ead;
+ background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e));
+ background: -moz-linear-gradient(top, #0095cc, #00678e);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e');
+}
+.blue:active {
+ color: #80bed6;
+ background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee));
+ background: -moz-linear-gradient(top, #0078a5, #00adee);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee');
+}
+/* green */
+.green {
+ color: #e8f0de;
+ border: solid 1px #538312;
+ background: #64991e;
+ background: -webkit-gradient(linear, left top, left bottom, from(#7db72f), to(#4e7d0e));
+ background: -moz-linear-gradient(top, #7db72f, #4e7d0e);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7db72f', endColorstr='#4e7d0e');
+}
+.green:hover {
+ background: #538018;
+ background: -webkit-gradient(linear, left top, left bottom, from(#6b9d28), to(#436b0c));
+ background: -moz-linear-gradient(top, #6b9d28, #436b0c);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6b9d28', endColorstr='#436b0c');
+}
+.green:active {
+ color: #a9c08c;
+ background: -webkit-gradient(linear, left top, left bottom, from(#4e7d0e), to(#7db72f));
+ background: -moz-linear-gradient(top, #4e7d0e, #7db72f);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4e7d0e', endColorstr='#7db72f');
+}
+.gray {
+ color: #e9e9e9;
+ border: solid 1px #555;
+ background: #6e6e6e;
+ background: -webkit-gradient(linear, left top, left bottom, from(#888), to(#575757));
+ background: -moz-linear-gradient(top, #888, #575757);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#888888', endColorstr='#575757');
+}
+.gray:hover {
+ background: #616161;
+ background: -webkit-gradient(linear, left top, left bottom, from(#757575), to(#4b4b4b));
+ background: -moz-linear-gradient(top, #757575, #4b4b4b);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#757575', endColorstr='#4b4b4b');
+}
+.gray:active {
+ color: #afafaf;
+ background: -webkit-gradient(linear, left top, left bottom, from(#575757), to(#888));
+ background: -moz-linear-gradient(top, #575757, #888);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#575757', endColorstr='#888888');
+}
+#save-pattern-button span {
+ border-radius: 20px;
+ width: 15px;
+ height: 15px;
+ display: block;
+ float: left;
+ margin: 0 10px 0px 0;
+}
View
33 index.html
@@ -0,0 +1,33 @@
+<!DOCTYPE public>
+<html lang="en">
+ <head>
+ <meta name="HandheldFriendly" content="True">
+ <meta name="MobileOptimized" content="320">
+ <meta name="viewport" content = "width=device-width , user-scalable=no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
+ <meta http-equiv="cleartype" content="on">
+
+ <title>Android Pattern LockScreen using Canvas</title>
+ <link href='http://fonts.googleapis.com/css?family=Sansita+One' rel='stylesheet'/>
+ <link rel="stylesheet" href="android-pattern-lockScreen.css" />
+ <script src="kinetic-v3.9.8.js"></script>
+ </head>
+ <body>
+ <div id="lock-screen-container">
+ <h1>Android Pattern LockScreen</h1>
+ <div class="buttons">
+ <button id="save-pattern-button" class="button blue">
+ <span class="gray"></span>Record Pattern</button>
+ <button id="unlock-button" class="button blue">Unlock</button>
+ <button id="reset-button" class="button blue">Reset</button>
+ <br/>
+ </div>
+ <div id="lock-screen" />
+ </div>
+ <script src="android-pattern-lockScreen.Pattern.js"></script>
+ <script src="android-pattern-lockScreen.PatternLockScreen.js"></script>
+ <script src="android-pattern-lockScreen.Dot.js"></script>
+ <script src="android-pattern-lockScreen.App.js"></script>
+ </body>
+</html>
View
4,990 kinetic-v3.9.8.js
4,990 additions, 0 deletions not shown
Please sign in to comment.
Something went wrong with that request. Please try again.