I am creating a 360 degree canvas app. It works well when there is just one instance, but the problem incurs when trying to invoke multiple instances of the canvas.
I am building from the ticked tooltip plugin example.
How to create a jQuery plugin with methods?
I am wondering if its falling down - because in the plugin I am not doing this.each
-- here is some of the code in a jsfiddle - but its missing image frames
https://jsfiddle.net/mxx67b9m/9/
HTML Example
<canvas data-init="canvas360" id="render1" data-icon-path="images/" width="520" height="520" data-start-frame=0 data-file-count=22 data-file-path="watch1/"></canvas>
JS invoke
$('[data-init="canvas360"]').each(function(index) {
$(this).superView();
});
JQuery Plugin in the works
(function( $ ){
var canvasApp = {
reInit: function(){
this.loaded = 0;//reset
this.render();
this.load360Image(false);
},
setCursor: function(cursor){
document.body.style.cursor = cursor;
},
render: function(){
//load in a new render
this.fileCount = this.el.data("file-count");
this.path = this.el.data("file-path");
this.startFrame = 10;
//create img list
this.imgList = [];
for (i = 1; i <= this.fileCount; i++) {
this.imgList.push(this.path+i+".png");
}
this.totalFrames = this.imgList.length;
},
start: function(element){
var self = this;
console.log(element);
this.el = element;
this.canvas = this.el[0];
if (!this.canvas || !this.canvas.getContext){
return;
}
this.stage = new createjs.Stage(this.canvas);
this.stage.enableMouseOver(true);
this.stage.mouseMoveOutside = true;
createjs.Touch.enable(this.stage);
this.images = [];
this.loaded = 0;
this.currentFrame = 0
this.rotate360Interval;
this.start_x;
this.bg = new createjs.Shape();
this.stage.addChild(this.bg);
this.bmp = new createjs.Bitmap();
this.stage.addChild(this.bmp);
var myTxt = new createjs.Text("HTC One", '24px Ubuntu', "#ffffff");
myTxt.x = myTxt.y =20;
myTxt.alpha = 0.08;
this.stage.addChild(myTxt);
this.setCursor("progress");
this.render();
this.load360Image(true);
// TICKER
createjs.Ticker.addEventListener("tick", function(event){
self.stage.update();
});
createjs.Ticker.setFPS(60);
createjs.Ticker.useRAF = true;
},
load360Image: function(spin) {
var img = new Image();
//img.crossOrigin = "Anonymous";
img.src = this.imgList[this.loaded];
this.img360Loaded(img, spin);
this.images[this.loaded] = img;
},
img360Loaded: function(img, spin){
var that = this;
img.onload = function(event){
that.loaded++;
that.bg.graphics.clear()
that.bg.graphics.beginFill("#222").drawRect(0,0,that.stage.canvas.width * that.loaded/that.totalFrames, that.stage.canvas.height);
that.bg.graphics.endFill();
if(that.loaded==that.totalFrames){
that.start360(spin);
}else{
that.load360Image(spin);
}
}
},
start360: function(spin) {
this.setCursor("none");
// 360 icon
var iconImage = new Image();
//iconImage.crossOrigin = "Anonymous";
iconImage.src = this.el.data("icon-path")+"360.png";
this.iconLoaded(iconImage);
// update-draw
this.update360(0);
if(spin){
this.revolveOnce(function(){
console.log("done");
}, 25);
}
this.setCursor("auto");
},
revolveOnce: function(callback, speed){
var self = this;
// first rotation
this.rotate360Interval = setInterval(function(){
if(self.currentFrame===self.totalFrames-1) {
clearInterval(self.rotate360Interval);
self.addNavigation();
}
self.update360(1);
if(self.currentFrame===self.totalFrames-1) {
callback();
}
}, speed);
},
iconLoaded: function(iconImage) {
var self = this;
iconImage.onload = function(event){
var iconBmp = new createjs.Bitmap();
iconBmp.image = event.target;
iconBmp.x = 20;
iconBmp.y = self.canvas.height - iconBmp.image.height - 20;
self.stage.addChild(iconBmp);
}
},
setFrame: function(newFrame){
this.bmp.image = this.images[newFrame];
},
addNavigation: function() {
var self = this;
this.stage.onMouseOver = function(event) {
self.setCursor("pointer");
}
this.stage.onMouseDown = function(event) {
self.start_x = event.rawX;
self.stage.onMouseMove = self.mouseMoved;
self.stage.onMouseMove = function(event) {
var dx = event.rawX - self.start_x;
var abs_dx = Math.abs(dx);
if(abs_dx>5) {
self.update360(dx/abs_dx);
self.start_x = event.rawX;
}
}
self.stage.onMouseUp = function(event) {
self.stage.onMouseMove = null;
self.stage.onMouseUp = null;
self.setCursor("pointer");
app.changeOnStage(this, self.currentFrame);
}
self.setCursor("w-resize");
}
this.setCursor("auto");
},
update360: function(dir) {
this.currentFrame+=dir;
if(this.currentFrame<0){
this.currentFrame = this.totalFrames-1;
}
else if(this.currentFrame>this.totalFrames-1){
this.currentFrame = 0;
}
this.bmp.image = this.images[this.currentFrame];
}
};
var methods = {
init : function(options) {
canvasApp.start($(this));
},
reInits: function(args) {
canvasApp.reInit($(this));
},
spin : function(speed, callback) {
//console.log("speed", speed);
canvasApp.revolveOnce(function(){
//console.log("REV:: END");
callback("revolution complete");
},speed);
}
};
$.fn.superView = function(methodOrOptions) {
if ( methods[methodOrOptions] ) {
return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
// Default to "init"
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.superView' );
}
};
})(jQuery);
This is as close as I have come..
but its breaking when loading in the images -- only the 2nd canvas appears to render?
https://jsfiddle.net/7a4738jo/23/
html..
<script type="text/javascript" src="https://code.createjs.com/easeljs-0.6.0.min.js"></script>
<canvas id="one" data-init="table" width="465" height="465">1</canvas>
<canvas id="two" data-init="table" width="465" height="465">2</canvas>
js...
(function ($) {
var defaults = {
string1: "hello ",
string2: "world!"
};
var methods = {
init: function (options) {
if (options) {
$.extend(defaults, options);
}
//console.log("defaults", defaults);
methods.start(this);
//console.log(defaults.string1 + defaults.string2);
},
test: function (arg) {
console.log("test: " + arg.args);
console.log("args: " + defaults.string1 + defaults.string2);
},
reInit: function () {
this.loaded = 0; //reset
this.render();
this.load360Image(false);
},
setCursor: function (cursor) {
document.body.style.cursor = cursor;
},
render: function () {
//load in a new render
this.fileCount = this.el.data("file-count");
this.path = this.el.data("file-path");
this.startFrame = 10;
//create img list
this.imgList = [];
/*
for (i = 1; i <= this.fileCount; i++) {
this.imgList.push(this.path + i + ".png");
}*/
this.imgList = ["http://jsrun.it/assets/N/b/D/X/NbDXj.jpg",
"http://jsrun.it/assets/f/K/7/y/fK7yE.jpg",
"http://jsrun.it/assets/j/U/q/d/jUqdG.jpg",
"http://jsrun.it/assets/q/o/4/j/qo4jP.jpg",
"http://jsrun.it/assets/i/Q/e/1/iQe1f.jpg",
"http://jsrun.it/assets/5/k/y/R/5kyRi.jpg",
"http://jsrun.it/assets/x/T/I/h/xTIhA.jpg",
"http://jsrun.it/assets/4/X/G/F/4XGFt.jpg",
"http://jsrun.it/assets/6/7/n/r/67nrO.jpg",
"http://jsrun.it/assets/k/i/r/8/kir8T.jpg",
"http://jsrun.it/assets/2/3/F/q/23Fqt.jpg",
"http://jsrun.it/assets/c/l/d/5/cld59.jpg",
"http://jsrun.it/assets/e/J/O/f/eJOf1.jpg",
"http://jsrun.it/assets/o/j/Z/x/ojZx4.jpg",
"http://jsrun.it/assets/w/K/2/m/wK2m3.jpg",
"http://jsrun.it/assets/w/K/2/m/wK2m3.jpg",
"http://jsrun.it/assets/4/b/g/V/4bgVf.jpg",
"http://jsrun.it/assets/4/m/1/8/4m18z.jpg",
"http://jsrun.it/assets/4/w/b/F/4wbFX.jpg",
"http://jsrun.it/assets/4/k/T/G/4kTGQ.jpg",
"http://jsrun.it/assets/s/n/C/r/snCrr.jpg",
"http://jsrun.it/assets/7/f/H/u/7fHuI.jpg",
"http://jsrun.it/assets/v/S/d/F/vSdFm.jpg",
"http://jsrun.it/assets/m/g/c/S/mgcSp.jpg",
"http://jsrun.it/assets/t/L/t/P/tLtPF.jpg",
"http://jsrun.it/assets/j/7/e/H/j7eHx.jpg",
"http://jsrun.it/assets/m/o/8/I/mo8Ij.jpg",
"http://jsrun.it/assets/n/P/7/h/nP7ht.jpg",
"http://jsrun.it/assets/z/f/K/S/zfKSP.jpg",
"http://jsrun.it/assets/2/3/4/U/234U6.jpg",
"http://jsrun.it/assets/d/Z/y/m/dZymk.jpg"];
this.totalFrames = this.imgList.length;
},
start: function (element) {
var self = this;
console.log(">>>element",element);
this.el = element;
this.canvas = this.el[0];
if (!this.canvas || !this.canvas.getContext) {
return;
}
console.log(">>>methods.canvas",this.canvas);
this.stage = new createjs.Stage(this.canvas);
this.stage.enableMouseOver(true);
this.stage.mouseMoveOutside = true;
createjs.Touch.enable(methods.stage);
this.images = [];
this.loaded = 0;
this.currentFrame = 0
this.rotate360Interval;
this.start_x;
this.bg = new createjs.Shape();
this.stage.addChild(this.bg);
this.bmp = new createjs.Bitmap();
this.stage.addChild(this.bmp);
var myTxt = new createjs.Text("HTC One", '24px Ubuntu', "#ffffff");
myTxt.x = myTxt.y = 20;
myTxt.alpha = 0.08;
this.stage.addChild(myTxt);
this.setCursor("progress");
this.render();
//console.log(this.el[0]);
this.load360Image(true);
// TICKER
createjs.Ticker.addEventListener("tick", function (event) {
self.stage.update();
});
createjs.Ticker.setFPS(60);
createjs.Ticker.useRAF = true;
return this.canvas;
},
load360Image: function (spin) {
var img = new Image();
//img.crossOrigin = "Anonymous";
img.src = this.imgList[this.loaded];
this.img360Loaded(img, spin);
this.images[this.loaded] = img;
},
img360Loaded: function (img, spin) {
//console.log("LOAD IMG", this.el[0], img);
var that = this;
img.onload = function (event) {
//console.log(img);
that.loaded++;
that.bg.graphics.clear()
that.bg.graphics.beginFill("#222").drawRect(0, 0, that.stage.canvas.width * that.loaded / that.totalFrames, that.stage.canvas.height);
that.bg.graphics.endFill();
if (that.loaded == that.totalFrames) {
that.start360(spin);
} else {
that.load360Image(spin);
}
//console.log(">>LOAD IMG DONE", that.el[0]);
}
},
start360: function (spin) {
this.setCursor("none");
// 360 icon
var iconImage = new Image();
//iconImage.crossOrigin = "Anonymous";
iconImage.src = this.el.data("icon-path") + "360.png";
this.iconLoaded(iconImage);
// update-draw
this.update360(0);
if (spin) {
this.revolveOnce(function () {
//console.log("done");
}, 25);
}
this.setCursor("auto");
},
revolveOnce: function (callback, speed) {
var self = this;
// first rotation
this.rotate360Interval = setInterval(function () {
if (self.currentFrame === self.totalFrames - 1) {
clearInterval(self.rotate360Interval);
self.addNavigation();
}
self.update360(1);
if (self.currentFrame === self.totalFrames - 1) {
callback();
}
}, speed);
},
iconLoaded: function (iconImage) {
var self = this;
iconImage.onload = function (event) {
var iconBmp = new createjs.Bitmap();
iconBmp.image = event.target;
iconBmp.x = 20;
iconBmp.y = self.canvas.height - iconBmp.image.height - 70;
self.stage.addChild(iconBmp);
}
},
setFrame: function (newFrame) {
this.bmp.image = this.images[newFrame];
},
addNavigation: function () {
var self = this;
this.stage.onMouseOver = function (event) {
self.setCursor("pointer");
}
this.stage.onMouseDown = function (event) {
self.start_x = event.rawX;
self.stage.onMouseMove = self.mouseMoved;
self.stage.onMouseMove = function (event) {
var dx = event.rawX - self.start_x;
var abs_dx = Math.abs(dx);
if (abs_dx > 5) {
self.update360(dx / abs_dx);
self.start_x = event.rawX;
}
}
self.stage.onMouseUp = function (event) {
self.stage.onMouseMove = null;
self.stage.onMouseUp = null;
self.setCursor("pointer");
core.changeOnStage(this, self.currentFrame);
}
self.setCursor("w-resize");
}
this.setCursor("auto");
},
update360: function (dir) {
this.currentFrame += dir;
if (this.currentFrame < 0) {
this.currentFrame = this.totalFrames - 1;
} else if (this.currentFrame > this.totalFrames - 1) {
this.currentFrame = 0;
}
this.bmp.image = this.images[this.currentFrame];
}
};
$.fn.dataTable = function (method) {
var args = arguments;
var $this = this;
return this.each(function () {
if (methods[method]) {
return methods[method].apply($this, Array.prototype.slice.call(args, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply($this, Array.prototype.slice.call(args, 0));
} else {
$.error('Method ' + method + ' does not exist on jQuery.plugin');
}
});
};
})(jQuery);
// Init
$(document).ready(function () {
//create multiple instances of canvas
$('[data-init="table"]').each(function (index) {
var instance = $(this).dataTable();
console.log("instance", instance);
});
$("#two").dataTable("test", {
args: "test args passed"
});
});
Related
I am trying to make a function which will close my tooltip by 'click' on the parent element which returns me this tooltip by first click on it. Need to get the closing function exclusively for tooltip parent element. Right now everything is working, but i can also close my tooltip by clicking anywhere on body element.
`(function () {
function Tooltip(options) {
if (!options) options = {};
var self = this;
this.tooltips;
this.offset = 5;
this.beforeTooltip = options.beforeTooltip;
this.afterTooltip = options.afterTooltip;
this.tooltipWrapper = document.createElement('div');
this.status = false;
this.tooltip = function (elem) {
if (!elem.classList.contains('active')){
if (this.status) this.remElemActive();
if (this.beforeTooltip) this.beforeTooltip(elem);
elem.classList.add('active');
var coords = this.getCoords(elem);
this.tooltipWrapper.textContent = elem.dataset.tooltip;
this.tooltipWrapper.classList.add('active');
this.tooltipWrapper.style.top = coords.top - (this.tooltipWrapper.offsetHeight + this.offset) + 'px';
this.tooltipWrapper.style.left = (coords.left + coords.width / 2) - (this.tooltipWrapper.offsetWidth / 2) + 'px';
this.status = true;
if (this.status){
setTimeout(function () {
document.addEventListener('click', self.closeTipsBody, false);
}, 100)
}
if (this.afterTooltip) this.afterTooltip(elem)
}else {
elem.classList.remove('active');
}
};
this.closeTipsBody = function (e) {
if (self.tooltipWrapper === e.target || e.target.classList.contains('active')){
return false
}
self.closeTips();
};
this.closeTips = function () {
this.tooltipWrapper.classList.remove('active');
this.remElemActive();
this.status = false;
document.removeEventListener('click', self.closeTipsBody, false)
};
this.remElemActive = function () {
document.querySelector('.tooltip-js').classList.remove('active')
};
this.getCoords = function (elem) {
elem = elem.getBoundingClientRect();
return{
top: elem.top + window.pageYOffset,
left: elem.left + window.pageXOffset,
width: elem.width
}
};
this.init = function () {
document.addEventListener('DOMContentLoaded', function () {
this.tooltips = document.querySelectorAll('.tooltip-js');
this.tooltipWrapper.classList.add('tooltip-box');
document.querySelector('body').appendChild(this.tooltipWrapper);
for (var i = 0; i < this.tooltips.length; i++ ){
this.tooltips[i].addEventListener('click', function (e) {
e.preventDefault();
self.tooltip(this);
})
}
}.bind(this))
};
this.init();
}
window.Tooltip = Tooltip;
})();`
if you need any additional info, about what do i want to get to, text me.
I'm using a jquery plugin called quicksearch within Sharepoint 2010 and it works perfectly. Unfortunately were being forced to migrate onto sharepoint 2013 and it's stopped working. An error is shown saying that the function is undefined. I believe I've narrowed this down to the quicksearch function itself.
Here is the preliminary code:
_spBodyOnLoadFunctionNames.push("Load");
$('[name=search]').on('keyup', function(){
Load();
});
function Load() {
var searchArea = "#cbqwpctl00_ctl22_g_ca6bb172_1ab4_430d_ae38_a32cfa03b56b ul li";
var qs = $('input#id_search_list').val();
qs.quicksearch(searchArea);
$('.filter input').on('change', function(){
checkAndHide()
//$(searchArea).unhighlight();
});
function checkAndHide(){
var inputs = $('.filter input');
var i =0;
for (var i = 0; i < inputs.length; i++){
if (!inputs[i].checked){
$('.' + inputs[i].name).addClass('filter-hide');
} else {
$('.' + inputs[i].name).removeClass('filter-hide');
};
};
};
}
Here is an example of the quicksearch library I'm using:
(function($, window, document, undefined) {
$.fn.quicksearch = function (target, opt) {
var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({
delay: 300,
selector: null,
stripeRows: null,
loader: null,
noResults: 'div#noresults',
bind: 'keyup keydown',
onBefore: function () {
var ar = $('input#id_search_list').val()
if (ar.length > 2) {
var i=0;
var ar2 = $('input#id_search_list').val().split(" ");
for (i = 0; i < ar2.length; i++) {
$(searchArea + ':visible');
}
return true;
}
return false;
checkAndHide()
},
onAfter: function () {
return;
},
show: function () {
this.style.display = "block";
},
hide: function () {
this.style.display = "none";
},
prepareQuery: function (val) {
return val.toLowerCase().split(' ');
},
testQuery: function (query, txt, _row) {
for (var i = 0; i < query.length; i += 1) {
if (txt.indexOf(query[i]) === -1) {
return false;
}
}
return true;
}
}, opt);
this.go = function () {
var i = 0,
noresults = true,
query = options.prepareQuery(val),
val_empty = (val.replace(' ', '').length === 0);
for (var i = 0, len = rowcache.length; i < len; i++) {
if (val_empty) {
options.hide.apply(rowcache[i]);
noresults = false;
} else if (options.testQuery(query, cache[i], rowcache[i])){
options.show.apply(rowcache[i]);
noresults = false;
} else {
options.hide.apply(rowcache[i]);
}
}
if (noresults) {
this.results(false);
} else {
this.results(true);
this.stripe();
}
this.loader(false);
options.onAfter();
return this;
};
this.stripe = function () {
if (typeof options.stripeRows === "object" && options.stripeRows !== null)
{
var joined = options.stripeRows.join(' ');
var stripeRows_length = options.stripeRows.length;
jq_results.not(':hidden').each(function (i) {
$(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
});
}
return this;
};
this.strip_html = function (input) {
var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
output = $.trim(output.toLowerCase());
return output;
};
this.results = function (bool) {
if (typeof options.noResults === "string" && options.noResults !== "") {
if (bool) {
$(options.noResults).hide();
} else {
$(options.noResults).show();
}
}
return this;
};
this.loader = function (bool) {
if (typeof options.loader === "string" && options.loader !== "") {
(bool) ? $(options.loader).show() : $(options.loader).hide();
}
return this;
};
this.cache = function () {
jq_results = $(target);
if (typeof options.noResults === "string" && options.noResults !== "") {
jq_results = jq_results.not(options.noResults);
}
var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults);
cache = t.map(function () {
return e.strip_html(this.innerHTML);
});
rowcache = jq_results.map(function () {
return this;
});
return this.go();
};
this.trigger = function () {
this.loader(true);
if (options.onBefore()) {
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
e.go();
}, options.delay);
}
return this;
};
this.cache();
this.results(true);
this.stripe();
this.loader(false);
return this.each(function () {
$(this).bind(options.bind, function () {
val = $(this).val();
e.trigger();
});
});
};
}(jQuery, this, document));
`
This is where the error comes up:
var qs = $('input#id_search_list').val();
qs.quicksearch(searchArea);
Any help would be appreciated
Turns out was a small issue in the code and major css as sharepoint plays differently in 2013
I use the following codes to preload album images and show a loading bar.
var album1 = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'];
var album2 = ['01.jpg', '02.jpg', '03.jpg', '04.jpg', '05.jpg'];
var total_images = album1.length + album2.length;
var load_count = 0;
$(document).ready(function() {
function preloadImages(list, path) {
var img;
if (!preloadImages.cache) {
preloadImages.cache = [];
}
for (var i = 0; i < list.length; i++) {
img = new Image();
$(img).bind('load', function() {
load_count++;
$('#loading_bar #progress').css('width', Math.round(load_count * 100 / total_images) + '%');
if(load_count >= total_images) {
init_sequence();
}
});
img.src = path + list[i];
preloadImages.cache.push(img);
}
}
preloadImages(album1, 'http://www.example.com/images/path1/');
preloadImages(album2, 'http://www.example.com/images/path2/');
}
The above preloading codes work fine in normal network condition. However when network is unstable, making one of the images unable to load, the function init_sequence() cannot be triggered.
My question is, how can I set a timeout (probably using setTimeout() on above function) in preloading images (e.g. if the preload cannot finish in 30 seconds, load the init_sequence() anyways)?
Additional Information:
In case somebody needs to know the HTML structure, here it is (allow me to show only the <body> part; I have included jQuery for sure):
<body>
<div id="loading_bar">
<div id="progress"></div>
</div>
</body>
and the CSS:
#loading_bar {
position: fixed;
left: 0;
bottom: 0;
height: 5px;
width: 100%;
background-color: #EEE;
}
#loading_bar #progress {
position: relative;
left: 0;
height: 5px;
width: 0;
background-color: #A68029;
}
Just use a timeout variable like below.
var album1 = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'];
var album2 = ['01.jpg', '02.jpg', '03.jpg', '04.jpg', '05.jpg'];
var total_images = album1.length + album2.length;
var load_count = 0;
$(document).ready(function() {
// A flag to check if loading timeout had been reached
var loadTimeout = false;
function preloadImages(list, path) {
var img;
if (!preloadImages.cache) {
preloadImages.cache = [];
}
for (var i = 0; i < list.length; i++) {
img = new Image();
$(img).bind('load', function() {
load_count++;
$('#loading_bar #progress').css('width', Math.round(load_count * 100 / total_images) + '%');
if(load_count >= total_images) {
// If we get this far, then clear the timeout variable
clearTimeout(timeout);
// If the image is loaded after timeout, then do nothing because init_sequence have been called.
if (loadTimeout == false) {
init_sequence();
}
}
});
img.src = path + list[i];
preloadImages.cache.push(img);
}
}
// Set timeout for 30 seconds
var timeout = setTimeout(function() {
loadTimeout = true;
init_sequence();
}, 30000);
preloadImages(album1, 'http://www.example.com/images/path1/');
preloadImages(album2, 'http://www.example.com/images/path2/');
}
var initialized = false;
function init_sequence(){
if (initialized)
return;
initialized = true;
//...
}
setTimeout(init_sequence, 30000);
Well in my case it would be something like this (or I'd use promises instead of observers), I like to be oo... But I don't think this is acceptable for you ;-)
var Observer = function (){
this.listeners = {};
};
Observer.prototype = {
constructor: Observer,
register: function (type){
this.listeners[type] = [];
},
on: function (type, callback){
this.listeners[type].push(callback);
},
off: function (type){
this.listeners[type].length = 0;
},
trigger: function (type){
var args = Array.prototype.slice.call(arguments, 1);
var listeners = this.listeners[type];
for (var i=0, l=listeners.length; i<l; ++i){
var listener = listeners[i];
}
}
};
var Map = function (){
this.data = {};
};
Map.prototype = {
constructor: Map,
length: 0,
set: function (key, value){
if (!this.has(key))
++this.length;
this.data[key] = value;
},
has: function (key){
return this.data.hasOwnProperty(key);
},
get: function (key){
if (this.has(key))
return this.data[key];
},
remove: function (key){
if (this.has(key))
--this.length;
delete(this.data[key]);
},
each: function (callback){
for (var key in this.data)
if (this.has(key))
callback(this.get(key), key);
}
};
var ImagePreloader = function (){
this.loaded = new Map();
this.loading = new Map();
this.observer = new Observer();
this.observer.register("progress");
this.observer.register("complete");
};
ImagePreloader.prototype = {
constructor: ImagePreloader,
on: function (type, callback){
this.observer.on(type, callback);
},
off: function (type){
this.observer.off(type);
},
trigger: function (type){
this.observer.trigger.apply(this.observer, arguments);
},
percent: function (){
var totalCount = this.loading.length + this.loaded.length;
if (!totalCount)
return 0;
return Math.round(100 * this.loading.length / totalCount);
},
load: function (url){
if (this.loading.has(url) || this.loaded.has(url))
return;
var image = new Image();
this.loading.set(url, image);
$(image).bind("load", function() {
this.success(url);
}.bind(this));
image.src = url;
this.progress();
},
success: function (url){
var image = this.loading.get(url);
this.loading.remove(url);
this.loaded.set(url, image);
this.progress();
},
progress: function (){
var percent = this.percent();
this.observer.trigger("progress", percent);
if (percent == 100)
this.observer.trigger("complete");
}
}
var ProgressBar = function (){
};
ProgressBar.prototype = {
constructor: ProgressBar,
$el: null,
percent: 0,
setElement: function (el){
this.$el = $(el);
},
setProgress: function (percent){
this.percent = percent;
},
render: function (){
if (!this.$el)
return;
this.$el.css("width", this.percent + "%");
}
};
var Album = function (baseUrl, pathes){
this.baseUrl = baseUrl || "/";
this.images = new Map();
if (pathes)
this.pushAll(pathes);
};
Album.prototype = {
constructor: Album,
length: 0,
pushAll: function (pathes){
for (var i=0, l=pathes.length; i<l; ++i)
this.push(images[i]);
},
push: function (path){
var url = baseUrl + path;
this.images.set(path, url);
this.length = this.images.length;
},
each: function (callback){
this.images.each(callback);
}
};
var Main = {
run: function (){
var albums = this.createAlbums();
this.preloadAlbums(albums, this.renderAlbums.bind(this));
},
createAlbums: function (){
var albums = new Map();
albums.set("album1", new Album(
'http://www.example.com/images/path1/',
['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg']
));
albums.set("album2", new Album(
'http://www.example.com/images/path2/',
['01.jpg', '02.jpg', '03.jpg', '04.jpg', '05.jpg']
));
return albums;
},
preloadAlbums: function (albums, complete){
var timeoutSeconds = 30;
var progressBar = new ProgressBar();
$(document).ready(function() {
progressBar.setElement('#loading_bar #progress');
});
var preloader = new ImagePreloader();
preloader.on("progress", function (percent){
progressBar.setProgress(percent);
progressBar.render();
});
preloader.on("complete", function (){
preloader.off("complete");
complete(albums);
});
albums.each(function (album){
album.each(function (url){
preloader.load(url);
});
});
setTimeout(function (){
preloader.trigger("complete");
}, timeoutSeconds * 1000);
},
renderAlbums: function (albums){
init_sequence();
}
};
Main.run();
Btw. I don't think you have to wait until ready to start preloading images...
I know very little about Javascript but need to use hammer.js in a project I'm working on.
Instead of replacing/refreshing the image im trying to use the pull to refresh scrit to refresh the page.
Ive tried adding
location.reload();
to the script but to no avail, can anyone shed any light on this.
http://eightmedia.github.io/hammer.js/
This is the code im using
/**
* requestAnimationFrame and cancel polyfill
*/
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
/**
* pull to refresh
* #type {*}
*/
var PullToRefresh = (function() {
function Main(container, slidebox, slidebox_icon, handler) {
var self = this;
this.breakpoint = 80;
this.container = container;
this.slidebox = slidebox;
this.slidebox_icon = slidebox_icon;
this.handler = handler;
this._slidedown_height = 0;
this._anim = null;
this._dragged_down = false;
this.hammertime = Hammer(this.container)
.on("touch dragdown release", function(ev) {
self.handleHammer(ev);
});
};
/**
* Handle HammerJS callback
* #param ev
*/
Main.prototype.handleHammer = function(ev) {
var self = this;
switch(ev.type) {
// reset element on start
case 'touch':
this.hide();
break;
// on release we check how far we dragged
case 'release':
if(!this._dragged_down) {
return;
}
// cancel animation
cancelAnimationFrame(this._anim);
// over the breakpoint, trigger the callback
if(ev.gesture.deltaY >= this.breakpoint) {
container_el.className = 'pullrefresh-loading';
pullrefresh_icon_el.className = 'icon loading';
this.setHeight(60);
this.handler.call(this);
}
// just hide it
else {
pullrefresh_el.className = 'slideup';
container_el.className = 'pullrefresh-slideup';
this.hide();
}
break;
// when we dragdown
case 'dragdown':
this._dragged_down = true;
// if we are not at the top move down
var scrollY = window.scrollY;
if(scrollY > 5) {
return;
} else if(scrollY !== 0) {
window.scrollTo(0,0);
}
// no requestAnimationFrame instance is running, start one
if(!this._anim) {
this.updateHeight();
}
// stop browser scrolling
ev.gesture.preventDefault();
// update slidedown height
// it will be updated when requestAnimationFrame is called
this._slidedown_height = ev.gesture.deltaY * 0.4;
break;
}
};
/**
* when we set the height, we just change the container y
* #param {Number} height
*/
Main.prototype.setHeight = function(height) {
if(Modernizr.csstransforms3d) {
this.container.style.transform = 'translate3d(0,'+height+'px,0) ';
this.container.style.oTransform = 'translate3d(0,'+height+'px,0)';
this.container.style.msTransform = 'translate3d(0,'+height+'px,0)';
this.container.style.mozTransform = 'translate3d(0,'+height+'px,0)';
this.container.style.webkitTransform = 'translate3d(0,'+height+'px,0) scale3d(1,1,1)';
}
else if(Modernizr.csstransforms) {
this.container.style.transform = 'translate(0,'+height+'px) ';
this.container.style.oTransform = 'translate(0,'+height+'px)';
this.container.style.msTransform = 'translate(0,'+height+'px)';
this.container.style.mozTransform = 'translate(0,'+height+'px)';
this.container.style.webkitTransform = 'translate(0,'+height+'px)';
}
else {
this.container.style.top = height+"px";
}
};
/**
* hide the pullrefresh message and reset the vars
*/
Main.prototype.hide = function() {
container_el.className = '';
this._slidedown_height = 0;
this.setHeight(0);
cancelAnimationFrame(this._anim);
this._anim = null;
this._dragged_down = false;
};
/**
* hide the pullrefresh message and reset the vars
*/
Main.prototype.slideUp = function() {
var self = this;
cancelAnimationFrame(this._anim);
pullrefresh_el.className = 'slideup';
container_el.className = 'pullrefresh-slideup';
this.setHeight(0);
setTimeout(function() {
self.hide();
}, 500);
};
/**
* update the height of the slidedown message
*/
Main.prototype.updateHeight = function() {
var self = this;
this.setHeight(this._slidedown_height);
if(this._slidedown_height >= this.breakpoint){
this.slidebox.className = 'breakpoint';
this.slidebox_icon.className = 'icon arrow arrow-up';
}
else {
this.slidebox.className = '';
this.slidebox_icon.className = 'icon arrow';
}
this._anim = requestAnimationFrame(function() {
self.updateHeight();
});
};
return Main;
})();
function getEl(id) {
return document.getElementById(id);
}
var container_el = getEl('container');
var pullrefresh_el = getEl('pullrefresh');
var pullrefresh_icon_el = getEl('pullrefresh-icon');
var image_el = getEl('random-image');
var refresh = new PullToRefresh(container_el, pullrefresh_el, pullrefresh_icon_el);
// update image onrefresh
refresh.handler = function() {
var self = this;
// a small timeout to demo the loading state
setTimeout(function() {
var preload = new Image();
preload.onload = function() {
image_el.src = this.src;
self.slideUp();
};
preload.src = 'http://lorempixel.com/800/600/?'+ (new Date().getTime());
}, 1000);
};
There is a Beer involved for anyone that can fix this :)
http://jsfiddle.net/zegermens/PDcr9/1/
You're assigning the return value of the location.reload function to the src attribute of an Image element. I'm not sure if the function even has a return value, https://developer.mozilla.org/en-US/docs/Web/API/Location.reload
Try this:
// update image onrefresh
refresh.handler = function() {
var self = this;
// a small timeout to demo the loading state
setTimeout(function() {
window.location.reload();
}, 1000);
};
This slider works but I just need to preload images:
document.observe("dom:loaded", function(event) {
initSlider()
});
var slider_index = 0;
var auto_scroll = true;
var ctime = false;
function initSlider() {
$('slider-img').src = slider_images[0];
$('slider-text').innerHTML = slider_text[0];
$('slider-link').setAttribute('href',slider_links[0]);
ctime = window.setTimeout(function() {
sliderNext(true);
},7000);
}
function sliderPrev() {
changeSlide(slider_index-1);
clearTimeout(ctime);
}
function sliderNext(scroll) {
if (scroll == true) {
ctime = window.setTimeout(function() {
sliderNext(true);
},21000);
} else {
clearTimeout(ctime);
}
changeSlide(slider_index+1, scroll);
}
function changeSlide(target, auto) {
if (auto) auto_scroll = true; else auto_scroll = false;
if (!auto_scroll) clearTimeout(ctime);
var name = "slider_thumb" + slider_index;
$(name).removeClassName("active");
slider_index = target;
if ( slider_index >= slider_count ) {
slider_index = 0;
} else if ( slider_index < 0 ) {
slider_index = slider_count - 1;
}
$('slider-img').src = slider_images[slider_index];
$('slider-text').innerHTML = slider_text[slider_index];
$('slider-link').setAttribute('href',slider_links[slider_index]);
var name = "slider_thumb" + slider_index;
$(name).addClassName("active");
}
// Preload Image
$('<img />')
.attr('src', 'picture.jpg')
.load(function(){
$('.slider').append( $(this) );
// some other Code
});