Disable bounce on first and last item in Owl Carousel - javascript

I'm using a Owl Carousel slider.
When you reach the last or first item of the slider you can still drag the slider although there aren't anymore items. Instead there is a bounce effect like when you pull down a native mobile app to refresh the content.
Demo: (link removed since the official docs aren't there anymore)
Drag the slider to the right and it will bounce back.
Is there a possibility to disable that bounce effect?

Yes, you can disable the bounce effect. I struggled finding it but I did it.
Just remove or comment out this lines code in owl.carousel.js:
base.newPosX = Math.max(Math.min(base.newPosX, minSwipe()), maxSwipe());
if (base.browser.support3d === true) {
base.transition3d(base.newPosX);
} else {
base.css2move(base.newPosX);
}
E.g.
owl.carousel.js
function dragMove(event) {
var ev = event.originalEvent || event || window.event,
minSwipe,
maxSwipe;
base.newPosX = getTouches(ev).x - locals.offsetX;
base.newPosY = getTouches(ev).y - locals.offsetY;
base.newRelativeX = base.newPosX - locals.relativePos;
if (typeof base.options.startDragging === "function" && locals.dragging !== true && base.newRelativeX !== 0) {
locals.dragging = true;
base.options.startDragging.apply(base, [base.$elem]);
}
if ((base.newRelativeX > 8 || base.newRelativeX < -8) && (base.browser.isTouch === true)) {
if (ev.preventDefault !== undefined) {
ev.preventDefault();
} else {
ev.returnValue = false;
}
locals.sliding = true;
}
if ((base.newPosY > 10 || base.newPosY < -10) && locals.sliding === false) {
$(document).off("touchmove.owl");
}
minSwipe = function () {
return base.newRelativeX / 5;
};
maxSwipe = function () {
return base.maximumPixels + base.newRelativeX / 5;
};
// base.newPosX = Math.max(Math.min(base.newPosX, minSwipe()), maxSwipe());
// if (base.browser.support3d === true) {
// base.transition3d(base.newPosX);
// } else {
// base.css2move(base.newPosX);
// }
}
Hope it helps.

Related

disable hover effect for touch devices - javascript

In my application, there are multiple cards to show different details. Now, there are two paddles(left/right) to scroll cards . For normal browsing(safari,firefox,chrome) in desktop/laptop, that left/right paddles are visible while hovering over those cards. Inside those cards all the link/hyperlink are working fine in desktop/laptop.
But, when i check that same application in ipad, we had to double click for any link on those cards. Because on first click those paddles are visible then on second click those link routes to the correct path. I want to disable that hover effect and show the paddles initially.
here is my template code snippet
<div
v-show="grid"
class="second-row"
#mouseover="showPaddle"
#scroll.passive="setScrolledLeft"
>
<Paddles
:margin-top="secondRowHeight/2"
:showRightPaddle="showRightPaddle"
:showLeftPaddle="showLeftPaddle"
#scroll-cards="scrollCards"
/> ..... </div>
Now, i am trying to check the touch devices and remove the hover effect on paddles and display them.
method to show paddles
// checking the device is touch or non-touch
isTouchDevice() {
if ('ontouchstart' in window ||
(window.DocumentTouch && document instanceof window.DocumentTouch) ||
(navigator.maxTouchPoints > 0 || window.navigator.msMaxTouchPoints > 0)
) {
return true;
}
return window.matchMedia( "(pointer: coarse)" ).matches;
},
showPaddle() {
const secondRowEl = this.$el.querySelector('.second-row');
const gridWidth = this.$el.querySelector('.grid').clientWidth; // to scroll cards
const scrollMax = gridWidth - secondRowEl.clientWidth;
if (gridWidth > secondRowEl.clientWidth) {
if (secondRowEl.scrollLeft > 0 && secondRowEl.scrollLeft < scrollMax) {
this.showLeftPaddle = true;
this.showRightPaddle = true;
if(window.innerWidth < 768) {
if(this.isTouchDevice) {
try {
for (let sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI-=1) {
const sheet = document.styleSheets[sheetI];
if (sheet.cssRules) {
for (let ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI-=1) {
const rule = sheet.cssRules[ruleI];
if (rule.selectorText) {
if (sheet.rules[ruleI].selectorText.match(':hover')) {
sheet.deleteRule(ruleI);
}
}
}
}
}
} catch(e) {
Logger.error(e);
}
}
}
} else if (secondRowEl.scrollLeft >= scrollMax) {
this.showLeftPaddle = true;
this.showRightPaddle = false;
} else if (secondRowEl.scrollLeft <= 0) {
this.showLeftPaddle = false;
this.showRightPaddle = true;
}
} else {
this.showLeftPaddle = false;
this.showRightPaddle = false;
}
if (!this.secondRowHeight) {
this.secondRowHeight = secondRowEl.offsetHeight;
}
}
How will i solve that #mouseover issue and display paddles normally ?

In FabricJS, how can I identify through a set of objects that overlap at the coordinates where the mouse is clicked?

I need to be able to iterate through a set of objects that overlap each other at the coordinates where the mouse if clicked. As a follow-on, I would use bringToFront and then display a nice menu based on that object but I'm unsure of how to even identify and iterate on the set of objects.
My specific need was to iterate over a set of overlapping objects by pressing the tab key to set the active object/group. Below is what I did:
var stackArray = new Array();
canvas.on('mouse:down', function(e){
var subobj = canvas.getObjects();
stackArray = [];
for (var i=0;i<subobj.length;i++) {
if (subobj[i].id != '' && typeof(subobj[i].id) != 'undefined' && subobj[i].id != 'navpanel' && subobj[i].id != 'header') {
if (e.target!=null && typeof(e.target.id) != 'undefined') {
if (subobj[i].intersectsWithObject(canvas.getActiveObject()) && subobj[i].id != e.target.id) {
stackArray.push(subobj[i]);
} else if (subobj[i].id == e.target.id) {
stackArray.push(subobj[i]);
}
}
}
}
});
...
e.preventDefault();
switch(e.keyCode){
case 9: // tab
if (stackArray.length > 1) {
fillObj(canvas.getActiveObject(),'inactive');
canvas.getActiveObject().sendToBack();
canvas.setActiveObject(stackArray[stackArray.length-1]);
fillObj(canvas.getActiveObject(),'active');
stackArray.splice(0, 0, stackArray.splice(stackArray.length-1,1)[0]);
}
break;
}
function fillObj(obj,mode) {
if (obj.type == 'group') {
obj = obj.item(0);
}
if (mode == 'active') {
obj.set('fill', 'red');
obj.set('strokeWidth', 1);
obj.set('shadow','rgba(0,0,0,0.5) 5px 5px 15px');
} else if (mode == 'inactive') {
obj.set('fill', '#333');
obj.set('strokeWidth', 0);
obj.set('shadow','');
}
}

Animate CC HTML5 - toggle fullscreen

I have this code (below) on a buton to force my HTML5 game to fullscreen, but I'd like to have it turn back also with the button - right now it only works using ESC key. Is it possbile?
this.fsbtn.addEventListener("click", doFullscreen);
function doFullscreen() {
var i;
var elem = document.getElementById("animation_container");
var fs = ["requestFullscreen", "webkitRequestFullscreen", "mozRequestFullScreen", "msRequestFullscreen"];
for (i = 0; i < 4; i++) {
if (elem[fs[i]]) {
elem[fs[i]]();
break;
}
}
}
Sure it's possible. Change your doFullscreen function to a toggle one that checks if it's fullscreen or not:
function toggleFullscreen(event) {
var element = document.body;
if (event instanceof HTMLElement) {
element = event;
}
var isFullscreen = document.webkitIsFullScreen || document.mozFullScreen || false;
element.requestFullScreen = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || function () {
return false;
};
document.cancelFullScreen = document.cancelFullScreen || document.webkitCancelFullScreen || document.mozCancelFullScreen || function () {
return false;
};
isFullscreen ? document.cancelFullScreen() : element.requestFullScreen();
}
Read the documentation here for fullscreen API
You can exit from fullscreen mode using functions listed below(for more read documentation)
In JS/HTML code you can add button with absolute position and high z-index. Write new click listener for added button and run cancelFullscreen function, that's all.
Example JS function for FullScreen mode:
function toggleFullScreen() {
if (!document.mozFullScreen && !document.webkitFullScreen) {
if (videoElement.mozRequestFullScreen) {
videoElement.mozRequestFullScreen();
} else {
videoElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
if (document.mozCancelFullScreen) {
videoElement.mozCancelFullScreen();
} else {
videoElement.webkitCancelFullScreen();
}
}
}
Working example you can see here: https://developer.mozilla.org/samples/domref/fullscreen.html

Trying to debug a custom .sort in a JS array

A link to the Plunker.
I've been working on a button and list system in jQuery for awhile now. Recently I decided to make my code more reproducible. I want to make it so I just have to add classes or IDs, and I don't have to add any additional code. I'm very close to doing that for my entire site. So if you go to this site specifically you will see it in action.
If you click on any buttons, in any order, it will arrange chronologically.
The bugs come from closing them.
If you click at least three, close the middle one, then click a new button, the sort function falls apart and that closed middle one is now floating with the wrong class.
Below is my current jQuery. On my site, ignore the "All Years" button. I'll work on that after I figure out this bug.
//the variables needed for the floating buttons
var groupArray = $(".yearGroup");
var buttonArray = $(".buttonGroup");
var hideGroupArray = $(".hideGroup");
var closeBarArray = $(".closeBar");
var closeBar = $("#allCloseBar");
var allButtonArray = [];
sortElements = function(a,b)
{
if (a.text() < b.text())
{
return -1;
}
else if (a.text() > b.text())
{
return 1;
}
else
{
return 0;
}
}
$.each(buttonArray, function(i, item) {
$(this).click(function(){
console.log($(buttonArray[i]).text())
console.log($(closeBarArray[i]).text())
//for removing the tooltip when the button is clicked. Mostly for Firefox bug
$(".ui-tooltip-content").parents('div').remove();
$(hideGroupArray[i-1]).slideToggle(slideToggleDuration, function(){
htmlBody.animate({scrollTop: $(groupArray[i-1]).offset().top - 25}, {duration: timeDuration, easing: 'easeOutBack'});
$(buttonArray[i]).toggleClass("float", 1200);
if ($(groupArray[i-1]).height() > 0)
{
//This will stop any animations if the user scrolls.
htmlBody.bind("scroll mousedown DOMMouseScroll mousewheel keyup", function(e)
{
if ( e.which > 0 || e.type === "mousedown" || e.type === "mousewheel"){
htmlBody.stop().unbind('scroll mousedown DOMMouseScroll mousewheel keyup');
}
});
closeBar.addClass("floatCloseBar");
$(closeBarArray[i]).hide();
allButtonArray.splice(0, 0, $(buttonArray[i]));
var timer;
var delay = 1500;
$(buttonArray[i]).hover(function() {
//This will stop any animations if the user scrolls.
htmlBody.bind("scroll mousedown DOMMouseScroll mousewheel keyup", function(e)
{
if ( e.which > 0 || e.type === "mousedown" || e.type === "mousewheel"){
htmlBody.stop().unbind('scroll mousedown DOMMouseScroll mousewheel keyup');
}
});
var link = $(groupArray[i-1]);
var offset = link.offset();
var top2 = offset.top;
var left = offset.left;
var bottom = top2 + $(groupArray[i-1]).outerHeight();
//bottom = Math.abs(bottom - offset.top);
var right = $(window).width() - link.width();
right = Math.abs(offset.left - right);
var scrollDuration = 0;
if (inRange($(buttonArray[i]).offset().top, $(groupArray[i-1]).position().top, bottom))
{
//console.log("fast");
scrollDuration = 500;
//$(group).addClass("hoverYear");
}
else if ($(buttonArray[i]).offset().top <= $(groupArray[i-1]).offset().top && allButtonArray.length == 1)
{
//console.log("fast");
scrollDuration = 500;
//$(group).removeClass("hoverYear");
}
else if ($(buttonArray[i]).offset().top > 495 && $(buttonArray[i]).offset().top < 1700 && !inRange($(buttonArray[i]).offset().top, $(groupArray[i-1]).position().top, bottom))
{
scrollDuration = 1000;
//console.log("slow");
//$(group).removeClass("hoverYear");
}
else if ($(buttonArray[i]).offset().top > 1701 && $(buttonArray[i]).offset().top < 3000 && !inRange($(buttonArray[i]).offset().top, $(groupArray[i-1]).position().top, bottom))
{
scrollDuration = 1500;
//console.log("slower");
//$(group).removeClass("hoverYear");
}
else if ($(buttonArray[i]).offset().top > 3001 && $(buttonArray[i]).offset().top < 6000 && !inRange($(buttonArray[i]).offset().top, $(groupArray[i-1]).position().top, bottom))
{
scrollDuration = 2000;
//console.log("much slower");
//$(group).removeClass("hoverYear");
}
else if ($(buttonArray[i]).offset().top > 6001 && !inRange($(buttonArray[i]).offset().top, $(groupArray[i-1]).position().top, bottom))
{
scrollDuration = 2500;
console.log("the slowest");
//$(group).removeClass("hoverYear");
}
else
{
scrollDuration = 500;
}
//to prevent the various hover states to take control when the button isn't floating
if (!($(buttonArray[i])).hasClass("float"))
{
scrollDuration = 0;
console.log("doesnt have class")
}
// on mouse in, start a timeout
timer = setTimeout(function() {
//the delay for the hover scroll feature
htmlBody.animate({scrollTop: $(groupArray[i-1]).offset().top}, scrollDuration, 'easeInOutCubic');
}, delay);
}, function() {
// on mouse out, cancel the timer
clearTimeout(timer);
});
$.each(allButtonArray, function(j, val){
$(allButtonArray[j]).appendTo(closeBar);
console.log(allButtonArray.length);
arrowDown.show();
arrowUp.show();
arrowDown.prependTo(closeBar);
arrowUp.appendTo(closeBar);
//Changes the width of the buttons based upon how many are on the screen
if (allButtonArray.length > 7)
{
$("float").css('width', '7%');
$(val).css('width', '7%');
$(allButtonArray[0]).css('width','7%');
allButtonArray.sort(sortElements);
//console.log(val);
}
else if (allButtonArray.length <= 7)
{
$(val).css("width", '10%');
$("float").css("width", '10%');
allButtonArray.sort(sortElements);
//console.log(val);
}
});
}
if ($(groupArray[i-1]).height() == 0)
{
$(buttonArray[i]).css("width", '50%');
allButtonArray.splice(allButtonArray.indexOf($(buttonArray[i])), 1);
console.log(allButtonArray.length);
$(closeBarArray[i]).show();
$(buttonArray[i]).appendTo($(closeBarArray[i]));
arrowDown.show();
arrowUp.show();
arrowDown.prependTo(closeBar);
arrowUp.appendTo(closeBar);
}
if (group2001.height() == 0 && group2002.height() == 0 && group2003.height() == 0 && group2004.height() == 0 && group2005.height() == 0 && group2006.height() == 0 && group2007.height() == 0
&& group2008.height() == 0 && group2009.height() == 0 && group2010.height() == 0 && group2011.height() == 0 && group2012.height() == 0)
{
$(closeBarArray[i]).removeClass("floatCloseBar");
htmlBody.animate({scrollTop: revealAllButton.offset().top - 75}, 500);
arrowDown.hide();
arrowUp.hide();
//console.log($(document).height() + " the current height");
}
});
$(buttonArray[i]).toggleClass("openClose");
$(buttonArray[i]).toggleClass("openClose2");
});
});
function inRange(x, min, max){
return (x >= min && x <= max);
}
If you would like a reference to what worked previously, I could post that code. It is much more bulky and much less organized. I've tried many different things to eliminate the bug but I'm at a loss. My knowledge of JS scope is limited.
And thanks for any help, it is very much appreciated.

Animation fade | jQuery vs pure js | setInterval vs. setTimeout

I have this tested function below that works fine for fading an element in or out.
What do I gain by using JQuery?
Thanks
Effects.prototype.fade = function( direction, max_time, element )
{
var elapsed = 0;
function next() {
elapsed += 10;
if (direction === 'up')
{
element.style.opacity = elapsed / max_time;
}
else if (direction === 'down')
{
element.style.opacity = (max_time - elapsed) / max_time;
}
if (elapsed <= max_time) {
setTimeout(next, 10);
}
}
next();
};
Running a search on fadeIn() on the core jquery library I get one hit here:
jQuery.each({
slideDown: genFx( "show", 1 ),
slideUp: genFx( "hide", 1 ),
slideToggle: genFx( "toggle", 1 ),
fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" },
fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
jQuery.fn[ name ] = function( speed, easing, callback ) {
return this.animate( props, speed, easing, callback );
};
});
Using the JQuery Source Viewer
function (prop, speed, easing, callback) {
var optall = jQuery.speed(speed, easing, callback);
if (jQuery.isEmptyObject(prop)) {
return this.each(optall.complete, [false]);
}
prop = jQuery.extend({},
prop);
return this[optall.queue === false ? "each" : "queue"](function () {
if (optall.queue === false) {
jQuery._mark(this);
}
var opt = jQuery.extend({},
optall),
isElement = this.nodeType === 1,
hidden = isElement && jQuery(this).is(":hidden"),
name, val, p, display, e, parts, start, end, unit;
opt.animatedProperties = {};
for (p in prop) {
name = jQuery.camelCase(p);
if (p !== name) {
prop[name] = prop[p];
delete prop[p];
}
val = prop[name];
if (jQuery.isArray(val)) {
opt.animatedProperties[name] = val[1];
val = prop[name] = val[0];
} else {
opt.animatedProperties[name] = opt.specialEasing && opt.specialEasing[name] || opt.easing || "swing";
}
if (val === "hide" && hidden || val === "show" && !hidden) {
return opt.complete.call(this);
}
if (isElement && (name === "height" || name === "width")) {
opt.overflow = [this.style.overflow, this.style.overflowX, this.style.overflowY];
if (jQuery.css(this, "display") === "inline" && jQuery.css(this, "float") === "none") {
if (!jQuery.support.inlineBlockNeedsLayout) {
this.style.display = "inline-block";
} else {
display = defaultDisplay(this.nodeName);
if (display === "inline") {
this.style.display = "inline-block";
} else {
this.style.display = "inline";
this.style.zoom = 1;
}
}
}
}
}
if (opt.overflow != null) {
this.style.overflow = "hidden";
}
for (p in prop) {
e = new jQuery.fx(this, opt, p);
val = prop[p];
if (rfxtypes.test(val)) {
e[val === "toggle" ? hidden ? "show" : "hide" : val]();
} else {
parts = rfxnum.exec(val);
start = e.cur();
if (parts) {
end = parseFloat(parts[2]);
unit = parts[3] || (jQuery.cssNumber[p] ? "" : "px");
if (unit !== "px") {
jQuery.style(this, p, (end || 1) + unit);
start = (end || 1) / e.cur() * start;
jQuery.style(this, p, start + unit);
}
if (parts[1]) {
end = (parts[1] === "-=" ? -1 : 1) * end + start;
}
e.custom(start, end, unit);
} else {
e.custom(start, val, "");
}
}
}
return true;
});
}
Usually you don't include a library like jQuery just for a single effect, but as a general purpose library in order to simplify things such as DOM manipulation, AJAX calls, setting CSS properties in a way that's cross-browser, in addition to applying effects (such as .fadeIn/.fadeOut) and other applications.
Tipically it's recommended you don't add jQuery for just a simple call. But my reasoning is that you are probably be going to exploit more and more of it's features in the long run, so I don't see a real reason not to use it.
On the subject of implementing your own fadeIn or fadeOut functions, you could look at the jQuery source and extract those methods, or make your own implementation from scratch. But given the fact that jQuery already implemented this method, I don't see why you would want to replicate it, other than for educational purposes.
The biggest reason to use JQuery over your custom code, in my opinion, is that you don't have to maintain the code for multiple browsers and multiple versions. JQuery does a good job of handling the quirks of the major browsers for you.
In addition, there are many other excellent uses for JQuery that you may want to use later.
Concerning the code, when you download JQuery: http://docs.jquery.com/Downloading_jQuery you can get the uncompressed version, which is intended to be readable.
I don't know of a simple way to get only those functions out of JQuery. Why not use the full library?

Categories