You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.3 KiB
JavaScript
201 lines
5.3 KiB
JavaScript
/******
|
|
*
|
|
*
|
|
* @constructor
|
|
*/
|
|
clippy.Balloon = function (targetEl) {
|
|
this._targetEl = targetEl;
|
|
|
|
this._hidden = true;
|
|
this._setup();
|
|
};
|
|
|
|
clippy.Balloon.prototype = {
|
|
|
|
WORD_SPEAK_TIME:200,
|
|
CLOSE_BALLOON_DELAY:2000,
|
|
|
|
_setup:function () {
|
|
|
|
this._balloon = $('<div class="clippy-balloon"><div class="clippy-tip"></div><div class="clippy-content"></div></div> ').hide();
|
|
this._content = this._balloon.find('.clippy-content');
|
|
|
|
$(document.body).append(this._balloon);
|
|
},
|
|
|
|
reposition:function () {
|
|
var sides = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
|
|
for (var i = 0; i < sides.length; i++) {
|
|
var s = sides[i];
|
|
this._position(s);
|
|
if (!this._isOut()) break;
|
|
}
|
|
},
|
|
|
|
_BALLOON_MARGIN:15,
|
|
|
|
/***
|
|
*
|
|
* @param side
|
|
* @private
|
|
*/
|
|
_position:function (side) {
|
|
var o = this._targetEl.offset();
|
|
var h = this._targetEl.height();
|
|
var w = this._targetEl.width();
|
|
o.top -= $(window).scrollTop();
|
|
o.left -= $(window).scrollLeft();
|
|
|
|
var bH = this._balloon.outerHeight();
|
|
var bW = this._balloon.outerWidth();
|
|
|
|
this._balloon.removeClass('clippy-top-left');
|
|
this._balloon.removeClass('clippy-top-right');
|
|
this._balloon.removeClass('clippy-bottom-right');
|
|
this._balloon.removeClass('clippy-bottom-left');
|
|
|
|
var left, top;
|
|
switch (side) {
|
|
case 'top-left':
|
|
// right side of the balloon next to the right side of the agent
|
|
left = o.left + w - bW;
|
|
top = o.top - bH - this._BALLOON_MARGIN;
|
|
break;
|
|
case 'top-right':
|
|
// left side of the balloon next to the left side of the agent
|
|
left = o.left;
|
|
top = o.top - bH - this._BALLOON_MARGIN;
|
|
break;
|
|
case 'bottom-right':
|
|
// right side of the balloon next to the right side of the agent
|
|
left = o.left;
|
|
top = o.top + h + this._BALLOON_MARGIN;
|
|
break;
|
|
case 'bottom-left':
|
|
// left side of the balloon next to the left side of the agent
|
|
left = o.left + w - bW;
|
|
top = o.top + h + this._BALLOON_MARGIN;
|
|
break;
|
|
}
|
|
|
|
this._balloon.css({top:top, left:left});
|
|
this._balloon.addClass('clippy-' + side);
|
|
},
|
|
|
|
_isOut:function () {
|
|
var o = this._balloon.offset();
|
|
var bH = this._balloon.outerHeight();
|
|
var bW = this._balloon.outerWidth();
|
|
|
|
var wW = $(window).width();
|
|
var wH = $(window).height();
|
|
var sT = $(document).scrollTop();
|
|
var sL = $(document).scrollLeft();
|
|
|
|
var top = o.top - sT;
|
|
var left = o.left - sL;
|
|
var m = 5;
|
|
if (top - m < 0 || left - m < 0) return true;
|
|
if ((top + bH + m) > wH || (left + bW + m) > wW) return true;
|
|
|
|
return false;
|
|
},
|
|
|
|
speak:function (complete, text, hold) {
|
|
this._hidden = false;
|
|
this.show();
|
|
var c = this._content;
|
|
// set height to auto
|
|
c.height('auto');
|
|
c.width('auto');
|
|
// add the text
|
|
c.text(text);
|
|
// set height
|
|
c.height(c.height());
|
|
c.width(c.width());
|
|
c.text('');
|
|
this.reposition();
|
|
|
|
this._complete = complete;
|
|
this._sayWords(text, hold, complete);
|
|
},
|
|
|
|
show:function () {
|
|
if (this._hidden) return;
|
|
this._balloon.show();
|
|
},
|
|
|
|
hide:function (fast) {
|
|
if (fast) {
|
|
this._balloon.hide();
|
|
return;
|
|
}
|
|
|
|
this._hiding = window.setTimeout($.proxy(this._finishHideBalloon, this), this.CLOSE_BALLOON_DELAY);
|
|
},
|
|
|
|
_finishHideBalloon:function () {
|
|
if (this._active) return;
|
|
this._balloon.hide();
|
|
this._hidden = true;
|
|
this._hiding = null;
|
|
},
|
|
|
|
_sayWords:function (text, hold, complete) {
|
|
this._active = true;
|
|
this._hold = hold;
|
|
var words = text.split(/[^\S-]/);
|
|
var time = this.WORD_SPEAK_TIME;
|
|
var el = this._content;
|
|
var idx = 1;
|
|
|
|
|
|
this._addWord = $.proxy(function () {
|
|
if (!this._active) return;
|
|
if (idx > words.length) {
|
|
delete this._addWord;
|
|
this._active = false;
|
|
if (!this._hold) {
|
|
complete();
|
|
this.hide();
|
|
}
|
|
} else {
|
|
el.text(words.slice(0, idx).join(' '));
|
|
idx++;
|
|
this._loop = window.setTimeout($.proxy(this._addWord, this), time);
|
|
}
|
|
}, this);
|
|
|
|
this._addWord();
|
|
|
|
},
|
|
|
|
close:function () {
|
|
if (this._active) {
|
|
this._hold = false;
|
|
} else if (this._hold) {
|
|
this._complete();
|
|
}
|
|
},
|
|
|
|
pause:function () {
|
|
window.clearTimeout(this._loop);
|
|
if (this._hiding) {
|
|
window.clearTimeout(this._hiding);
|
|
this._hiding = null;
|
|
}
|
|
},
|
|
|
|
resume:function () {
|
|
if (this._addWord) {
|
|
this._addWord();
|
|
} else if (!this._hold && !this._hidden) {
|
|
this._hiding = window.setTimeout($.proxy(this._finishHideBalloon, this), this.CLOSE_BALLOON_DELAY);
|
|
}
|
|
}
|
|
|
|
|
|
};
|
|
|