How do I limit the range of my draggable SVG shape? - javascript

I have an SVG slider that I've been working on ... please see it on jsFiddle here.
I would like to limit the range of my sliders.
My JS started out as found on this picker (thanks to #Phrogz), then I poked and prodded at it until I was able to strip it down to its current state.
The sliders are working great, but I can really use some guidance on adding the limitations.
For example, I'd like slider_1 (the slider on the left) to be limited to the area in front of the blue rectangle.
JS is still pretty unnatural for me, so I'd appreciate any and all feedback.
Thanks-a-bunch.

Try throwing something like this into your move functions:
var limitLower = 0;
var limitUpper = 20;
if ( x < limitLower || x > limitUpper ) {
return;
}
Here's a fiddle with the above code inserted for slider1: http://jsfiddle.net/ucnyz/4/

Related

How to increase speed of mousemove/clientX/Y and applying a transform?

I have built a WordPress theme. I came across a website that created a div to follow the user's cursor. The div was enlarged smoothly when the user hovers over a button or a link.
I want to add this nice functionality as an optional feature.
I added a div to the web page, #ambition_cursor and added some basic styling. The div now shows like a blue circle. The circle has position fixed to the top left corner of the site. The position can be changed by adding a CSS translate property.
I managed to make it work with the following code:
var ambition_cursor = document.getElementById("ambition_cursor");
function ambition_mouse(e) {
var ambition_cursor_x = e.clientX; // Get the horizontal coordinate
var ambition_cursor_y = e.clientY; // Get the vertical coordinate
var ambition_cursor_pos = `translate(${ambition_cursor_x}px, ${ambition_cursor_y}px)`;
ambition_cursor.style.transform = ambition_cursor_pos;
}
window.addEventListener('mousemove', ambition_mouse);
The big downside here is the lag (?). There's quite a big delay, especially when moving the mouse around very fast. You can try it out on this site. I also put the situation in a JSFiddle; although the delay doesn't really happen there.
I didn't apply yet much styling (the default cursor is visible, so you can get a better idea of the real position). I first want this to work better, before I spent much time on that.
How can I increase the speed of this, so that the div position follows the mouse more accurately? I'm a beginner, so I don't really know which JavaScript optimisations I should make.
Current code is JavaScript, but jQuery is also an option.
Many thanks in advance!
Update: example how it looks on my computer.
All elements on the page have a transition applied. Remove/override this style and the delay goes away (tested).
As an alternative to the great answer of Joseph Atkinson:
var ambition_cursor = document.getElementById("ambition_cursor");
function ambition_mouse(e) {
ambition_cursor.style.left = e.clientX + 'px'; // Get the horizontal coordinate
ambition_cursor.style.top = e.clientY + 'px' ; // Get the vertical coordinate
}
window.addEventListener('mousemove', ambition_mouse);
See: https://levelup.gitconnected.com/use-javascript-to-make-an-element-follow-the-cursor-3872307778b4
I visited the site example, cracked open the dev console, and found throttled(20, ambition_mouse) It is not a performance issue, and the solution is to not throttle the events. It was too smooth to be a performance issue, which gave me the first clue it had to be an accidental/deliberate effect.

Basic JS - Is this function okay?

I have a carousel (Owl Carousel) with vertically centered controls. Because of the structure, I have to absolutely position the previous and next arrow. Because the page is responsive, their position is dynamic. The size of the controls may also change.
I've written a function that runs on load and resize. It gets the height of the image and the height of the controls, subtracts the latter from the former, divides by two, and then uses that number as the controls' margin-top.
It works, but I'm questioning if I'm getting and using all the variables correctly. Does JavaScript read in order? Where it runs the first line, then the next, then the next... I'm strong in CSS but JS has always been a crutch.
Can I write this more efficiently?
function centerCarouselControls() {
var carouselImage = $('.carousel-card > img');
var carouselControls = $('.owl-nav > div');
var carouselHeight = carouselImage.outerHeight();
var controlHeight = carouselControls.outerHeight();
var controlMargin = (carouselHeight - controlHeight) / 2;
carouselControls.css('margin-top', controlMargin);
}
$('.carousel-card > img').load(centerCarouselControls);
$(window).on('resize', centerCarouselControls);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I feel like this might be the type of question that gets flagged on here for not being specific enough. If that's the case, could someone please point me to a community where this would be more appropriate? Thanks!
In some browsers your code works like firefox 51, but it is more complete code this:
carouselControls.css('margin-top', controlMargin + 'px');

Set draggable bars to custom start position with javascript in Qualtrics

In Qualtrics, it is possible to set the starting position of draggable bars (i.e., their width) with a "Custom Start Position". This is done by dragging the bars to the desired width while editing the survey. However, I am looking for a way to set the width of the bars to a start position with JavaScript (or Prototype JavaScript).
Here are my attempts, first (successfully) trying to change the color of the bars (in qualtrics and on jsfiddle), then (successfully) trying to adapt these attempts to change the bar widths on jsfiddle; and then getting stuck because what works on jsfiddle does not work on Qualtrics.
In Qualtrics, I can change the color of draggable sliders with the following Prototype JavaScript (adapted from this answer):
Qualtrics.SurveyEngine.addOnload(function()
{
//change the color of all bars to red for testing
$(this.questionId).select('.bar').each(function(name, index) {
name.style.backgroundColor = "red";
});
});
The result can be seen (and inspected) here. Inspecting the survey in the link indeed shows that the background-color was set to red:
<div id="QID2~2~bar" class="bar" style="width: 103px; background-color: red;"></div>. A width argument is also present, meaning I should be able to modify the width with the following code (which indeed does work on jsfiddle when setting the library to prototype):
$("test").select('.bar').each(function(name, index) {
name.setStyle({ width: '40px'});
});
However, this code does not work on Qualtrics (when replacing $("test") with $(this.questionId) and including the code in Qualtrics addOnload function).
The following javascript also works on Qualtrics for changing bar colors (adapted from this answer):
Qualtrics.SurveyEngine.addOnload(function()
{
//change the color of all bars to red for testing
var bar = document.querySelectorAll('.bar');
for (var i=0; i < bar.length; i++) {
bar[i].setAttribute("style", "background-color:red");
}
});
With this code, I can also adjust the div width on jsfiddle:
var bar = document.querySelectorAll('.bar');
for (var i=0; i < bar.length; i++) {
bar[i].setAttribute("style", "width:40px");
}
However, again this has no effect in Qualtrics.
So, long story short: Is there a way to programmatically give the bars in Qualtrics a start position, e.g., by setting their width to 50% of the parent div?
Update:
After digging deeper into the Qualtrics Question API, I found setChoiceValue with which I can programmatically select multiple choice items. E.g.,
Qualtrics.SurveyEngine.addOnload(function()
{
this.setChoiceValue(2,true);
});
will select the 2nd radio-button by setting its value to true:
However, so far I was unable to either apply setChoiceValue to draggable bars or find a similar equivalent.
Update 2:
Qualtrics Support (who are very friendly and approachable) has suggested that setChoiceAnswerValue might be what I am looking for. However they also explained that they cannot provide customer support for JavaScript. I took a look at a more recent version of the API documentation which also lists setChoiceAnswerValue, but so far without success.
I must have made a typo in my original code, as it turns out that what I had started with actually works:
Qualtrics.SurveyEngine.addOnload(function()
{
$(this.questionId).select('.bar').each(function(name, index) {
name.setStyle({ width: '50px'});
});
});
Here is a solution for setting the custom start positions for draggable bars using the setChoiceValue method as documented in the Qualtrics Question API.
Below is an example code for a question with 10 bars using embedded data from previous questions.
var embedded = ["${e://Field/r1}", "${e://Field/r2}",
"${e://Field/r3}", "${e://Field/r4}", "${e://Field/r5}",
"${e://Field/r6}", "${e://Field/r7}", "${e://Field/r8}",
"${e://Field/r9}", "${e://Field/r10}"];
for (var i = 0; i < 11; i++) {
var index = i + 1;
var choiceInput = embedded[i];
this.setChoiceValue(index, choiceInput);
}
For setting the custom value of one bar:
Qualtrics.SurveyEngine.addOnload(function()
{
this.setChoiceValue(2, "80");
});

Delayed autoscroll effect on a block of text

Im fairly new to JS... please be gentle.
Can anyone suggest a way to pull off a delayed autoscroll effect on a block of text?
It's important to mention that my ultimate goal is to use this on a popup modal window, on iOS devices. And because iOS browsers do not display the scrollbar until user interaction, I am resorting to the auto-scroll.
In effect: I would like the page to load, wait a couple of seconds, then have begin to slowly scroll down. The scroll is intended to be a hint to the user that there is more content available, therefore if there is any way to stop or temporarily pause the auto-scroll on user interaction- that would be optimal.
I have searched for my answers a couple of hours now, but between not being able to initialize the found code to my design (again, I'm fairly green), and not being able to find a solution that achieves everything I need - I am turning to brighter minds.
I have set up a fiddle with my HTML and CSS: http://jsfiddle.net/zfMsQ/
Any help is greatly appreciated!
ps: This is my very first post on StackOverflow :)
My code:
Extensive. Linked above.
Here you go: http://jsfiddle.net/zfMsQ/3/
var roll = true;
var max = 0;
var text = $("#content");
function scroll() {
text.scrollTop(text.scrollTop() + 1)
var top = text.scrollTop()
if (top > max) {
max = top
if (roll) {
setTimeout(scroll, 50)
}
}
}
text.on("mouseenter mouseover mousedown", function(){
roll = false;
})
setTimeout(scroll, 2000)

getting the positions of multiple images using javascript

What I want to achieve is when the user stops scrolling I want to position the closest image to the centre to the centre. This will, I think, involve me running a series of if statements to determine which image is closest to the centre. I will be able to do this but before that the offsets I am getting are wrong. I am struggling to get my head around getting the images positioning's I know it has something to do with offset but I need some guidance because the offset values are not right. Take a look at this link http://bit.ly/PDz2JD and look at the function setupHscroll within that look at getImageOffset I think this is where the problem lies.
function getImageOffset() {
var arr = new Array;
var images = document.getElementById("container").getElementsByTagName("img");
for (var i = 0, l = images.length; i < l; i++) {
arr.push(images[i].offsetLeft);
console.log(images[i].offsetLeft - rect.left);
}
return arr;
}
Please help and if possible help me understand. Thanks and am I using the right thing to get the position of an image.
See http://www.w3.org/TR/cssom-view/#offset-attributes
offsetLeft will retrieve the offset relative to the offsetParent.
If you can, I would recommend bringing in jQuery for the $.offset() functionality.
Otherwise, try this: http://www.quirksmode.org/js/findpos.html
In your simple case, you can do something like this: for every image (or better, every <div> that contains it), take its offsetLeft and add half of its offsetWidth. Then take the offsetWidth of #container and divide it by two, then subtract the amount of its marginLeft style property.
Find the image which has its value closest to this one and you're done with it.

Categories