Can not drag slider handles - javascript

I've created a time range slider (noUiSlider) programmatically.
It's working fine except that, I'm NOT able to drag the slider handles (that is available as a default behaviour), in order to change the slider value(s).
var noUiSlider = require('./js/nouislider');
var sliderDiv = document.createElement("div");
sliderDiv.id = "slider-"+soundElement.description;
var sliderElem: any = noUiSlider.create(sliderDiv, {
start: [0, 50],
tooltips: [true, true],
behaviour: "tap-drag",
connect: true,
orientation: 'vertical',
range: {
min: 0,
max: 100
}
});
soundElementIframe.appendChild(sliderDiv);
I've not been able to figure out, why drag interaction is not working (while everything else like 'tap' is working fine). I'd really appreciate any help around this.

What I think is happening is that you create your slider, then when you append it, it loses its (default?) listeners. To avoid this, append your div then initialize the noUiSlider element.
const sliderDiv = document.createElement('div');
soundElementIframe.appendChild(sliderDiv);
noUiSlider.create(sliderDiv, options);
If this still doesn't work, try reselecting the new appended sliderDiv element and passing that into the noUiSlider.create() method.

Related

Since updating animejs my javascript no longer functions

Essentially I had an 'animejs' animation trigger when the nav button is clicked and then the same animation would reverse after a second click. It would toggle. Now this no longer works after updating animejs.
I've tried using a variable such as
var playing = true; and to toggle between it but that doesn't possess the same functionality as before.
the code looked something like this (this is simplified)
var navAnimation = anime.timeline({
duration: 100,
});
animation.add({
targets: 'navStuff'
//animation would be here
});
document.querySelector('.nav').onclick = () => {
animation.play();
// animation.play still functions properly
animation.reverse();
// animation.reverse(); is broken
};
//before the update you could simply place a two methods within the onclick function and it would toggle between them but that no longer is the case with animejs
What I want to happen is to be able to use a single target (button) to open my navigation and close it (toggle between the two state). I want to be able to spam the button and not see and glitches (as before).
Please beleive me I've spent an uncessary amount of time trying to get this working and it just refused to giv in.
I've attempted working with heights / transforms / colors, variable diffs, close inspection. Nothing works.
This is how I animate "reverses" now:
const notificationsContainerElement = document.querySelector('#demo-install-notifications-container');
let notificationsContainerAnimation = anime({
targets: notificationsContainerElement,
height: '350px',
easing: 'easeOutElastic(1.5, .5)',
duration: 1500,
delay: 0,
autoplay: false,
});
notificationsContainerElement.addEventListener('click', () => {
if(notificationsContainerAnimation.began === false) {
notificationsContainerAnimation.play();
} else if(notificationsContainerAnimation.began === true) {
notificationsContainerAnimation.began = false;
anime({
targets: notificationsContainerElement,
height: '100px',
easing: 'easeOutElastic(1.5, .5)',
duration: 1500,
delay: 0,
});
}
});
My first animation is autoplay: false, then, when I click an element, I .play() that animation, but notice the checks for the original animation's began. Once you hit play on an animation, the began property keeps changing.
Right...
But just doing notificationsContainerAnimation.reverse() on my animation just doesn't work no matter what. It just doesn't. I strongly believe it has to do with anime not being able to get where it's supposed to actually reverse to - the values.
The logic is sound, there's no way why it shouldn't work...but it doesn't.
So, for now, use 2 animations.

setAttribute for animation component 'to' attribute using position fails to set

I'm using A-Frame (webVR) to make a multi panorama explorer. The world has a few 3d buttons (with panorama mapped spheres at each button position). You click on a button, and an animation component moves the camera from its current location to the button location. A custom component containing a listener (for click events on buttons), uses setAttribute to set the 'to' and 'from' attributes of an animation component on the camera. An emit command triggers the animation. Unfortunately it fails, and I can see that the 'from' attribute is not setting correctly (it is setting to the same as 'to'). It doesn't throw errors, but I can see in the console that the from will not set,even though I set it explicitly.
I've already got this working in a previous version. You can see and test it here:
https://glitch.com/~camera-jumper
In this version, I don't set the from attribute, and it still works fine, presumably because it takes the previous value as a default.
Then I built in some other functionality and now it is failing. You can see the current version here:
https://glitch.com/~panojumper
AFRAME.registerComponent('buttoncontrol', {
schema: {
pano:{type:'string',default: 'pSphere1'}
},
init: function(){
var el = this.el;
var cam = document.querySelector('#camera');
var panoManEntity = document.querySelector('#panoMan');
var panoName = this.data.pano;
console.log(cam.getAttribute('animation__jump', 'to'));
this.el.addEventListener('click', function(evt){
// Animate the camera moving to the button position
var btnpos = el.getAttribute('position');
var cam = document.querySelector('#camera');
var campos = cam.getAttribute('position');
cam.setAttribute('animation__jump','to', {x: btnpos.x, y:
btnpos.y, z: btnpos.z });
cam.setAttribute('animation__jump','from', {x: campos.x, y:
campos.y, z: campos.z });
cam.emit('camjump');
});
}
});
I expect setAttribute for 'from' to be what I am setting it to, but it is the same as the 'to' value.
Setting the from attribute seems to be working, you can verify it by modifying your first glitch. Add the from attribute, and its still working properly:
var campos = cam.getAttribute('position')
// Animate the camera moving to the button position
cam.setAttribute('animation__jump','to', {x: btnpos.x, y: btnpos.y, z: btnpos.z });
cam.setAttribute('animation__jump','from', {x: campos.x, y: campos.y, z: campos.z });
fiddle here.
The other glitch will also work if you register the custom components in the <head> or at least before the <a-scene>. There is also a note on it in the docs.
fiddle here.
You nailed it! Custom components must not be in the scene, but in the head. I moved it because my assets tag was before the scene tag, which threw an error, so I moved the scene tag too far north. Moving the scene tag below registerComponents solved it.
All of this is in the docs, but I'm a noob. Thanks for your help!

Advance slick slider when image in gallery is clicked (multiple slick sliders on one page)

I came across this modification for slick slider for advancing when clicking on the current image (see below). When I implement it on my page with multiple galleries it advances all galleries when I click on one, not only the one selected. Is there a possibility to use e.g. "this" selector in here?
http://codepen.io/ethanclevenger91/pen/MYNGrN
window.onload=function(){
$slideshow = $('.slider').slick({
dots:false,
autoplay:false,
arrows:false,
adaptiveHeight: true,
slidesToShow:1,
slidesToScroll:1
});
$(".slide").click(function() {
$slideshow.slick('slickGoTo', parseInt($slideshow.slick('slickCurrentSlide'))+1);
});
};
Please see the following codepen: http://codepen.io/anon/pen/ZOGmWo?editors=1010
The main idea is to define each slider separately.
First, define an object to hold all the sliders:
var sliders = {};
Then, looping through all the sliders, extracting the ID and saving a reference to the newly defined slider in our map, indexed by the ID:
$('.slider').each(function (index, slider) {
var id = slider.getAttribute('id');
console.log(id);
sliders[id] = $(slider).slick({ ... })
});
Now, on the click handler, we determine to which slider do the clicked slide belong to, using $(this).closest('.slider') and using progressing it.
$('.slide').click(function() {
var id = $(this).closest('.slider').get(0).getAttribute('id');
var $slideshow = sliders[id];
$slideshow.slick('slickGoTo', parseInt($slideshow.slick('slickCurrentSlide'))+1);
});

Getting swipeJS to work with ajax loaded content

I am making a site currently being tested at test2.applicationcreations.net. With an image gallery that dynamically changes the images. I'm using swipeJS for the slider.
When you navigate to project gallery then to custom homes the new HTML with correct formatting loads in but the rotator does not work. I believe the problem is that swipeJS is not initialized on the new code. I have tried passing the new items to the object using window.mySwipe = new Swipe(document.getElementById('slider')); but I have had no luck.
For some reason if I click on inspect element on Chrome 18 OS X the rotator works with the new content.
Any help getting this working is greatly appreciated. Thank you.
Yup, you got it right, once you have added the new element, all you need to do is reinitialize the mySwipe object.
This is the first initialization of the swipe slider object:
/*----------------------------------------
Swipe slider to enable touch sliding
----------------------------------------*/
document.mySwipe = new Swipe(document.getElementById('slider'), {
startSlide: 0,
speed: 400,
auto: 5000,
callback: function(event, index, elem) {
// do something cool
}
});
Now just define a method which re-initializes the swipe object.
/*----------------------------------------
Reinitializing the Swipe Slider.
----------------------------------------*/
document.reinit = function(){
document.mySwipe = new Swipe(document.getElementById('slider'), {
startSlide: 0,
speed: 400,
auto: 5000,
callback: function(event, index, elem) {
// do something cool
}
});
}
Call that method when you have finished adding new elements to the existing slider.
// Finished adding new elements
document.reinit();

grumble.js, jQuery plugin (Bubble popups): how to make it not polute my document body with unremovable trash?

I want to show a popup many on click. I want that many to be in a bubble. So I created a demo: here. But that Bubble generator plugin i use tends to keep tons of trash in the DOM each time it shows a popup. Well so I tried to destroy trash via
$('.grumble-text').remove();
$('.grumble').remove();
$('.grumble-button').remove();
But it somehow brakes it at all=( So how to change grumble-bubble popup plugin code to make it either keep DOM clean or at least make plugin independent of trash it creates?
I've recently updated the plugin to provide better control of positioning and angle. The update also persists the grumble, invoking the plugin more than once on an element will not create extra left over DOM.
Try updating to the latest code. The code below should now work as you expect.
var html = ''
+'Download me'
+'<br/>'
+'Edit me'
+'<br/>'
+'Delete me';
var $grumble = $('#grumble3');
$grumble.mouseup(function(eventObj) {
$grumble.grumble({
text: html ,
angle: (Math.random() * 360 + 150),
distance: 30,
hideOnClick: true,
onShow: function() {
$grumble.addClass("hilight");
},
onBeginHide: function() {
$grumble.removeClass("hilight");
}
});
}).mousedown(function() {
$grumble.addClass("hilight");
});
Thanks for your interest. If there are any further problems please raise them as bugs on the github page. https://github.com/jamescryer/grumble.js
Use the grumble and button parameters on the onHide callback like this:
$('#grumble').grumble({
text: 'Whoaaa, this is a lot of text that i couldn\'t predict',
angle: 85,
distance: 50,
showAfter: 4000,
hideAfter: 2000,
onHide: function(grumble, button) {
grumble.bubble.remove();
grumble.text.remove();
button && button.remove();
}
});
This allows you to remove only the "trash" (I prefer "leftovers") associated with that specific tooltip/popup/bubble. Note that button only exists if hasHideButton is true, hence the button && existence check.
Why do you want to remove it? Is the 'trash' causing problems with browser performance?
In general, the only way to do this is to dig into the plugin source and add a function to remove the plugin, if one is not already present. If you just remove the related DOM elements you will leave behind references to them and events handlers that access them.

Categories

Resources