User:Rillke/SlideRotator.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
Documentation for this user script can be added at User:Rillke/SlideRotator. |
importScript('User:Rillke/blur.js');
function ClsGsCaption(img, left, top, maxheight, maxwidth, minheight, minwidth, blurradius, html, padding) {
if ('string' === typeof img) img = $(img);
if ('object' === typeof img && !$.isArray(img)) img = $(img);
img = img.eq(0);
var wrapperID = 'cbWS' + Math.round(Math.random()*65536);
var oldImgStyle = img.attr('style');
var $wrapperSpan = $('<span>', { style: oldImgStyle, id: wrapperID }).css('position', 'relative').css('display', 'inline-block');
img.data('oldStyle', oldImgStyle);
img.attr('style', '');
img.wrap($wrapperSpan);
$wrapperSpan = img.parent();
if (!$wrapperSpan.length) $wrapperSpan = $('#' + wrapperID);
var $imgClone = img.clone().attr('id', Math.round(Math.random()*65536));
var $imgCloneWrap = $('<span>').append($imgClone);
$imgCloneWrap.css('left', (-1*left) + 'px').css('top', (-1*top) + 'px').css('position', 'absolute').css('display', 'inline-block');
var $textDiv = $('<div>', { style: 'overflow:hidden; position:absolute;', html: html }).css('left', left + 'px').css('top', top + 'px');
if (maxheight) $textDiv.css('max-height', maxheight);
if (maxwidth) $textDiv.css('max-width', maxwidth);
if (minheight) $textDiv.css('min-height', minheight);
if (minwidth) $textDiv.css('min-width', minwidth);
var $viewWindow = $('<div>', { style: 'overflow:hidden; position:absolute;' }).css('left', left + 'px').css('top', top + 'px').append($imgCloneWrap);
var $colorWindow = $('<div>', { style: 'overflow:hidden; position:absolute;' }).css('left', left + 'px').css('top', top + 'px').text(' ');
$wrapperSpan.append($viewWindow, $colorWindow, $textDiv);
if (blurradius) $imgClone.blurRadius(blurradius);
this.rTimeout = 0;
// Finally save all the things we need later
this.$viewWindow = $viewWindow;
this.$colorWindow = $colorWindow;
this.$textDiv = $textDiv.css('padding', padding + 'px').css('font-size', '1.0em');
this.$wrapperSpan = $wrapperSpan;
this.$imgCloneWrap = $imgCloneWrap;
this.$imgClone = $imgClone;
this.$img = img;
this.padding = padding;
this.resize(false);
}
ClsGsCaption.prototype.resize = function(async) {
var _this = this;
var maybeResize = function() {
_this.$viewWindow.css('width', _this.$textDiv.width() + _this.padding*2);
_this.$viewWindow.css('height', _this.$textDiv.height() + _this.padding*2);
_this.$colorWindow.css('width', _this.$textDiv.width() + _this.padding*2);
_this.$colorWindow.css('height', _this.$textDiv.height() + _this.padding*2);
};
clearTimeout(this.rTimeout);
if (async) {
this.rTimeout = setTimeout(function() {
maybeResize();
}, 10);
} else {
maybeResize();
}
}
ClsGsCaption.prototype.show = function() {
this.$viewWindow.show();
this.$colorWindow.show();
this.$textDiv.show();
}
ClsGsCaption.prototype.hide = function() {
this.$viewWindow.hide();
this.$colorWindow.hide();
this.$textDiv.hide();
}
ClsGsCaption.prototype.remove = function() {
this.$img.attr('style', this.$img.data('oldStyle'));
this.$img.siblings().remove();
this.$img.unwrap();
}
ClsGsCaption.prototype.html = function(html) {
if (html) this.$textDiv.html(html);
this.resize(false);
return this.$textDiv.html();
}
ClsGsCaption.prototype.moveTo = function(top, left, duration, callback) {
this.$viewWindow.animate({
top: top,
left: left
}, duration);
this.$colorWindow.animate({
top: top,
left: left
}, duration);
this.$textDiv.animate({
top: top,
left: left
}, duration);
this.$imgCloneWrap.animate({
top: -1*top,
left: -1*left
}, duration, callback);
}
ClsGsCaption.prototype.width = function() {
return this.$textDiv.width();
}
ClsGsCaption.prototype.height = function() {
return this.$textDiv.height();
}
ClsGsCaption.prototype.blurRadius = function(radius) {
if (radius) this.$imgClone.blurRadius(radius);
}
ClsGsCaption.prototype.formCSS = function(name, value) {
this.$textDiv.css(name, value);
this.$viewWindow.css(name, value);
this.$colorWindow.css(name, value);
}
ClsGsCaption.prototype.formCSSO = function(obj) {
this.$textDiv.css(obj);
this.$viewWindow.css(obj);
this.$colorWindow.css(obj);
}
ClsGsCaption.prototype.background = function(value) {
this.$colorWindow.css('background', value);
}
ClsGsCaption.prototype.fadeColorTo = function(duration, opacity, callback) {
this.$colorWindow.fadeTo(duration, opacity, callback);
}
ClsGsCaption.prototype.fadeBlurTo = function(duration, opacity, callback) {
this.$viewWindow.fadeTo(duration, opacity, callback);
}
ClsGsCaption.prototype.fadeTextTo = function(duration, opacity, callback) {
this.$textDiv.fadeTo(duration, opacity, callback);
}
ClsGsCaption.prototype.materialize = function(color, opacity, blurradius) {
var _this = this;
if (!blurradius) blurradius = 7;
_this.$colorWindow.fadeTo(0, 0);
_this.$textDiv.animate({
left: '+=' + 20,
opacity: '-=' + 1
}, 0);
_this.$colorWindow.css('background', color);
var animateText = function() {
_this.blurRadius(Math.round(blurradius / 2));
_this.$textDiv.animate({
left: '-=' + 20,
opacity: '+=' + 1
}, 1000, undefined, _this.blurRadius(blurradius));
};
_this.$colorWindow.fadeTo(1700, opacity, animateText);
}
$(document).ready(function() {
var ClsSlide = function(file, input, ii) {
this.file = file;
this.input = input;
this.ii = ii;
};
$('div.SlideRotator').each(function (ix, el) {
var $el = $(el);
var slides = $el.nextUntil('div.SlideRotatorE', 'p');
// Fixed width now.
var width = $el.width();
$el.css('width', width + 'px');
// Calculating height if a ratio is provided
var ratio = $el.find('.ratio-H-to-W').text();
if (ratio) $el.css('height', width * ratio + 'px');
var titles = [];
var templateSlideData = [];
var slidesByFile = {};
slides.each(function(i, p) {
$p = $(p);
var fileSrc = 'File:' + $p.find('.srs-file').text().replace(/^File:/, '');
titles.push( fileSrc );
templateSlideData.push( { caption: { text: ($p.find('.srs-caption').html() || 'No caption-text present!')
, positioning: ($p.find('.srs-caption-position').text() || 'left')
, maxHeight: ($p.find('.srs-caption-maxHeight').text() || '200px')
, maxWidth: ($p.find('.srs-caption-maxWidth').text() || '150px')
, minHeight: ($p.find('.srs-caption-minHeight').text() || '0px')
, minWidth: ($p.find('.srs-caption-minWidth').text() || '0px')
, color: ($p.find('.srs-caption-color').text() || '#fff')
, opacity: ($p.find('.srs-caption-opacity').text() || 0.6)
, blurRadius: ($p.find('.srs-caption-blurRadius').text() || 7)
}, image: { title: fileSrc
, vPosition: ($p.find('.srs-vPosition').text() || 'center')
}
});
});
var gotImageDimensions = function(result) {
// Process result and build container
var pg, pgs, arrpos, arrlen, title;
pgs = result.query.pages;
arrlen = titles.length;
for (var i = 0; i < arrlen; i++ ) {
title = titles[i];
for (var pid in pgs) {
pg = pgs[pid];
if (pg.title === title) {
slidesByFile[pg.title + '|' + i] = new ClsSlide(pg.title, templateSlideData[i], pg.imageinfo[0]);
}
}
}
var $img, sl, $imgContainerDiv, currentObj, previousObj, nextObj;
for (var slid in slidesByFile) {
sl = slidesByFile[slid];
$img = $('<img>', { height: sl.ii.thumbheight, width: sl.ii.thumbwidth }).data('myParent', sl).load(function() {
myParent = $(this).data('myParent');
myParent.loaded = true;
if (myParent.cb) myParent.cb();
}).attr('src', sl.ii.thumburl);
sl.imgTopPosition = ('center' === sl.input.image.vPosition) ? (($el.height() - sl.ii.thumbheight) /2) : sl.input.image.vPosition;
$imgContainerDiv = $('<div>', { style: 'position:absolute; top:' + ( sl.imgTopPosition ) + 'px; overflow:hidden; display:none;' }).append($('<span>', { style: 'width: 100%, height:100%' }).append($img)).appendTo($el);
sl.$img = $img;
sl.$imgContainerDiv = $imgContainerDiv;
}
var offset = arrlen - 1, oldOffset = 0;
var exposeObjects = function() {
currentObj = slidesByFile[titles[offset] + '|' + offset];
goNext(true);
nextObj = slidesByFile[titles[offset] + '|' + offset];
goPrev(true); goPrev(true);
previousObj = slidesByFile[titles[offset] + '|' + offset];
goNext(true);
};
var goNext = function(noExpose) {
if (!noExpose) oldOffset = offset;
offset++;
offset = offset % arrlen;
if (!noExpose) exposeObjects();
};
var goPrev = function(noExpose) {
if (!noExpose) oldOffset = offset;
offset--;
offset = offset % arrlen;
offset = (offset < 0) ? arrlen + offset : offset;
if (!noExpose) exposeObjects();
};
var goTo = function(n, noExpose) {
if (!noExpose) oldOffset = offset;
offset = n % arrlen;
offset = (offset < 0) ? arrlen - offset : offset;
if (!noExpose) exposeObjects();
};
var removeCaption = function(obj) {
if (obj && obj.capt) {
obj.capt.remove();
obj.capt = undefined;
}
};
var doTransition = function(complete) {
currentObj.$imgContainerDiv.show().animate({
left: '0'
}, {
duration: 1000,
complete: function() {
// Remove the captions
removeCaption(currentObj);
removeCaption(nextObj);
removeCaption(previousObj);
if (nextObj) {
nextObj.$imgContainerDiv.show();
nextObj.$imgContainerDiv.css('left', width + 'px');
}
if (previousObj) {
previousObj.$imgContainerDiv.show();
previousObj.$imgContainerDiv.css('left', (-1 * width) + 'px');
}
if (complete) complete();
},
step: function() {
// Adjust position of the previous and following slides
// in case the show was moved forward, oldOffset is smaller than offset and vice versa
if (previousObj) previousObj.$imgContainerDiv.css('left', (currentObj.$imgContainerDiv.position().left - width) + 'px');
}
});
};
goNext();
var createCaption = function () {
if (currentObj.capt) return;
setTimeout(function() {
var capt = currentObj.capt = new ClsGsCaption( currentObj.$img,
0, //-1*hPos + 15
-1*currentObj.imgTopPosition, // -1*top + 15
currentObj.input.caption.maxHeight,
currentObj.input.caption.maxWidth,
currentObj.input.caption.minHeight,
currentObj.input.caption.minWidth,
0,
currentObj.input.caption.text,
5
);
capt.formCSSO({
'-webkit-border-top-right-radius': '12px',
'-webkit-border-bottom-right-radius': '12px',
'-moz-border-radius-topright': '12px',
'-moz-border-radius-bottomright': '12px',
'border-top-right-radius': '12px',
'border-bottom-right-radius': '12px'
});
capt.materialize(currentObj.input.caption.color, currentObj.input.caption.opacity, currentObj.input.caption.blurRadius);
// setTimeout(function() { capt.remove(); console.log('done') }, 8000);
}, 300);
};
// Now replace the load-container with images.
var init = function() {
$el.find('.srLoader').fadeOut();
doTransition(createCaption);
};
if (currentObj.loaded) {
init();
} else {
currentObj.cb = init;
}
setInterval(function() {
goNext();
doTransition(createCaption);
}, 10000);
};
// Query information from API
var params = { 'format': 'json'
,'action': 'query'
,'prop': 'imageinfo'
,'titles': titles.join('|')
,'iiprop': 'url'
,'iiurlwidth': width
// Set max-height to prevent too big images. Users should crop and upload a new one in this case
,'iiurlheight': $el.height() * 8
};
$.ajax({
url: mw.util.wikiScript('api'),
data: params,
dataType: 'json',
error: function(x, t, s) {
if (window.console && console.log) {
console.log('Error:');
console.log(t);
}
},
success: gotImageDimensions,
type: 'GET',
cache: true
});
});
}); // $(document).ready