!function ($) {
"use strict"; // jshint ;_
/* FILEUPLOAD PUBLIC CLASS DEFINITION
* ================================= */
var Fileupload = function (element, options) {
this.$element = $(element)
this.type = this.$element.data('uploadtype') || (this.$element.find('.thumbnail').length > 0 ? "image" : "file")
this.$input = this.$element.find(':file')
if (this.$input.length === 0) return
this.name = this.$input.attr('name') || options.name
this.$hidden = this.$element.find('input[type=hidden][name="'+this.name+'"]')
if (this.$hidden.length === 0) {
this.$hidden = $('<input type="hidden" />')
this.$element.prepend(this.$hidden)
}
this.$preview = this.$element.find('.fileupload-preview')
var height = this.$preview.css('height')
if (this.$preview.css('display') != 'inline' && height != '0px' && height != 'none') this.$preview.css('line-height', height)
this.original = {
'exists': this.$element.hasClass('fileupload-exists'),
'preview': this.$preview.html(),
'hiddenVal': this.$hidden.val()
}
this.$remove = this.$element.find('[data-dismiss="fileupload"]')
this.$element.find('[data-trigger="fileupload"]').on('click.fileupload', $.proxy(this.trigger, this))
this.listen()
}
Fileupload.prototype = {
listen: function() {
this.$input.on('change.fileupload', $.proxy(this.change, this))
$(this.$input[0].form).on('reset.fileupload', $.proxy(this.reset, this))
if (this.$remove) this.$remove.on('click.fileupload', $.proxy(this.clear, this))
},
change: function(e, invoked) {
if (invoked === 'clear') return
var file = e.target.files !== undefined ? e.target.files[0] : (e.target.value ? { name: e.target.value.replace(/^.+\\/, '') } : null)
if (!file) {
this.clear()
return
}
this.$hidden.val('')
this.$hidden.attr('name', '')
this.$input.attr('name', this.name)
if (this.type === "image" && this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
var reader = new FileReader()
var preview = this.$preview
var element = this.$element
reader.onload = function(e) {
preview.html('<img src="' + e.target.result + '" ' + (preview.css('max-height') != 'none' ? 'style="max-height: ' + preview.css('max-height') + ';"' : '') + ' />')
element.addClass('fileupload-exists').removeClass('fileupload-new')
}
reader.readAsDataURL(file)
} else {
this.$preview.text(file.name)
this.$element.addClass('fileupload-exists').removeClass('fileupload-new')
}
},
clear: function(e) {
this.$hidden.val('')
this.$hidden.attr('name', this.name)
this.$input.attr('name', '')
//ie8+ doesn't support changing the value of input with type=file so clone instead
if (navigator.userAgent.match(/msie/i)){
var inputClone = this.$input.clone(true);
this.$input.after(inputClone);
this.$input.remove();
this.$input = inputClone;
}else{
this.$input.val('')
}
this.$preview.html('')
this.$element.addClass('fileupload-new').removeClass('fileupload-exists')
if (e) {
this.$input.trigger('change', [ 'clear' ])
e.preventDefault()
}
},
reset: function(e) {
this.clear()
this.$hidden.val(this.original.hiddenVal)
this.$preview.html(this.original.preview)
if (this.original.exists) this.$element.addClass('fileupload-exists').removeClass('fileupload-new')
else this.$element.addClass('fileupload-new').removeClass('fileupload-exists')
},
trigger: function(e) {
this.$input.trigger('click')
e.preventDefault()
}
}
/* FILEUPLOAD PLUGIN DEFINITION
* =========================== */
$.fn.fileupload = function (options) {
return this.each(function () {
var $this = $(this)
, data = $this.data('fileupload')
if (!data) $this.data('fileupload', (data = new Fileupload(this, options)))
if (typeof options == 'string') data[options]()
})
}
$.fn.fileupload.Constructor = Fileupload
/* FILEUPLOAD DATA-API
* ================== */
$(document).on('click.fileupload.data-api', '[data-provides="fileupload"]', function (e) {
var $this = $(this)
if ($this.data('fileupload')) return
$this.fileupload($this.data())
var $target = $(e.target).closest('[data-dismiss="fileupload"],[data-trigger="fileupload"]');
if ($target.length > 0) {
$target.trigger('click.fileupload')
e.preventDefault()
}
})
}(window.jQuery);
I am using this js for upload file. with it i can upload and preview only one file but i want to upload multiple file with preview anyone can help me to make it for multiple file upload .
i wanna upload multiple file within a time with preview.
see this example.
<div id="mulitplefileuploader">Upload</div>
<div id="status"></div>
<script>
$(document).ready(function()
{
var settings = {
url: "upload.php",
method: "POST",
allowedTypes:"jpg,png,gif,doc,pdf,zip",
fileName: "myfile",
multiple: true,
onSuccess:function(files,data,xhr)
{
$("#status").html("<font color='green'>Upload is success</font>");
},
afterUploadAll:function()
{
alert("all images uploaded!!");
},
onError: function(files,status,errMsg)
{
$("#status").html("<font color='red'>Upload is Failed</font>");
}
}
$("#mulitplefileuploader").uploadFile(settings);
});
</script>
//php code
$output_dir = "./uploads/";
if(isset($_FILES["myfile"]))
{
$ret = array();
$error =$_FILES["myfile"]["error"];
{
if(!is_array($_FILES["myfile"]['name'])) //single file
{
$RandomNum = time();
$ImageName = $_FILES['myfile']['name'];
$ImageType = $_FILES['myfile']['type']; //"image/png", image/jpeg etc.
if (is_dir($output_dir) && is_writable($output_dir)) {
move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir. $ImageName);
//echo "<br> Error: ".$_FILES["myfile"]["error"];
$ret[$ImageName]= $output_dir.$ImageName;
}
else {
echo 'Upload directory is not writable, or does not exist.';
}
}
else
{
$fileCount = count($_FILES["myfile"]['name']);
for($i=0; $i < $fileCount; $i++)
{
$ImageName = $_FILES['myfile']['name'][$i];
$ImageType = $_FILES['myfile']['type'][$i]; //"image/png", image/jpeg etc.
$ret[$ImageName]= $output_dir.$ImageName;
if (is_dir($output_dir) && is_writable($output_dir)) {
move_uploaded_file($_FILES["myfile"]["tmp_name"][$i],$output_dir.$ImageName );
}
else {
echo 'Upload directory is multi not writable, or does not exist.';
}
}
}
}
echo json_encode($ret);
}
//js code
/*!
* jQuery Upload File Plugin
* version: 3.1.2
* #requires jQuery v1.5 or later & form plugin
* Copyright (c) 2013 Ravishanker Kusuma
* http://hayageek.com/
*/
(function(b) {
if (b.fn.ajaxForm == undefined) {
b.getScript("http://malsup.github.io/jquery.form.js")
}
var a = {};
a.fileapi = b("<input type='file'/>").get(0).files !== undefined;
a.formdata = window.FormData !== undefined;
b.fn.uploadFile = function(t) {
var r = b.extend({
url: "",
method: "POST",
enctype: "multipart/form-data",
formData: null,
returnType: null,
allowedTypes: "*",
fileName: "file",
formData: {},
dynamicFormData: function() {
return {}
},
maxFileSize: -1,
maxFileCount: -1,
multiple: true,
dragDrop: true,
autoSubmit: true,
showCancel: true,
showAbort: true,
showDone: true,
showDelete: false,
showError: true,
showStatusAfterSuccess: true,
showStatusAfterError: true,
showFileCounter: true,
fileCounterStyle: "). ",
showProgress: false,
onSelect: function(s) {
return true
},
onSubmit: function(s, u) {},
onSuccess: function(u, s, v) {},
onError: function(v, s, u) {},
deleteCallback: false,
afterUploadAll: false,
uploadButtonClass: "upload",
dragDropStr: "<span><b>Drag & Drop Files</b></span>",
abortStr: "Abort",
cancelStr: "Cancel",
deletelStr: "Delete",
doneStr: "Done",
multiDragErrorStr: "Multiple File Drag & Drop is not allowed.",
extErrorStr: "is not allowed. Allowed extensions: ",
sizeErrorStr: "is not allowed. Allowed Max size: ",
uploadErrorStr: "Upload is not allowed",
maxFileCountErrorStr: " is not allowed. Maximum allowed files are:"
}, t);
this.fileCounter = 1;
this.selectedFiles = 0;
this.fCounter = 0;
this.sCounter = 0;
this.tCounter = 0;
var d = "upload-" + (new Date().getTime());
this.formGroup = d;
this.hide();
this.errorLog = b("<div></div>");
this.after(this.errorLog);
this.responses = [];
if (!a.formdata) {
r.dragDrop = false
}
if (!a.formdata) {
r.multiple = false
}
var m = this;
var e = b("<div>" + b(this).html() + "</div>");
b(e).addClass(r.uploadButtonClass);
(function k() {
if (b.fn.ajaxForm) {
if (r.dragDrop) {
var s = b('<div class="ajax-upload-dragdrop" style="vertical-align:top;"></div>');
b(m).before(s);
b(s).append(e);
b(s).append(b(r.dragDropStr));
f(m, r, s)
} else {
b(m).before(e)
}
q(m, d, r, e)
} else {
window.setTimeout(k, 10)
}
})();
this.startUpload = function() {
b("." + this.formGroup).each(function(u, s) {
if (b(this).is("form")) {
b(this).submit()
}
})
};
this.stopUpload = function() {
b(".upload-red").each(function(u, s) {
if (b(this).hasClass(m.formGroup)) {
b(this).click()
}
})
};
this.getResponses = function() {
return this.responses
};
var g = false;
function j() {
if (r.afterUploadAll && !g) {
g = true;
(function s() {
if (m.sCounter != 0 && (m.sCounter + m.fCounter == m.tCounter)) {
r.afterUploadAll(m);
g = false
} else {
window.setTimeout(s, 100)
}
})()
}
}
function f(w, u, v) {
v.on("dragenter", function(s) {
s.stopPropagation();
s.preventDefault();
b(this).css("border", "2px solid #000000")
});
v.on("dragover", function(s) {
s.stopPropagation();
s.preventDefault()
});
v.on("drop", function(x) {
b(this).css("border", "2px solid #000000");
x.preventDefault();
w.errorLog.html("");
var s = x.originalEvent.dataTransfer.files;
if (!u.multiple && s.length > 1) {
if (u.showError) {
b("<div style='color:red;'>" + u.multiDragErrorStr + "</div>").appendTo(w.errorLog)
}
return
}
if (u.onSelect(s) == false) {
return
}
l(u, w, s)
});
b(document).on("dragenter", function(s) {
s.stopPropagation();
s.preventDefault()
});
b(document).on("dragover", function(s) {
s.stopPropagation();
s.preventDefault();
v.css("border", "2px solid #000000")
});
b(document).on("drop", function(s) {
s.stopPropagation();
s.preventDefault();
v.css("border", "2px solid #000000")
})
}
function i(s) {
var v = "";
var u = s / 1024;
if (parseInt(u) > 1024) {
var w = u / 1024;
v = w.toFixed(2) + " MB"
} else {
v = u.toFixed(2) + " KB"
}
return v
}
function o(x) {
var y = [];
if (jQuery.type(x) == "string") {
y = x.split("&")
} else {
y = b.param(x).split("&")
}
var u = y.length;
var s = [];
var w, v;
for (w = 0; w < u; w++) {
y[w] = y[w].replace(/\+/g, " ");
v = y[w].split("=");
s.push([decodeURIComponent(v[0]), decodeURIComponent(v[1])])
}
return s
}
function l(H, B, u) {
for (var C = 0; C < u.length; C++) {
if (!c(B, H, u[C].name)) {
if (H.showError) {
b("<div style='color:red;'><b>" + u[C].name + "</b> " + H.extErrorStr + H.allowedTypes + "</div>").appendTo(B.errorLog)
}
continue
}
if (H.maxFileSize != -1 && u[C].size > H.maxFileSize) {
if (H.showError) {
b("<div style='color:red;'><b>" + u[C].name + "</b> " + H.sizeErrorStr + i(H.maxFileSize) + "</div>").appendTo(B.errorLog)
}
continue
}
if (H.maxFileCount != -1 && B.selectedFiles >= H.maxFileCount) {
if (H.showError) {
b("<div style='color:red;'><b>" + u[C].name + "</b> " + H.maxFileCountErrorStr + H.maxFileCount + "</div>").appendTo(B.errorLog)
}
continue
}
B.selectedFiles++;
var D = H;
var w = new FormData();
var A = H.fileName.replace("[]", "");
w.append(A, u[C]);
var y = H.formData;
if (y) {
var F = o(y);
for (var z = 0; z < F.length; z++) {
if (F[z]) {
w.append(F[z][0], F[z][1])
}
}
}
D.fileData = w;
var E = new p(B, H);
var G = "";
if (H.showFileCounter) {
G = B.fileCounter + H.fileCounterStyle + u[C].name
} else {
G = u[C].name
}
E.filename.html(G);
var v = b("<form style='display:block; position:absolute;left: 150px;' class='" + B.formGroup + "' method='" + H.method + "' action='" + H.url + "' enctype='" + H.enctype + "'></form>");
v.appendTo("body");
var x = [];
x.push(u[C].name);
n(v, D, E, x, B);
B.fileCounter++
}
}
function c(w, v, y) {
var x = v.allowedTypes.toLowerCase().split(",");
var u = y.split(".").pop().toLowerCase();
if (v.allowedTypes != "*" && jQuery.inArray(u, x) < 0) {
return false
}
return true
}
function h(u, w) {
if (u.showFileCounter) {
var v = b(".upload-filename").length;
w.fileCounter = v + 1;
b(".upload-filename").each(function(A, y) {
var s = b(this).html().split(u.fileCounterStyle);
var x = parseInt(s[0]) - 1;
var z = v + u.fileCounterStyle + s[1];
b(this).html(z);
v--
})
}
}
function q(y, B, D, u) {
var A = "ajax-upload-id-" + (new Date().getTime());
var w = b("<form method='" + D.method + "' action='" + D.url + "' enctype='" + D.enctype + "'></form>");
var v = "<input type='file' id='" + A + "' name='" + D.fileName + "'/>";
if (D.multiple) {
if (D.fileName.indexOf("[]") != D.fileName.length - 2) {
D.fileName += "[]"
}
v = "<input type='file' id='" + A + "' name='" + D.fileName + "' multiple/>"
}
var z = b(v).appendTo(w);
z.change(function() {
y.errorLog.html("");
var K = D.allowedTypes.toLowerCase().split(",");
var G = [];
if (this.files) {
for (H = 0; H < this.files.length; H++) {
G.push(this.files[H].name)
}
if (D.onSelect(this.files) == false) {
return
}
} else {
var I = b(this).val();
var F = [];
G.push(I);
if (!c(y, D, I)) {
if (D.showError) {
b("<div style='color:red;'><b>" + I + "</b> " + D.extErrorStr + D.allowedTypes + "</div>").appendTo(y.errorLog)
}
return
}
F.push({
name: I,
size: "NA"
});
if (D.onSelect(F) == false) {
return
}
}
h(D, y);
u.unbind("click");
w.hide();
q(y, B, D, u);
w.addClass(B);
if (a.fileapi && a.formdata) {
w.removeClass(B);
var J = this.files;
l(D, y, J)
} else {
var E = "";
for (var H = 0; H < G.length; H++) {
if (D.showFileCounter) {
E += y.fileCounter + D.fileCounterStyle + G[H] + "<br>"
} else {
E += G[H] + "<br>"
}
y.fileCounter++
}
if (D.maxFileCount != -1 && (y.selectedFiles + G.length) > D.maxFileCount) {
if (D.showError) {
b("<div style='color:red;'><b>" + E + "</b> " + D.maxFileCountErrorStr + D.maxFileCount + "</div>").appendTo(y.errorLog)
}
return
}
y.selectedFiles += G.length;
var s = new p(y, D);
s.filename.html(E);
n(w, D, s, G, y)
}
});
w.css({
margin: 0,
padding: 0
});
var C = b(u).width() + 10;
if (C == 10) {
C = 120
}
var x = u.height() + 10;
if (x == 10) {
x = 35
}
u.css({
position: "relative",
overflow: "hidden",
cursor: "default"
});
z.css({
position: "absolute",
cursor: "pointer",
top: "0px",
width: C,
height: x,
left: "0px",
"z-index": "100",
opacity: "0.0",
filter: "alpha(opacity=0)",
"-ms-filter": "alpha(opacity=0)",
"-khtml-opacity": "0.0",
"-moz-opacity": "0.0"
});
w.appendTo(u)
}
function p(v, u) {
//console.log(this);
this.statusbar = b("<div class='upload-statusbar'></div>");
this.filename = b("<div class='upload-filename'></div>").appendTo(this.statusbar);
this.progressDiv = b("<div class='upload-progress'>").appendTo(this.statusbar).hide();
this.progressbar = b("<div class='upload-bar " + v.formGroup + "'></div>").appendTo(this.progressDiv);
this.abort = b("<div class='upload-red " + v.formGroup + "'>" + u.abortStr + "</div>").appendTo(this.statusbar).hide();
this.cancel = b("<div class='upload-red'>" + u.cancelStr + "</div>").appendTo(this.statusbar).hide();
this.done = b("<div class='upload-green'>" + u.doneStr + "</div>").appendTo(this.statusbar).hide();
this.del = b("<div class='upload-red'>" + u.deletelStr + "</div>").appendTo(this.statusbar).hide();
v.errorLog.after(this.statusbar);
return this
}
function n(z, y, u, w, A) {
var x = null;
var v = {
cache: false,
contentType: false,
processData: false,
forceSync: false,
data: y.formData,
formData: y.fileData,
dataType: y.returnType,
beforeSubmit: function(F, C, E) {
if (y.onSubmit.call(this, w) != false) {
var B = y.dynamicFormData();
if (B) {
var s = o(B);
if (s) {
for (var D = 0; D < s.length; D++) {
if (s[D]) {
if (y.fileData != undefined) {
E.formData.append(s[D][0], s[D][1])
} else {
E.data[s[D][0]] = s[D][1]
}
}
}
}
}
A.tCounter += w.length;
j();
return true
}
u.statusbar.append("<div style='color:red;'>" + y.uploadErrorStr + "</div>");
u.cancel.show();
z.remove();
u.cancel.click(function() {
u.statusbar.remove()
});
return false
},
beforeSend: function(B, s) {
u.progressDiv.show();
u.cancel.hide();
u.done.hide();
if (y.showAbort) {
u.abort.show();
u.abort.click(function() {
B.abort();
A.selectedFiles -= w.length
})
}
if (!a.formdata) {
u.progressbar.width("5%")
} else {
u.progressbar.width("1%")
}
},
uploadProgress: function(E, s, D, C) {
if (C > 98) {
C = 98
}
var B = C + "%";
if (C > 1) {
u.progressbar.width(B)
}
if (y.showProgress) {
u.progressbar.html(B);
u.progressbar.css("text-align", "center")
}
},
success: function(B, s, C) {
A.responses.push(B);
u.progressbar.width("100%");
if (y.showProgress) {
u.progressbar.html("100%");
u.progressbar.css("text-align", "center")
}
u.abort.hide();
y.onSuccess.call(this, w, B, C);
if (y.showStatusAfterSuccess) {
if (y.showDone) {
u.done.show();
u.done.click(function() {
u.statusbar.hide("slow");
u.statusbar.remove()
})
} else {
u.done.hide()
}
if (y.showDelete) {
u.del.show();
u.del.click(function() {
u.statusbar.hide().remove();
if (y.deleteCallback) {
y.deleteCallback.call(this, B, u)
}
A.selectedFiles -= w.length;
h(y, A)
})
} else {
u.del.hide()
}
} else {
u.statusbar.hide("slow");
u.statusbar.remove()
}
z.remove();
A.sCounter += w.length
},
error: function(C, s, B) {
u.abort.hide();
if (C.statusText == "abort") {
u.statusbar.hide("slow").remove();
h(y, A)
} else {
y.onError.call(this, w, s, B);
if (y.showStatusAfterError) {
u.progressDiv.hide();
u.statusbar.append("<span style='color:red;'>ERROR: " + B + "</span>")
} else {
u.statusbar.hide();
u.statusbar.remove()
}
A.selectedFiles -= w.length
}
z.remove();
A.fCounter += w.length
}
};
if (y.autoSubmit) {
z.ajaxSubmit(v)
} else {
if (y.showCancel) {
u.cancel.show();
u.cancel.click(function() {
z.remove();
u.statusbar.remove();
A.selectedFiles -= w.length;
h(y, A)
})
}
z.ajaxForm(v)
}
}
return this
}
}(jQuery));
Related
I do have slider that outputs a value as text. Now I need also to build an input Textfield that does change the slider value and the slider value change the input Textfield value. I did find couple solutions, but that does not work for me, because I have comparison boxes that work hand in hand, when I try those solutions everything crashes.
Here my code:
// Term Slider
function comparisons_term_slider($settings) {
$term = str_replace('[term]',$settings['terminitial'],$settings['termoutput']);
$term = str_replace('[period]',$settings['plural'],$term);
$output = '<div class="comparisons-range comparisons-slider-term">
<div class="comparisons_slider_output">';
$output .= '<div class="output-pad"><span class="circle-down circle-control"></span><span class="output-number"><label for="loan-term">'.$settings['termlabel'].'</label> <output>'.$term.'</output><span class="circle-up circle-control"></span></div>';
$output .= '</div>
<input type="range" class="loan_term" name="loan-term" id="loan-term" min="'.$settings['termmin'].'" max="'.$settings['termmax'].'" value="'.$settings['terminitial'].'" step="'.$settings['termstep'].'" data-comparisons>
</div>';
return $output;
}
and in javascript
// Select all relevant loan slider forms
$(comparisons_loan_selector).each(function() {
// Initialize sliders
var sliders = $(this).find('[data-comparisons]'), x = $(this);
sliders.change(comparisonsCalculate);
sliders.comparisons({polyfill:false});
$('#lc_show_more').click(function() {
comparisonsShowMore.apply(this);
//comparisonsCalculate;
});
$('#sortby').change(comparisonsCalculate);
// Up and down buttons
x.find('.circle-control').click(function() {
var holder = $(this).closest('.comparisons-range'),
range = holder.find('input'),
newVal = parseFloat(range.val()),
step = parseFloat(range.attr('step')),
min = parseFloat(range.attr('min')),
max = parseFloat(range.attr('max'));
if ($(this).hasClass('circle-down')) { // reduce the slider value
newVal = newVal - step;
if (newVal > min) range.val(newVal);
else range.val(min);
} else { // raise the slider value
newVal = newVal + step;
if (newVal < max) range.val(newVal);
else range.val(max);
}
range.change();
});
// Sliders
jQuery(document).ready(function($) {
(function(factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof exports === 'object') {
factory(require('jquery'));
} else {
factory(jQuery);
}
} (function($) {
'use strict';
function supportsRange() {
var input = document.createElement('input');
input.setAttribute('type', 'range');
return input.type !== 'text';
}
var pluginName = 'comparisons',
pluginInstances = [],
inputrange = supportsRange(),
defaults = {
polyfill: true,
rangeClass: 'comparisons',
disabledClass: 'comparisons--disabled',
fillClass: 'comparisons__fill',
handleClass: 'comparisons__handle',
startEvent: ['mousedown', 'touchstart', 'pointerdown'],
moveEvent: ['mousemove', 'touchmove', 'pointermove'],
endEvent: ['mouseup', 'touchend', 'pointerup']
};
function delay(fn, wait) {
var args = Array.prototype.slice.call(arguments, 2);
return setTimeout(function(){ return fn.apply(null, args); }, wait);
}
function debounce(fn, debounceDuration) {
debounceDuration = debounceDuration || 100;
return function() {
if (!fn.debouncing) {
var args = Array.prototype.slice.apply(arguments);
fn.lastReturnVal = fn.apply(window, args);
fn.debouncing = true;
}
clearTimeout(fn.debounceTimeout);
fn.debounceTimeout = setTimeout(function(){
fn.debouncing = false;
}, debounceDuration);
return fn.lastReturnVal;
};
}
function Plugin(element, options) {
this.$window = $(window);
this.$document = $(document);
this.$element = $(element);
this.options = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.startEvent = this.options.startEvent.join('.' + pluginName + ' ') + '.' + pluginName;
this.moveEvent = this.options.moveEvent.join('.' + pluginName + ' ') + '.' + pluginName;
this.endEvent = this.options.endEvent.join('.' + pluginName + ' ') + '.' + pluginName;
this.polyfill = this.options.polyfill;
this.onInit = this.options.onInit;
this.onSlide = this.options.onSlide;
this.onSlideEnd = this.options.onSlideEnd;
if (this.polyfill) {
if (inputrange) { return false; }
}
this.identifier = 'js-' + pluginName + '-' +(+new Date())+'-'+(pluginInstances.length + 1);
this.min = parseFloat(this.$element[0].getAttribute('min') || 0);
this.max = parseFloat(this.$element[0].getAttribute('max') || 100);
this.value = parseFloat(this.$element[0].value || this.min + (this.max-this.min)/2);
this.step = parseFloat(this.$element[0].getAttribute('step') || 1);
this.$fill = $('<div class="' + this.options.fillClass + '" />');
this.$handle = $('<div class="' + this.options.handleClass + '" />');
this.$range = $('<div class="' + this.options.rangeClass + '" id="' + this.identifier + '" />').insertAfter(this.$element).prepend(this.$fill, this.$handle);
this.$element.css({
'position': 'absolute',
'width': '1px',
'height': '1px',
'overflow': 'hidden',
'opacity': '0'
});
this.handleDown = $.proxy(this.handleDown, this);
this.handleMove = $.proxy(this.handleMove, this);
this.handleEnd = $.proxy(this.handleEnd, this);
this.init();
var _this = this;
this.$window.on('resize' + '.' + pluginName, debounce(function() {
delay(function() { _this.update(); }, 300);
}, 20));
this.$document.on(this.startEvent, '#' + this.identifier + ':not(.' + this.options.disabledClass + ')', this.handleDown);
this.$element.on('change' + '.' + pluginName, function(e, data) {
if (data && data.origin === pluginName) {
return;
}
var value = e.target.value,
pos = _this.getPositionFromValue(value);
_this.setPosition(pos);
});
}
Plugin.prototype.init = function() {
if (this.onInit && typeof this.onInit === 'function') {
this.onInit();
}
this.update();
};
Plugin.prototype.attributes = function() {
var e = this.$element;
this.min = parseFloat(e.attr('min'));
this.max = parseFloat(e.attr('max'));
this.value = parseFloat(e.attr('value'));
if (this.value > this.max) this.setValue(this.max);
if (this.value < this.min) this.setValue(this.min);
if (this.value > this.min && this.value > this.min) this.setValue(this.value);
this.update();
};
Plugin.prototype.update = function() {
this.handleWidth = this.$handle[0].offsetWidth;
this.rangeWidth = this.$range[0].offsetWidth;
this.maxHandleX = this.rangeWidth - this.handleWidth;
this.grabX = this.handleWidth / 2;
this.position = this.getPositionFromValue(this.value);
if (this.$element[0].disabled) {
this.$range.addClass(this.options.disabledClass);
} else {
this.$range.removeClass(this.options.disabledClass);
}
this.setPosition(this.position);
};
Plugin.prototype.handleDown = function(e) {
e.preventDefault();
this.$document.on(this.moveEvent, this.handleMove);
this.$document.on(this.endEvent, this.handleEnd);
if ((' ' + e.target.className + ' ').replace(/[\n\t]/g, ' ').indexOf(this.options.handleClass) > -1) {
return;
}
var posX = this.getRelativePosition(this.$range[0], e),
handleX = this.getPositionFromNode(this.$handle[0]) - this.getPositionFromNode(this.$range[0]);
this.setPosition(posX - this.grabX);
if (posX >= handleX && posX < handleX + this.handleWidth) {
this.grabX = posX - handleX;
}
};
Plugin.prototype.handleMove = function(e) {
e.preventDefault();
var posX = this.getRelativePosition(this.$range[0], e);
this.setPosition(posX - this.grabX);
};
Plugin.prototype.handleEnd = function(e) {
e.preventDefault();
this.$document.off(this.moveEvent, this.handleMove);
this.$document.off(this.endEvent, this.handleEnd);
if (this.onSlideEnd && typeof this.onSlideEnd === 'function') {
this.onSlideEnd(this.position, this.value);
}
};
Plugin.prototype.cap = function(pos, min, max) {
if (pos < min) { return min; }
if (pos > max) { return max; }
return pos;
};
Plugin.prototype.setPosition = function(pos) {
var value, left;
value = (this.getValueFromPosition(this.cap(pos, 0, this.maxHandleX)) / this.step) * this.step;
left = this.getPositionFromValue(value);
this.$fill[0].style.width = (left + this.grabX) + 'px';
this.$handle[0].style.left = left + 'px';
this.setValue(value);
this.position = left;
this.value = value;
};
Plugin.prototype.getPositionFromNode = function(node) {
var i = 0;
while (node !== null) {
i += node.offsetLeft;
node = node.offsetParent;
}
return i;
};
Plugin.prototype.getRelativePosition = function(node, e) {
return (e.pageX || e.originalEvent.clientX || e.originalEvent.touches[0].clientX || e.currentPoint.x) - this.getPositionFromNode(node);
};
Plugin.prototype.getPositionFromValue = function(value) {
var percentage, pos;
percentage = (value - this.min)/(this.max - this.min);
pos = percentage * this.maxHandleX;
return pos;
};
Plugin.prototype.getValueFromPosition = function(pos) {
var percentage, value;
percentage = ((pos) / (this.maxHandleX || 1));
value = this.step * Math.round((((percentage) * (this.max - this.min)) + this.min) / this.step);
return Number((value).toFixed(2));
};
Plugin.prototype.setValue = function(value) {
if (value !== this.value) {
this.$element.val(value).trigger('change', {origin: pluginName});
}
};
Plugin.prototype.destroy = function() {
this.$document.off(this.startEvent, '#' + this.identifier, this.handleDown);
this.$element
.off('.' + pluginName)
.removeAttr('style')
.removeData('plugin_' + pluginName);
if (this.$range && this.$range.length) {
this.$range[0].parentNode.removeChild(this.$range[0]);
}
pluginInstances.splice(pluginInstances.indexOf(this.$element[0]),1);
if (!pluginInstances.length) {
this.$window.off('.' + pluginName);
}
};
$.fn[pluginName] = function(options) {
return this.each(function() {
var $this = $(this),
data = $this.data('plugin_' + pluginName);
if (!data) {
$this.data('plugin_' + pluginName, (data = new Plugin(this, options)));
pluginInstances.push(this);
}
if (typeof options === 'string') {
data[options]();
}
});
};
}));
});
any solutions possible? Do you need more code?
Already did try this but it doesnt work aswell..
<div>
<input id="rangeInput" type="range" min="0" max="200" oninput="amount.value=rangeInput.value" />
<input id="amount" type="number" value="100" min="0" max="200" oninput="rangeInput.value=amount.value" />
</div>
My server is acting weird -- the updating setInterval under Update LOBBIES is set to run # 1000/60ms or 60cps, which I'm only getting a steady 34cps. But when socket.emit('angle') is used from CLIENT side, it runs smoothly at 60cps up until socket.emit('angle') stops, then returns back to 34cps. It's been 3 days and I still have absolutely no idea. Code doesn't seem to have a throttle issue, and weirdly enough, works better when a socket.on event is called for the angle only, not others. Doesn't make any sense! Any ideas?
HTML/Javascript Client
User.onConnect = (socket) => {
var lobbies = [];
socket.on('updateLobbies', (data) => {
$('#menu-screen-navigation-display-play ul').empty();
$('#menu-screen-navigation-display-play ul').append(
"<li style='position: fixed;top: calc(13vh); width: 47.5%; height: calc(5vh); left:26.25%;background-color: rgba(50,50,50,1);'>" +
" <table>" +
" <th style='width:10%'>" +
" <span></span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-lobby'>Lobby</span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-map'>Map</span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-gamemode'>Game Mode</span>" +
" </th>" +
" <th style='width:15%'>" +
" <span class='play-players'>Players</span>" +
" </th>" +
" <th style='width:15%'>" +
" <span></span>" +
" </th>" +
" </table>" +
"</li>");
$('#menu-screen-navigation-display-play ul').append(
"<li style='position: fixed;bottom: calc(4vh); width: 47.5%; height: calc(5vh); left:26.25%;background-color: rgba(50,50,50,1);'>" +
" <table>" +
" <th style='width:10%'>" +
" <span></span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-lobby'></span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-map'></span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-gamemode'></span>" +
" </th>" +
" <th style='width:15%'>" +
" <span class='play-players'></span>" +
" </th>" +
" <th style='width:15%'>" +
" <span></span>" +
" </th>" +
" </table>" +
"</li>");
for(let i in data){
lobbies[i] = data[i];
switch(lobbies[i].mode){
case 'Outbreak': {
lobbies[i].modeColor = 'green';
break;
}
default: {
lobbies[i].modeColor = 'white';
}
}
switch(lobbies[i].map){
case 'Urban Delight': {
lobbies[i].mapSrc = 'img/ui/map-icons/urbanDelight.png';
break;
}
default: {
break;
}
}
$('#menu-screen-navigation-display-play ul').append(
"<li>" +
" <table>" +
" <th style='width:10%'>" +
" <img src='" + lobbies[i].mapSrc + "'/>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-lobby'>" + lobbies[i].title + "</span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-map'>" + lobbies[i].map + "</span>" +
" </th>" +
" <th style='width:20%'>" +
" <span class='play-gamemode' style='color:"+lobbies[i].modeColor+"'>" + lobbies[i].mode + "</span>" +
" </th>" +
" <th style='width:15%'>" +
" <span class='play-players'>" + lobbies[i].online + " / " + lobbies[i].max + "</span>" +
" </th>" +
" <th style='width:15%'>" +
" <button id='"+ lobbies[i].title + "' class='bubble'>Join</button>" +
" </th>" +
" </table>" +
"</li>");
$('#'+lobbies[i].title).click(function(){
playAudio(SFX['pop']);
socket.emit('lobby.join', this.id);
$('#menu-screen').hide();
$('#menu-canvas').hide();
$('#game-screen').show();
MUSIC['menu'].pause();
MUSIC['menu'].currentTime = 0;
game(socket);
});
}
});
socket.on('gameID', (data) => {
MAIN.id = data;
});
socket.on('sendClientChat', (data) => {
if(data.user == 'server'){
$("#chat-list").append(`<li><span class="chat-message" style="color:rgba(255,255,255,0.8);"> ${data.msg}</span></li>`);
}
else {
$("#chat-list").append(`<li><span class="chat-message"><span style="color:red;">${data.user}:</span> ${chatFilter(data.msg)}</span></li>`);
}
$("#chat-list").scrollTop($("#chat-list").prop('scrollHeight'));
});
socket.on('lobbyinfo', (data) => {
MAP = data;
});
socket.on('refresh', (data) => {
PLAYER_LIST = data.players;
for(var P in PLAYER_LIST){
if(MAIN.id == PLAYER_LIST[P].id){
MAIN.position = PLAYER_LIST[P].position;
break;
}
}
$('#serverCPS').text(data.server.cps);
});
}
var controlReady = {
up: true,
down: true,
left: true,
right: true,
Q: true,
E: true,
R: true,
SHIFT: true,
SPACE: true,
ENTER: true,
click: true
};
function controls(mobile, socket){
if(mobile){
$('#touchable-screen').show();
document.getElementById("touchable-screen").addEventListener("touchstart", function(event){
event.preventDefault();
event.stopImmediatePropagation();
emitMouseClick(true);
emitMouseAngle(socket, event.touches[0]);
});
document.getElementById("touchable-screen").addEventListener("touchmove", function(event){
event.preventDefault();
event.stopImmediatePropagation();
emitMouseAngle(socket, event.touches[0]);
});
document.getElementById("touchable-screen").addEventListener("touchend", function(event){
event.preventDefault();
event.stopImmediatePropagation();
emitMouseClick(false);
emitMouseAngle(socket, event.touches[0]);
});
var joystickRadius = Math.round(window.innerHeight/100 * 5);
document.getElementById("joystick-left").style.width = Math.round(window.innerHeight/100 * 30) +"px";
document.getElementById("joystick-left").style.height = Math.round(window.innerHeight/100 * 30) +"px";
document.getElementById("joystick-left").style.left = Math.round(window.innerHeight/100 * 3) +"px";
document.getElementById("joystick-left").style.bottom = Math.round(window.innerHeight/100 * 3) +"px";
document.getElementById("joystick-left-stick").style.width = Math.round(window.innerHeight/100 * 20) +"px";
document.getElementById("joystick-left-stick").style.height = Math.round(window.innerHeight/100 * 20) +"px";
document.getElementById("joystick-left-stick").style.right = Math.round(window.innerHeight/100 * 5) +"px";
document.getElementById("joystick-left-stick").style.bottom = Math.round(window.innerHeight/100 * 2.5) +"px";
let myStickLeft = new JoystickController("joystick-left-stick", joystickRadius, 8);
document.getElementById("joystick-right").style.width = Math.round(window.innerHeight/100 * 30) +"px";
document.getElementById("joystick-right").style.height = Math.round(window.innerHeight/100 * 30) +"px";
document.getElementById("joystick-right").style.right = Math.round(window.innerHeight/100 * 3) +"px";
document.getElementById("joystick-right").style.bottom = Math.round(window.innerHeight/100 * 3) +"px";
document.getElementById("joystick-right-stick").style.width = Math.round(window.innerHeight/100 * 20) +"px";
document.getElementById("joystick-right-stick").style.height = Math.round(window.innerHeight/100 * 20) +"px";
document.getElementById("joystick-right-stick").style.right = Math.round(window.innerHeight/100 * 5) +"px";
document.getElementById("joystick-right-stick").style.bottom = Math.round(window.innerHeight/100 * 2.5) +"px";
let myStickRight = new JoystickController("joystick-right-stick", joystickRadius, 8);
$('#joystick-left').show();
$('#joystick-right').show();
$('#chat-input').hide();
}
else{
document.addEventListener('mousemove', function(event){
emitMouseAngle(socket, event);
});
document.addEventListener('mousedown', function(event){
emitMouseAngle(socket, event);
emitMouseClick(true);
});
document.addEventListener('mouseup', function(event){
emitMouseAngle(socket, event);
emitMouseClick(false);
});
}
document.addEventListener('keydown', (event) => {
if(controlReady.up && (event.keyCode === 87 || event.keyCode == 38)){//UP
controlReady.up = false;
socket.emit('controls',{inputId:'up',state:true});
}
if(controlReady.down && (event.keyCode == 83 || event.keyCode == 40)){//DOWN
controlReady.down = false;
socket.emit('controls',{inputId:'down',state:true});
}
if(controlReady.left && (event.keyCode == 65 || event.keyCode == 37)){//LEFT
controlReady.left = false;
socket.emit('controls',{inputId:'left',state:true});
}
if(controlReady.right && (event.keyCode == 68 || event.keyCode == 39)){//RIGHT
controlReady.right = false;
socket.emit('controls',{inputId:'right',state:true});
}
if(controlReady.Q && event.keyCode == 81){//Q
controlReady.Q = false;
socket.emit('controls',{inputId:'Q',state:true});
}
if(controlReady.E && event.keyCode == 69){//E
controlReady.E = false;
socket.emit('controls',{inputId:'E',state:true});
}
if(controlReady.R && event.keyCode == 82){//R
controlReady.R = false;
socket.emit('controls',{inputId:'R',state:true});
}
if(controlReady.SHIFT && event.keyCode == 16){//SHIFT
controlReady.SHIFT = false;
socket.emit('controls',{inputId:'shift',state:true});
}
if(controlReady.SPACE && event.keyCode == 32){//SPACE
controlReady.SPACE = false;
socket.emit('controls',{inputId:'space',state:true});
}
});
document.addEventListener('keyup', (event) => {
if(!controlReady.up && (event.keyCode === 87 || event.keyCode == 38)){//UP
controlReady.up = true;
socket.emit('controls',{inputId:'up',state:false});
}
if(!controlReady.down && (event.keyCode == 83 || event.keyCode == 40)){//DOWN
controlReady.down = true;
socket.emit('controls',{inputId:'down',state:false});
}
if(!controlReady.left && (event.keyCode == 65 || event.keyCode == 37)){//LEFT
controlReady.left = true;
socket.emit('controls',{inputId:'left',state:false});
}
if(!controlReady.right && (event.keyCode == 68 || event.keyCode == 39)){//RIGHT
controlReady.right = true;
socket.emit('controls',{inputId:'right',state:false});
}
if(!controlReady.Q && event.keyCode == 81){//Q
controlReady.Q = true;
socket.emit('controls',{inputId:'Q',state:false});
}
if(!controlReady.E && event.keyCode == 69){//E
controlReady.E = true;
socket.emit('controls',{inputId:'E',state:false});
}
if(!controlReady.R && event.keyCode == 82){//R
controlReady.R = true;
socket.emit('controls',{inputId:'R',state:false});
}
if(!controlReady.SHIFT && event.keyCode == 16){//false
controlReady.SHIFT = true;
socket.emit('controls',{inputId:'shift',state:false});
}
if(!controlReady.SPACE && event.keyCode == 32){//SPACE
controlReady.SPACE = true;
socket.emit('controls',{inputId:'space',state:false});
}
});
$('#chat-input').focus(() => {
controlReady.ENTER = false;
});
$('#chat-input').blur(() => {
controlReady.ENTER = true;
});
function emitMouseAngle(socket, event) {
var mouse;
if(settings.mobile){
mouse = {
x: Math.round(event.clientX * pixelDensityRatio),
y: Math.round(event.clientY * pixelDensityRatio)
};
}
else {
mouse = {
x: Math.round(event.x * pixelDensityRatio),
y: Math.round(event.y * pixelDensityRatio)
};
};
var angle = Math.floor(Math.atan2(mouse.y - center.y, mouse.x - center.x) * 100)/100;
socket.emit('angle', angle);
}
function emitMouseClick(click){
if(click){
socket.emit('controls',{inputId:'click',state:true});
}
else{
socket.emit('controls',{inputId:'click',state:false});
}
}
}
Node.js Server Code w/ Redis
const os = require('os'),
cluster = require('cluster'),
cores = os.cpus();
var clusterCount = 0;
process.on('uncaughtException', function (exception) {
console.log(exception); // to see your exception details in the console
// if you are on production, maybe you can send the exception details to your
// email as well ?
});
if(cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < cores.length; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
}
else{
const http = require('http'),
express = require('express'),
socketio = require('socket.io'),
process = require('process'),
config = require('./config.js'),
socketioRedis = require('socket.io-redis'),
redis = require('./redis.js');
const settings = {
cps: 60
};
var LOBBY_LIST = {};
redis.subscriber.on('connect', () => {
console.log(`worker ${process.pid} connected to redis(subscriber)`);
redis.subscriber.subscribe('LOBBIES');
redis.subscriber.on('message', (channel, data) => {
var parsedData = JSON.parse(data);
switch(channel){
case 'LOBBIES': {
//console.log(`Lobby -- ${parsedData.title} | ${parsedData.map} | ${parsedData.mode} | ${parsedData.max}`);
LOBBY_LIST[parsedData.title] = parsedData;
break;
}
default: {
break;
}
}
});
redis.subscriber.on('users', (channel, data) => {
console.log(`${data.id} connected to worker ${data.server}`);
});
});
redis.publisher.on('connect', () => {
console.log(`worker ${process.pid} connected to redis(publisher)`);
var cpu = cores[clusterCount];
var app = express();
var port = process.env.PORT || process.argv[2] || 8080;
var server = app.listen(port);
var io = socketio(server);
var User = {};
var SOCKET_LIST = {};
var PLAYER_LIST = {};
io.adapter(socketioRedis({host: config.redis_host, port: config.redis_port}));
io.on('connection', (socket) => {
User.onConnect(socket);
});
User.onConnect = (socket) => {
console.log(`${socket.id} connected to worker ${process.pid}`);
var id = socket.id;
var player = new Player(id);
SOCKET_LIST[id] = socket;
SOCKET_LIST[id].spamGuard = 0;
var updateLobbies = setInterval(() => {
socket.emit('updateLobbies', LOBBY_LIST);
}, 3000);
socket.emit('gameID', id);
socket.on('serverPing', (ping) => {
socket.emit('serverPong', ping);
});
socket.on('sendServerChat', (data) => {
if(data != ' ' && data != ' ' && data != ' '){
if(SOCKET_LIST[socket.id].spamGuard < 3){
if(data.length < 100){
var chat = {
user: socket.id,
msg: data
};
io.sockets.emit('sendClientChat', chat);
SOCKET_LIST[socket.id].spamGuard++;
}
}
else{
var chat = {
user: 'server',
msg: 'You\'re sending messages too fast!'
};
socket.emit('sendClientChat', chat);
}
}
else {
var chat = {
user: 'server',
msg: 'Can\'t send an empty message!'
};
socket.emit('sendClientChat', chat);
}
});
socket.on('lobby.join', (lobby) => {
var user = {
id: socket.id,
lobby: lobby
};
redis.publisher.publish('JOINROOM', JSON.stringify(user));
socket.emit('lobbyinfo', map[LOBBY_LIST[lobby].map]);
});
socket.on('lobby.leave', () => {
var user = {
id: socket.id,
lobby: lobby
};
redis.publisher.publish('LEAVEROOM', JSON.stringify(user));
});
socket.on('disconnect', () => {
User.onDisconnect(socket);
});
socket.on('controls', (data) => {
if(data.inputId === 'up'){//UP
player.controls.pressingUp = data.state;
}
else if(data.inputId === 'down'){//DOWN
player.controls.pressingDown = data.state;
}
else if(data.inputId === 'left'){//LEFT
player.controls.pressingLeft = data.state;
}
else if(data.inputId === 'right'){//RIGHT
player.controls.pressingRight = data.state;
}
else if(data.inputId === 'Q'){//Q
player.controls.pressingQ = data.state;
}
else if(data.inputId === 'E'){//E
player.controls.pressingE = data.state;
}
else if(data.inputId === 'R'){//R
player.controls.pressingR = data.state;
}
else if(data.inputId === 'shift'){//SHIFT
player.controls.pressingSHIFT = data.state;
}
else if(data.inputId === 'space'){//SPACE
player.controls.pressingSPACE = data.state;
}
if(data.inputId === 'click'){//Click
player.controls.leftClick = data.state;
}
});
socket.on('angle', (data) => {
player.angle = data;
});
};
User.onDisconnect = (socket) => {
console.log(`${socket.id} disconnected from worker ${process.pid}`);
delete SOCKET_LIST[socket.id];
delete PLAYER_LIST[socket.id];
socket.disconnect();
};
var Player = function(id){
var self = {
id: id,
username: 'player',
server: '',
position: {
x: 0,
y: 0
},
speed: 500,
angle: degrees_to_radians(Math.floor(Math.random()*360)),
controls: {
leftClick: false,
pressingUp: false,
pressingDown: false,
pressingLeft: false,
pressingRight: false,
pressingQ: false,
pressingE: false,
pressingR: false,
pressingSHIFT: false,
pressingSPACE: false
}
};
self.updatePosition = function(){
if(self.controls.pressingUp){
self.position.y -= self.speed / settings.cps;
if(self.position.y < 0){
self.position.y = 0;
}
}
if(self.controls.pressingDown){
self.position.y += self.speed / settings.cps;
if(self.position.y > 9999){
self.position.y = 9999;
}
}
if(self.controls.pressingLeft){
self.position.x -= self.speed / settings.cps;
if(self.position.x < 0){
self.position.x = 0;
}
}
if(self.controls.pressingRight){
self.position.x += self.speed / settings.cps;
if(self.position.x > 9999){
self.position.x = 9999;
}
}
};
PLAYER_LIST[self.id] = self;
return self;
};
Player.update = function(){
var pack = [];
for(var i in PLAYER_LIST){
var player = PLAYER_LIST[PLAYER_LIST[i].id];
player.updatePosition();
pack.push({
id: player.id,
position: player.position,
angle: player.angle
});
}
return pack;
};
//Spam Guard
setInterval(() => {
for(var id in SOCKET_LIST){
if(SOCKET_LIST[id].spamGuard > 0){
SOCKET_LIST[id].spamGuard--;
}
}
}, 3000);
//Update LOBBIES
setInterval(() => {
//for(var L in LOBBY_LIST){
// var lobby = LOBBY_LIST[L];
checkCPS();
var pack = {
players: Player.update(),
server: {
cps: cpsSave
}
};
for(var S in SOCKET_LIST){
var user = SOCKET_LIST[SOCKET_LIST[S].id];
user.emit('refresh', pack);
}
//}
}, 1000/settings.cps);
var map = [
'Urban Delight',
'Graveyard',
'Farmlands'
];
for(var i in map){
var mapName = map[i];
map[mapName] = {
tileSize: 100,
matrix: [],
};
for(var j = 0; j < 100; j++){
map[mapName].matrix[j] = [];
for(var k = 0; k < 100; k++){
map[mapName].matrix[j][k] = 0;
}
}
}
function degrees_to_radians(degrees){
var pi = Math.PI;
return degrees * (pi/180);
}
function radians_to_degrees(radians){
var pi = Math.PI;
return radians / (pi/180);
}
var cps = 0,
cpsCheck = 0,
cpsSave = 0;
function checkCPS(){
cps++;
var d = new Date().getSeconds();
if(cpsCheck != d){
cpsCheck = d;
cpsSave = cps;
cps = 0;
}
}
console.log(`Worker ${process.pid} started on port: ${port} | ${cpu.model}`);
clusterCount++;
});
}
After press the Form Submit button the page goes .scrollTop ... How to Stop that in this code bellow ?
jQuery(document).ready(function(i) {
"use strict";
(i.wc_product_vendors_vendor_frontend = {
init: function() {
var s = i(".wcpv-shortcode-registration-form").position();
i(document.body).on(
"submit",
"form.wcpv-shortcode-registration-form",
function(o) {
o.preventDefault();
var r = {
action: "wc_product_vendors_registration",
ajaxRegistrationNonce:
wcpv_registration_local.ajaxRegistrationNonce,
form_items: i(this).serialize()
},
e = i(this);
i(".wcpv-registration-message").remove(),
e.block({
message: null,
overlayCSS: { background: "#fff", opacity: 0.6 }
}),
i.post(wcpv_registration_local.ajaxurl, r, function(o) {
if ((e.unblock(), o.length && "success" === o))
i(document.body).trigger("wcpv_vendor_registration_on_success"),
e.before(
'<p class="wcpv-shortcode-registration-success wcpv-registration-message">' +
wcpv_registration_local.success +
"</p>"
),
e.fadeOut("fast"),
i("input, textarea", e)
.not('input[type="submit"]')
.val("");
else {
var t = "";
i.each(o.errors, function(o, r) {
t += '<span class="error">' + r + "</span>";
}),
e.before(
'<div class="wcpv-shortcode-registration-form-errors wcpv-registration-message">' +
t +
"</div"
);
}
i("html, body").scrollTop(s.top - 50);
});
}
);
}
}),
i.wc_product_vendors_vendor_frontend.init();
});
I need to have a lightbox image link to another page, in this case it's on tumblr as the permalink page. I tried wrapping the markup of mfp-img div in a href with "{Permalink}" (as per tumblr's api) and then "%url%", but both render exactly the same as inside the quotes, rather than the actual link to the page.
I'm quite familiar with css, but unfortunately my js is lacking. Here's the portion of the code that controls the lightbox image. Where and how should I add the href to the code?
a.magnificPopup.registerModule("image", {
options: {
markup: '<div class="mfp-figure"><div class="mfp-close"></div><div class="mfp-img"></div><div class="mfp-bottom-bar"><div class="mfp-title"></div><div class="mfp-counter"></div></div></div>',
cursor: "mfp-zoom-out-cur",
titleSrc: "title",
verticalFit: !0,
tError: 'The image could not be loaded.'
},
proto: {
initImage: function() {
var a = n.st.image,
c = ".image";
n.types.push("image"), x(g + c, function() {
n.currItem.type === "image" && a.cursor && s.addClass(a.cursor)
}), x(b + c, function() {
a.cursor && s.removeClass(a.cursor), r.off("resize" + j)
}), x("Resize" + c, n.resizeImage), n.isLowIE && x("AfterChange", n.resizeImage)
},
resizeImage: function() {
var a = n.currItem;
if (!a || !a.img) return;
if (n.st.image.verticalFit) {
var b = 0;
n.isLowIE && (b = parseInt(a.img.css("padding-top"), 10) + parseInt(a.img.css("padding-bottom"), 10)), a.img.css("max-height", n.wH - b)
}
},
_onImageHasSize: function(a) {
a.img && (a.hasSize = !0, N && clearInterval(N), a.isCheckingImgSize = !1, z("ImageHasSize", a), a.imgHidden && (n.content && n.content.removeClass("mfp-loading"), a.imgHidden = !1))
},
findImageSize: function(a) {
var b = 0,
c = a.img[0],
d = function(e) {
N && clearInterval(N), N = setInterval(function() {
if (c.naturalWidth > 0) {
n._onImageHasSize(a);
return
}
b > 200 && clearInterval(N), b++, b === 3 ? d(10) : b === 40 ? d(50) : b === 100 && d(500)
}, e)
};
d(1)
},
getImage: function(b, c) {
var d = 0,
e = function() {
b && (b.img[0].complete ? (b.img.off(".mfploader"), b === n.currItem && (n._onImageHasSize(b), n.updateStatus("ready")), b.hasSize = !0, b.loaded = !0, z("ImageLoadComplete")) : (d++, d < 200 ? setTimeout(e, 100) : f()))
},
f = function() {
b && (b.img.off(".mfploader"), b === n.currItem && (n._onImageHasSize(b), n.updateStatus("error", g.tError.replace("%url%", b.src))), b.hasSize = !0, b.loaded = !0, b.loadError = !0)
},
g = n.st.image,
h = c.find(".mfp-img");
if (h.length) {
var i = document.createElement("img");
i.className = "mfp-img", b.img = a(i).on("load.mfploader", e).on("error.mfploader", f), i.src = b.src, h.is("img") && (b.img = b.img.clone()), b.img[0].naturalWidth > 0 && (b.hasSize = !0)
}
return n._parseMarkup(c, {
title: O(b),
img_replaceWith: b.img
}, b), n.resizeImage(), b.hasSize ? (N && clearInterval(N), b.loadError ? (c.addClass("mfp-loading"), n.updateStatus("error", g.tError.replace("%url%", b.src))) : (c.removeClass("mfp-loading"), n.updateStatus("ready")), c) : (n.updateStatus("loading"), b.loading = !0, b.hasSize || (b.imgHidden = !0, c.addClass("mfp-loading"), n.findImageSize(b)), c)
}
}
});
var P, Q = function() {
return P === undefined && (P = document.createElement("p").style.MozTransform !== undefined), P
};
a.magnificPopup.registerModule("zoom", {
options: {
enabled: !1,
easing: "ease-in-out",
duration: 300,
opener: function(a) {
return a.is("img") ? a : a.find("img")
}
},
proto: {
initZoom: function() {
var a = n.st.zoom,
d = ".zoom";
if (!a.enabled || !n.supportsTransition) return;
var e = a.duration,
f = function(b) {
var c = b.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),
d = "all " + a.duration / 1e3 + "s " + a.easing,
e = {
position: "fixed",
zIndex: 9999,
left: 0,
top: 0,
"-webkit-backface-visibility": "hidden"
},
f = "transition";
return e["-webkit-" + f] = e["-moz-" + f] = e["-o-" + f] = e[f] = d, c.css(e), c
},
g = function() {
n.content.css("visibility", "visible")
},
h, i;
x("BuildControls" + d, function() {
if (n._allowZoom()) {
clearTimeout(h), n.content.css("visibility", "hidden"), image = n._getItemToZoom();
if (!image) {
g();
return
}
i = f(image), i.css(n._getOffset()), n.wrap.append(i), h = setTimeout(function() {
i.css(n._getOffset(!0)), h = setTimeout(function() {
g(), setTimeout(function() {
i.remove(), image = i = null, z("ZoomAnimationEnded")
}, 16)
}, e)
}, 16)
}
}), x(c + d, function() {
if (n._allowZoom()) {
clearTimeout(h), n.st.removalDelay = e;
if (!image) {
image = n._getItemToZoom();
if (!image) return;
i = f(image)
}
i.css(n._getOffset(!0)), n.wrap.append(i), n.content.css("visibility", "hidden"), setTimeout(function() {
i.css(n._getOffset())
}, 16)
}
}), x(b + d, function() {
n._allowZoom() && (g(), i && i.remove())
})
},
_allowZoom: function() {
return n.currItem.type === "image"
},
_getItemToZoom: function() {
return n.currItem.hasSize ? n.currItem.img : !1
},
_getOffset: function(b) {
var c;
b ? c = n.currItem.img : c = n.st.zoom.opener(n.currItem.el || n.currItem);
var d = c.offset(),
e = parseInt(c.css("padding-top"), 10),
f = parseInt(c.css("padding-bottom"), 10);
d.top -= a(window).scrollTop() - e;
var g = {
width: c.width(),
height: (p ? c.innerHeight() : c[0].offsetHeight) - f - e
};
return Q() ? g["-moz-transform"] = g.transform = "translate(" + d.left + "px," + d.top + "px)" : (g.left = d.left, g.top = d.top), g
}
}
});
Here is the portion I tried to edit, both with permalink and %url%, with and without quotations.
a.magnificPopup.registerModule("image", {
options: {
markup: '<div class="mfp-figure"><div class="mfp-close"></div><div class="mfp-img"></div><div class="mfp-bottom-bar"><div class="mfp-title"></div><div class="mfp-counter"></div></div></div>',
cursor: "mfp-zoom-out-cur",
titleSrc: "title",
verticalFit: !0,
tError: 'The image could not be loaded.'
},
I have a customized JW Player 7 Pro embedded on the following page: http://dev.sharepoint-videos.com/jw-player-self-hosted/.
The embed code is as follows:
<!--Course Video, Scripts and Style-->
<div id="visualSPPlayer">Loading the player...</div>
<script type="text/javascript">
var playerInstance = jwplayer("visualSPPlayer");
playerInstance.setup({
file: "http://dbt8c2ssdzlxg.cloudfront.net/Search2013.mp4",
primary: "HTML5",
image: "https://assets-jpcust.jwpsrv.com/thumbs/2kOAeo0k-320.jpg?1443200073230",
width: "100%",
aspectratio: "16:9",
tracks: [
{
file: "http://dbt8c2ssdzlxg.cloudfront.net/captions/Search/Captions.srt",
label: "English",
kind: "captions",
},
{
file: 'http://dbt8c2ssdzlxg.cloudfront.net/chapters/Search/Chapters.vtt',
kind: 'chapters'
},
{
file: "http://dbt8c2ssdzlxg.cloudfront.net/thumbnails/search_thumbnails.vtt",
kind: "thumbnails"
}
],
skin: {
name: "vapor",
active: "#E16933",
inactive: "#E16933",
background: "#333333"
}
});
</script>
<script type="application/javascript" src="http://dev.sharepoint-videos.com/wp-content/themes/symplex-child/js/player.js"></script>
<link rel="stylesheet" href="http://dev.sharepoint-videos.com/wp-content/themes/symplex-child/css/player.css" type="text/css" media="screen"/>
The player.js file contents:
jQuery(document).ready(function () {
jQuery(function ($) {
var playerInstance = jwplayer();
var chapters = [];
var captions = [];
var toc = [];
var caption = -1;
var matches = [];
var seekArr = [];
var seekPos = [];
var seePos;
var query = "";
var cycle = -1;
var transcript = document.getElementById('courseTranscript');
var search = document.getElementById('courseSearch');
var match = document.getElementById('courseMatch');
var caption_file;
var chapter_file;
playerInstance.onReady(function () {
//Self-Hosted
caption_file = playerInstance.getPlaylist()[0].tracks[0].file;
chapter_file = playerInstance.getPlaylist()[0].tracks[1].file;
if (playerInstance.getRenderingMode() == "flash") {
return;
}
tag = document.querySelector('video');
tag.defaultPlaybackRate = 1.0;
tag.playbackRate = 1.0;
playerInstance.addButton("http://dev.sharepoint-videos.com/wp-content/uploads/2015/09/hare.png", "1.5x", function () {
playerInstance.seek(playerInstance.getPosition());
tag.playbackRate = 1.5;
}, "playerHighSpeed");
playerInstance.addButton("http://dev.sharepoint-videos.com/wp-content/uploads/2015/09/normal.png", "1.0x", function () {
playerInstance.seek(playerInstance.getPosition());
tag.playbackRate = 1.0;
}, "playerNormalSpeed");
playerInstance.addButton("http://dev.sharepoint-videos.com/wp-content/uploads/2015/09/snail.png", "0.5x", function () {
playerInstance.seek(playerInstance.getPosition());
tag.playbackRate = 0.5;
}, "playerSlowSpeed");
});
//Adds Player Focus on Playing
playerInstance.on('play', function () {
$('html, body').animate({
scrollTop: $(".jwplayer").offset().top - 190
}, 1000);
});
playerInstance.onReady(function () {
$.get(caption_file, function (data) {
data = data.trim();
var t = data.split("\n\r\n");
for (var i = 0; i < t.length; i++) {
var c = parse(t[i]);
chapters.push(c);
}
loadCaptions();
loadChapters();
});
//
});
// Load chapters / captions
function loadCaptions() {
$.get(caption_file, function (data) {
data = data.trim();
var t = data.split("\n\r\n");
t.pop();
var h = "<p>";
var s = 0;
for (var i = 0; i < t.length; i++) {
var c = parse(t[i]);
if (s < chapters.length && c.begin > chapters[s].begin) {
s++;
}
h += "<span id='caption" + i + "'>" + c.text + "</span>";
captions.push(c);
}
transcript.innerHTML = h + "</p>";
});
};
function parse(d) {
var a = d.split("\n");
//console.log(a[1]);
var i = a[1].indexOf(' --> ');
var t = a[2]; //Caption text
if (a[3]) {
t += " " + a[3];
}
t = t.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return {
begin: seconds(a[1].substr(0, i)),
btext: a[1].substr(3, i - 7),
end: seconds(a[1].substr(i + 5)),
text: t
}
};
function seconds(s) {
var a = s.split(':');
secs = a[2].substring(0, a[2].indexOf(','));
var r = Number(secs) + Number(a[a.length - 2]) * 60;
if (a.length > 2) {
r += Number(a[a.length - 3]) * 3600;
}
return r;
};
function toc_seconds(s) {
var a = s.split(':');
secs = a[2].substring(0, a[2].indexOf('.'));
var r = Number(secs) + Number(a[a.length - 2]) * 60;
if (a.length > 2) {
r += Number(a[a.length - 3]) * 3600;
}
return r;
};
function toc_time(s) {
var a = s.split(':');
var ms = a[2].split(".");
var h = a[0];
if (h != "00") {
var r = a[0] + ":" + a[1] + ":" + ms[0];
} else {
var r = a[1] + ":" + ms[0];
}
return r;
};
// Highlight current caption and chapter
playerInstance.onTime(function (e) {
var p = e.position;
for (var j = 0; j < captions.length; j++) {
if (captions[j].begin < p && captions[j].end > p) {
if (j != caption) {
var c = document.getElementById('caption' + j);
if (caption > -1) {
document.getElementById('caption' + caption).className = "";
}
c.className = "current";
if (query == "") {
transcript.scrollTop = c.offsetTop - transcript.offsetTop - 40;
}
caption = j;
}
break;
}
}
});
// Hook up interactivity
transcript.addEventListener("click", function (e) {
if (e.target.id.indexOf("caption") == 0) {
var i = Number(e.target.id.replace("caption", ""));
playerInstance.seek(captions[i].begin);
}
});
/**/
search.addEventListener('focus', function (e) {
setTimeout(function () {
search.select();
}, 100);
resetSearch();
$("#prevMatchLink").hide();
$("#nextMatchLink").hide();
});
search.addEventListener('keydown', function (e) {
if (e.keyCode == 27) {
resetSearch();
$("#prevMatchLink").hide();
$("#nextMatchLink").hide();
} else if (e.keyCode == 13) {
$("#prevMatchLink").show();
$("#nextMatchLink").show();
var q = this.value.toLowerCase();
if (q.length > 0) {
if (q == query) {
if (cycle >= matches.length - 1) {
cycleSearch(0);
} else {
cycleSearch(cycle + 1);
}
} else {
resetSearch();
searchTranscript(q);
}
} else {
resetSearch();
}
} else if (e.keyCode == 37) {
cycleSearch(cycle - 1);
}
else if (e.keyCode == 39) {
cycleSearch(cycle + 1);
}
});
$("#prevMatchLink").click(function (e) {
e.preventDefault();
cycleSearch(cycle - 1);
});
$("#nextMatchLink").click(function (e) {
e.preventDefault();
cycleSearch(cycle + 1);
});
// Execute search
function searchTranscript(q) {
matches = [];
query = q;
for (var i = 0; i < captions.length; i++) {
var m = captions[i].text.toLowerCase().indexOf(q);
if (m > -1) {
document.getElementById('caption' + i).innerHTML =
captions[i].text.substr(0, m) + "<em>" +
captions[i].text.substr(m, q.length) + "</em>" +
captions[i].text.substr(m + q.length);
matches.push(i);
}
}
if (matches.length) {
cycleSearch(0);
} else {
resetSearch();
}
};
function cycleSearch(i) {
if (cycle > -1) {
var o = document.getElementById('caption' + matches[cycle]);
o.getElementsByTagName("em")[0].className = "";
}
var c = document.getElementById('caption' + matches[i]);
c.getElementsByTagName("em")[0].className = "current";
match.innerHTML = (i + 1) + " of " + matches.length;
transcript.scrollTop = c.offsetTop - transcript.offsetTop - 40;
cycle = i;
};
function resetSearch() {
if (matches.length) {
for (var i = 0; i < captions.length; i++) {
document.getElementById('caption' + i).innerHTML = captions[i].text;
}
}
query = "";
matches = [];
match.innerHTML = "0 of 0";
cycle = -1;
transcript.scrollTop = 0;
};
var videoTitle = $(".videoTitle").text();
var hasPlayed = false;
playerInstance.onBeforePlay(function (event) {
if (hasPlayed == false) {
ga('send', 'event', 'Video', 'Play', videoTitle);
hasPlayed = true;
}
});
//Can be used to trigger the Course to Marked Completed so the user doesn't have to
playerInstance.on('complete', function () {
});
function loadChapters() {
$.get(chapter_file, function (data) {
data = data.trim();
var c = data.split("\n\r\n");
var d;
for (var i = 0; i < c.length; i++) {
d = c[i].split("\n");
//pushes in Title for each chapter
toc.push(d[0]);
//pushes in the time intervals for each chapter
seekArr.push(d[1]);
};
for (var a = 0; a < seekArr.length; a++) {
//Splits the time interval and pushes the start interval for each chapter
var tempPos = seekArr[a].split(" --> ");
seekPos.push(tempPos[0]);
};
runTOC(seekPos);
var toc_output = "";
$.each(toc, function (i, v) {
toc_output += "<li class=ch" + i + "><a href='#' onclick='jwplayer().seek(" + toc_seconds(seekPos[i]) + ");'>" + v + "</a> (" + toc_time(seekPos[i]) + ")</li>"
});
if (toc.length < 7) {
toc_output += " <li class='blank'> </li><li class='blank'> </li>";
}
$(".courseTitles ul").html(toc_output);
});
};
function runTOC(x) {
playerInstance.onTime(function (event) {
for (var i = 0; i < x.length; i++) {
if (event.position > toc_seconds(x[i])) {
$(".courseTitles ul li").removeClass("active");
$(".courseTitles ul li.ch" + i).addClass('active');
}
};
});
}
});
});
We are hosting the video and Chapter/Captions VTT files using Amazon Web Services with Cloudfront.
We have included the interactive transcript from the captions as well as dynamic video chapters to be loaded once the video is ready to be played.
One thing I have noticed is that the chapters and the transcript do not always load and require the page to be refreshed several times so I was thinking that maybe it was a caching issue on the AWS side of the equation.
I have used Google Chrome and there are no errors in the developers console when the chapters and transcript do not load.
It should be noted that this functionality was working flawlessly when were using the JW Platform cloud hosted solution so it seems to be a factor of the AWS/Cloudfront CDN.
function load_jwp_scripts() {
wp_enqueue_script('jwplayer-js', plugins_url( "/js/jwplayer.js", __FILE__), array(), '1.0', false);
wp_enqueue_script('jwplayer-license-js', plugins_url( "/js/jwplayer_license.js", __FILE__), array(), '1.0', false);
wp_enqueue_script('jwplayer-player-js', plugins_url( "/js/player.js", __FILE__), array('jquery'), '1.0', true);
}
add_action('wp_enqueue_scripts', 'load_jwp_scripts');
I was able to find a workable solution to my problem.
The issue was the use of the $(document).ready declaration. It is not compatible with jwplayer.on("ready").
Removing that and it is rendering properly again.