Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #14350 from snowmantw/issue946139
Browse files Browse the repository at this point in the history
Bug 946139 - [LockScreen] Make lockscreen unlocking strategy customizable
  • Loading branch information
snowmantw committed Dec 5, 2013
2 parents 6a20f5a + 71de266 commit 78bb5a9
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 46 deletions.
2 changes: 1 addition & 1 deletion apps/system/index.html
Expand Up @@ -140,7 +140,7 @@

<!-- LockScreen -->
<link rel="stylesheet" type="text/css" href="style/lockscreen/lockscreen.css">
<script defer src="js/lockscreen_slide.js"></script>
<script defer src="/shared/js/lockscreen_slide.js"></script>
<script defer src="js/lockscreen.js"></script>

<!-- PIN Unlocking -->
Expand Down
30 changes: 24 additions & 6 deletions apps/system/js/lockscreen.js
Expand Up @@ -31,17 +31,37 @@ var LockScreen = {
},

/**
* Unlocker want to unlock.
* Unlocker want to trigger the right one.
*/
activateUnlock: function _activateUnlock() {
activateRight: function _activateRight() {
LockScreen._activateUnlock();
},

/**
* Unlocker want to activate the camera.
* Unlocker want to trigger the left one.
*/
activateCamera: function _activateCamera() {
activateLeft: function _activateLeft() {
LockScreen._activateCamera();
},

/**
* Sliding near left and made the state changed.
*
* @param {string} |state| 'normal', 'accelerating'
* @param {string} |statePrev| 'normal', 'accelerating'
*/
nearLeft: function _nearLeft(state, statePrev) {
// Do no-op in this lockscreen.
},

/**
* Sliding near right and made the state changed.
*
* @param {string} |state| 'normal', 'accelerating'
* @param {string} |statePrev| 'normal', 'accelerating'
*/
nearRight: function _nearRight(state, statePrev) {
// Do no-op in this lockscreen.
}
},

Expand Down Expand Up @@ -192,9 +212,7 @@ var LockScreen = {
return;
}
this.ready = true;

this._unlocker = new LockScreenSlide(this.intentionRouter);

this.getAllElements();

this.lockIfEnabled(true);
Expand Down
160 changes: 121 additions & 39 deletions apps/system/js/lockscreen_slide.js → shared/js/lockscreen_slide.js
Expand Up @@ -16,10 +16,13 @@
* and make all stateful objects become instance-able.
*
* @param {LockScreen.intentionRouter} |ir|
* @param {Object} |opts| (Opional) addtional, options that may overwrite the
* default settings.
* The options should follow the default settings above
* @constructor
*/
var LockScreenSlide = function(ir) {
this.initialize(ir);
var LockScreenSlide = function(ir, opts) {
this.initialize(ir, opts);
};

var LockScreenSlidePrototype = {
Expand Down Expand Up @@ -62,6 +65,7 @@
handle: {
// Whether we need to auto extend the handle.
autoExpand: {
accState: 'normal', // In accelerating or not.
accFactorOriginal: 1.0,
accFactor: 1.0, // Accelerate sliding if user's finger crossed.
accFactorMax: 1.3,
Expand All @@ -73,12 +77,30 @@
radius: 28, // The radius of the handle in pixel.
lineWidth: 1.6,
maxWidth: 0, // We need dynamic length here.
towardLeft: false,

// The colors here is the current color, which
// will be alternated with another side's color
// when user dragged across the center.

// If it slide across the boundary to color it.
touchedColor: '0, 170, 204', // RGB
// The intermediate color of touched color.
touchedColorStop: '178, 229, 239'
},

colors: {
left: {
touchedColor: '0, 170, 204',
touchedColorStop: '178, 229, 239'
},

right: {
touchedColor: '0, 170, 204',
touchedColorStop: '178, 229, 239'
}
},

states: {
// Some elements can only be initialized after initialization...
initialized: false,
Expand All @@ -98,6 +120,24 @@
prevX: -1,
deltaX: 0 // Diff from prevX and current X
}

},

// How to get elements.
IDs: {
overlay: 'lockscreen',
area: 'lockscreen-area',
canvas: 'lockscreen-canvas',
areas: {
camera: 'lockscreen-area-camera',
unlock: 'lockscreen-area-unlock'
}
},

// Paths to access the resources.
resources: {
larrow: '/style/lockscreen/images/larrow.png',
rarrow: '/style/lockscreen/images/rarrow.png'
},

// How we communicate with the LockScreen.
Expand All @@ -108,16 +148,45 @@
* Initialize this unlocker strategy.
*
* @param {IntentionRouter} |ir| see LockScreen's intentionRouter.
* @param {Object} |opts| (Opional) addtional, options that may overwrite the
* default settings.
* The options should follow the default settings above
* @this {LockScreenSlide}
*/
LockScreenSlidePrototype.initialize =
function(ir) {
function(ir, opts) {
this.intentionRouter = ir;
if (opts)
this._overwriteSettings(opts);
this._initializeCanvas();
ir.unlockerInitialize();
this.states.initialized = true;
};

/**
* Overwrite settings recursively.
*
* @param {Object} |options|
* @this {LockScreenSlide}
*/
LockScreenSlidePrototype._overwriteSettings =
function(options) {
var iterate = function _iterate(opts, settings) {
for (var property in opts) {
if (opts.hasOwnProperty(property)) {
if ('object' === typeof opts[property]) {
iterate(opts[property], settings[property]);
}
else {
settings[property] = opts[property];
}
}
}
};

iterate(options, this);
};

/**
* The dispatcher. Unlocker would manager all its DOMs individually.
*
Expand All @@ -139,21 +208,9 @@
this._resetArrows();
this._resetHandle();
break;
case 'click':
if (evt.target === this.areas.unlock) {
this.intentionRouter.activateUnlock();
} else if (evt.target === this.areas.camera) {
this.intentionRouter.activateCamera();
}
evt.preventDefault();
break;

case 'touchstart':
if (evt.target === this.areas.unlock) {
this.intentionRouter.activateUnlock();
} else if (evt.target === this.areas.camera) {
this.intentionRouter.activateCamera();
} else if (evt.target === this.area) {
if (evt.target === this.area) {
this._onSlideBegin(this._dpx(evt.touches[0].pageX));
}
evt.preventDefault();
Expand Down Expand Up @@ -193,15 +250,13 @@
LockScreenSlidePrototype._initializeCanvas =
function lss_initializeCanvas() {

this.overlay = document.getElementById('lockscreen');
this.area = document.getElementById('lockscreen-area');
this.canvas = document.getElementById('lockscreen-canvas');
this.areas.camera = document.getElementById('lockscreen-area-camera');
this.areas.unlock = document.getElementById('lockscreen-area-unlock');
this.overlay = document.getElementById(this.IDs.overlay);
this.area = document.getElementById(this.IDs.area);
this.canvas = document.getElementById(this.IDs.canvas);
this.areas.camera = document.getElementById(this.IDs.areas.camera);
this.areas.unlock = document.getElementById(this.IDs.areas.unlock);

this.area.addEventListener('touchstart', this);
this.areas.camera.addEventListener('click', this);
this.areas.unlock.addEventListener('click', this);

// Capture the first overlay change and do the delayed initialization.
this.layout = (ScreenLayout && ScreenLayout.getCurrentLayout) ?
Expand All @@ -212,8 +267,8 @@
this.arrows.right = new Image();
var larrow = this.arrows.left;
var rarrow = this.arrows.right;
larrow.src = '/style/lockscreen/images/larrow.png';
rarrow.src = '/style/lockscreen/images/rarrow.png';
larrow.src = this.resources.larrow;
rarrow.src = this.resources.rarrow;

// XXX: Bet it would be OK while user start to drag the slide.
larrow.onload = (function() {
Expand Down Expand Up @@ -335,15 +390,34 @@
var ctx = this.canvas.getContext('2d');

if (tx > expandSentinelR || tx < expandSentinelL) {
var prevState = this.handle.autoExpand.accState;
this.handle.autoExpand.accState = 'accelerating';
var currentState = this.handle.autoExpand.accState;
var slow = false;
if (isLeft) {
slow = this.states.touch.deltaX > 0;
if (prevState !== currentState)
this.intentionRouter.nearLeft(currentState, prevState);
} else {
slow = this.states.touch.deltaX < 0;
if (prevState !== currentState)
this.intentionRouter.nearRight(currentState, prevState);
}
// TODO: XXX: Where we use the previous 'mtx' ?
mtx = this._accelerateSlide(tx, tx < expandSentinelL, slow);
} else {
var prevState = this.handle.autoExpand.accState;
this.handle.autoExpand.accState = 'normal';
var currentState = this.handle.autoExpand.accState;
if (prevState !== currentState) {
if (isLeft) {
if (prevState !== currentState)
this.intentionRouter.nearLeft(currentState, prevState);
} else {
if (prevState !== currentState)
this.intentionRouter.nearRight(currentState, prevState);
}
}
this.handle.autoExpand.accFactor =
this.handle.autoExpand.accFactorOriginal;
}
Expand Down Expand Up @@ -399,8 +473,8 @@
if (false === this.states.slideReachEnd) {
this._bounceBack(this.states.touch.pageX, bounceEnd);
} else {
var intention = isLeft ? this.intentionRouter.activateCamera :
this.intentionRouter.activateUnlock;
var intention = isLeft ? this.intentionRouter.activateLeft :
this.intentionRouter.activateRight;
intention();

// Restore it only after screen changed.
Expand Down Expand Up @@ -651,6 +725,24 @@
offset = rw > 0 ? center.x + maxWidth : center.x - maxWidth;
}

var counterclock = false;
if (offset - center.x < 0) {
counterclock = true;
}
var isLeft = counterclock;

if (isLeft && !this.handle.towardLeft) {
this.handle.towardLeft = true;
this.handle.touchedColor = this.colors.left.touchedColor;
this.handle.touchedColorStop = this.colors.left.touchedColorStop;
}

if (!isLeft && this.handle.towardLeft) {
this.handle.towardLeft = false;
this.handle.touchedColor = this.colors.right.touchedColor;
this.handle.touchedColorStop = this.colors.right.touchedColorStop;
}

// 1.5 ~ 0.5 is the right part of a circle.
var startAngle = 1.5 * Math.PI;
var endAngle = 0.5 * Math.PI;
Expand All @@ -673,26 +765,21 @@
// so it's alpha would decrease to zero.
var borderAlpha = 1.0 - fillAlpha;

// From white to covered blue.
// From white to covered color.
strokeStyle = 'rgba(' + this.handle.touchedColorStop +
',' + borderAlpha + ')';

// It's colorful now.
this.states.slidingColorful = true;
} else {

// Has pass the stage of gradient color.
if (true === this.states.slidingColorGradientEnd) {
fillAlpha = 1.0;
var color = this.handle.touchedColor;
} else if (0 === urw) { // Draw as the initial circle.
if (0 === urw) { // Draw as the initial circle.
fillAlpha = 0.0;
var color = '255,255,255';
} else {
fillAlpha = (urw - 15) / GRADIENT_LENGTH;
if (fillAlpha > 1.0) {
fillAlpha = 1.0;
this.states.slidingColorGradientEnd = true;
}
var color = this.handle.touchedColorStop;
}
Expand All @@ -704,11 +791,6 @@
ctx.lineWidth = this.handle.lineWidth;
ctx.strokeStyle = strokeStyle;

var counterclock = false;
if (offset - center.x < 0) {
counterclock = true;
}

// Start to draw it.
// Can't use functions like rect or these individual parts
// would show its borders.
Expand Down

0 comments on commit 78bb5a9

Please sign in to comment.