<script>
var animate = function (element, target, callback) {
clearInterval(element.timer);
element.timer = setInterval(function () {
var step = (target - element.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
element.style.left = element.offsetLeft + step + 'px';
// console.log(element.offsetLeft);
if (element.offsetLeft == target) {
clearInterval(element.timer);
callback && callback();
}
}, 20)
};
window.addEventListener('load', function () {
var ul = document.querySelector('.local-nav');
console.log(ul);
for (var i = 0; i < ul.children.length; i++) {
ul.children[i].children[0].children[0].style.backgroundPosition = '0 ' + -i * 32 + 'px';
}
var ul2 = document.querySelector('.subnav-entry ul');
console.log(ul2);
for (var i = 0; i < ul2.children.length; i++) {
console.log(ul2.children[i].children[0].children[0]);
ul2.children[i].children[0].children[0].style.backgroundPosition = '0 ' + -i * 32 + 'px';
}
var focus_ul = document.querySelector('.focus ul');
var ol = document.querySelector('.focus ol');
var count = 0;
var focus_timer = setInterval(function () {
if (count == 2) {
animate(focus_ul, focus_ul.offsetLeft - 375);
// console.log('i run');
// console.log(focus_ul.offsetLeft + ' ' + count);
// focus_ul.style.left = focus_ul.offsetLeft + 375 * 2 + 'px';
focus_ul.style.left = 0 + 'px'; // Here is my problem
console.log(focus_ul);
console.log(focus_ul.offsetLeft + ' ' + count);
}
else {
console.log('before animation ' + focus_ul.offsetLeft + ' ' + count);
animate(focus_ul, focus_ul.offsetLeft - 375);
console.log(focus_ul.offsetLeft + ' ' + count);
}
// focus_ul.style.left = focus_ul.offsetLeft + 375 + 'px';
count++;
count = count % 3;
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[count].className = 'current-choice';
console.log('after a round ' + focus_ul.offsetLeft + ' ' + count);
}, 2500)
})
</script>
I meant to do a photo show that can play automaticly, like a Carousel or swiper, The 375px means that the screen is 375px wide, according to the code, when comming to the last photo, as the animation end, it should change back to the initial one which style.left == 0px, but 0px only occur a small while, next time it would be -1125px, -1500px and so on, I'm confused why i set style.left to 0 but fruitless. I'm new in front end ,thanks helping
You can use more of CSS (and less JavaScript) for this animation.
Declare two separate CSS class definitions for focus_ul. Use JavaScript to change the className of focus_ul.
Use CSS transition for animation of CSS offset-left property.
See: https://www.w3schools.com/css/tryit.asp?filename=trycss3_transition1
Write that custom className instead :hover in above example.
Related
how can I stop the infinite loop of the following Ken-Burns-Slider-script? I have 3 pictures and I would like to stop the slider after animation of the third picture. Try with stop() of slideRefresh did not work (or my coding was bad).
The full code of the script can be seen on GitHub. Thanks for your help.
(function($){
$.fn.slideshow = function(options){
var slides = $(this);
var settings = $.extend({
randomize: true,
slideDuration: 6000,
fadeDuration: 1000,
animate: true,
slideElementClass: 'slide',
slideshowId: 'slideshow'
}, options);
}
$('<div id="' + settings.slideshowId + '"></div>').insertBefore(slides);
var slideshow = $('#' + settings.slideshowId);
var slideTimeDelta = 0;
var resumeStartTime = 0;
var resumeTimer;
if(settings.animate == true){
var cssAnimationDuration = settings.slideDuration + settings.fadeDuration;
}else{
slides.find('.' + settings.slideElementClass + ' span.animate').removeClass('animate');
var cssAnimationDuration = 0;
}
console.log('Slideshow initialized.');
slides.find('.' + settings.slideElementClass + ':first span.animate').addClass('active').css('animation-duration', cssAnimationDuration + 'ms')
slides.find('.' + settings.slideElementClass + ':first').prependTo(slideshow);
var currentSlideStartTime = Date.now();
// Start interval loop
slidesInterval = setInterval(slideRefresh, settings.slideDuration);
console.log('Slideshow started.');
if(settings.pauseOnTabBlur == true){
$(window).focus(function() {
console.log('Window gained focus.');
if (paused == true) {
console.log('Resuming slideshow.');
resumeStartTime = Date.now();
paused = false;
$('#' + settings.slideshowId + ' span.active:last').removeClass('paused');
resumeTimer = setTimeout(function(){
slideTimeDelta = 0;
slideRefresh();
slidesInterval = setInterval(slideRefresh, settings.slideDuration);
}, settings.slideDuration - slideTimeDelta);
}
}).blur(function() {
paused = true;
console.log('Window lost focus, slideshow paused.');
if(slideTimeDelta != 0){
var timeSinceLastPause = Date.now() - resumeStartTime;
slideTimeDelta = slideTimeDelta + timeSinceLastPause;
console.log('Time since last pause within this slide: ' + timeSinceLastPause + ' ms');
}else{
slideTimeDelta = Date.now() - currentSlideStartTime;
}
console.log('Current slide at ' + slideTimeDelta + ' ms.');
$('#' + settings.slideshowId + ' span.active:first').addClass('paused');
clearInterval(slidesInterval);
clearTimeout(resumeTimer);
});
}
function slideRefresh() {
console.log('Slide refresh triggered.');
currentSlideStartTime = Date.now();
var slideshowDOM = slideshow[0];
if(slideshowDOM.children.length == 0) {
console.log('There are no slides in the slideshow.');
slides.find('.' + settings.slideElementClass + ':first').prependTo(slideshow);
}else{
slides.find('.' + settings.slideElementClass + ':first').prependTo(slideshow);
var slideElement = '#' + settings.slideshowId + ' .' + settings.slideElementClass;
$(slideElement + ':first span.animate').addClass('active').css('animation-duration', cssAnimationDuration + 'ms');
$(slideElement + ':last').fadeOut(settings.fadeDuration, function(){
$(slideElement + ':last span.animate').removeClass('active').css('animation-duration', '0ms');
$(slideElement + ':last').appendTo(slides);
slides.find('.' + settings.slideElementClass).show(0);
});
}
}
};
}( jQuery ));
I'm having some problem with this function. I ask sorry if the code looks a bit confused.
Basically what i'm trying to do is to divide some elements between the top and bottom of the documents having between them the same space circa.
i wrote this code but seems like the first "for" cycle goes loop ever and ever again.
** update**
so i improved the code and now the problem seems to be the variable "ifc"(if-counter). It suppose to increase by one every time that one of the if or else if is completed , but as you can see on the console it always remain 0 .
anyone can help?
thanks
var sizewidth = window.innerWidth;
var sizeheight = 3000;
function initialPosition(){
var els = document.querySelectorAll('.ico');
var tb = Math.round(els.length * 0.4);
console.log(tb);
var lr = els.length - tb;
var distPixEachTopBottom = sizewidth / (tb/2);
console.log(distPixEachTopBottom);
var distPixEachLefRight = sizeheight / (lr/2);
var nextTop = 0;
var nextLeft = 0;
var nextBottom = 0;
var nextRight = 0 ;
for (i = 0; i < els.length; i++) {
var ifc = 0;
console.log('i' + i);
if(i < tb){
var sf = 0;
for(;;){
console.log('sf' + sf + 'tb ' + tb);
if(ifc > 1){
console.log('ifc'+ ifc);
ifc = 0;
break
}else if(ifc == 0){
els[i].style.top = 0 +'px';
els[i].style.left = nextTop + 'px';
console.log('ifc ' + ifc + 'i ' + i + 'nexttop' + nextTop)
nextTop = nextTop + distPixEachTopBottom;
ifc++;
break;
}else if(ifc == 1){
els[i].style.bottom = 0 +'px';
els[i].style.right = nextBottom + 'px';
console.log('ifc ' + ifc + 'i ' + i + 'nextbottom' + nextBottom)
nextBottom = nextBottom + distPixEachTopBottom;
ifc++;
break;
}else{
console.log('else if problem')
break;
}
}
}else{
}
}
initialPosition();
update
i created a pen as you asked
codepen
So basically of all the boxes the 40% of them (6 in this case) should be divided between top and bottom but they go just on top.
So I solved by myself .
I put the var ifc before then any function .
Anyway thanks everyone
Hey all I have the html code below that should allow the page to scroll all the way down to the nextChatHolder element when you push the button.
It adds the chat bubble just fine at the bottom but I want it to scroll down to the nextChatHolder each time I press the button.
I have no errors and these examples work standalone. So naturally there somewhere in my javascript or css that is causing it not to scroll - and I am unable to find what that it!
Visual: https://jsbin.com/xihosicayo/edit?js,output
function getElementY(query) {
return window.pageYOffset + document.querySelector(query).getBoundingClientRect().top;
}
function scrollToItem(item) {
var diff = (item.offsetTop-window.scrollY)/8;
if (Math.abs(diff) > 1) {
window.scrollTo(0, (window.scrollY+diff));
clearTimeout(window._TO);
window._TO=setTimeout(scrollToItem, 30, item);
} else {
window.scrollTo(0, item.offsetTop);
}
}
function doScrolling(element, duration) {
var startingY = window.pageYOffset
var elementY = getElementY(element)
var targetY = document.body.scrollHeight - elementY < window.innerHeight ? document.body.scrollHeight - window.innerHeight : elementY
var diff = targetY - startingY
var easing = function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; }
var start;
if (!diff) return
window.requestAnimationFrame(function step(timestamp) {
if (!start) start = timestamp;
var time = timestamp - start;
var percent = Math.min(time / duration, 1);
percent = easing(percent);
window.scrollTo(0, startingY + diff * percent);
if (time < duration) {
window.requestAnimationFrame(step);
}
})
}
function newTalk(textVal, pic) {
var my_elem = document.getElementById("nextChatHolder");
var div = document.createElement('div');
div.innerHTML = '<div class="animated animatedFadeInUp fadeInUp">' +
'<div class="chat self">' +
'<div class="user-photo">' +
'<img src="' + pic + '">' +
'</div>' +
'<p class="chat-message">' + textVal + '</p>' +
'<span class="timeself">11:01 PM | Oct 11 2019</span>' +
'</div>' +
'</div>';
my_elem.parentNode.insertBefore(div, my_elem);
//scrollToItem(my_elem))
}
I believe you're looking for:
my_elem.scrollIntoView({behavior: "smooth",block: "end"})
as the last line in newTalk.
Documentation
I have two divs which numerically represent the width and height of the window's screen, counting from every 100th pixel. The numeric values are wrapped inside span tags and inserted into their respective div container through two loops. Since both of these loops share almost the same exact methods and conditional logic I was wondering if there was a way that I could combine them somehow:
HTML
<div class="rule rule--horizontal"></div>
<div class="rule rule--vertical"></div>
JS
document.addEventListener("DOMContentLoaded", function() {
var horizontal = document.getElementsByClassName("rule--horizontal")[0],
vertical = document.getElementsByClassName("rule--vertical")[0];
for (var i = 50, screenWidth = screen.width; i < screenWidth; i+= 50) {
if (i % 100 === 0) {
horizontal.innerHTML += "<span class='num num--visible'>" + i + "</span>";
}
}
for (var i = 50, screenHeight = screen.height; i < screenHeight; i+= 50) {
if (i % 100 === 0) {
vertical.innerHTML += "<span class='num num--visible'>" + i + "</span>";
}
}
});
JSFiddle
This produce the same result
document.addEventListener("DOMContentLoaded", function() {
var horizontal = document.getElementsByClassName("rule--horizontal")[0],
vertical = document.getElementsByClassName("rule--vertical")[0];
var a = screen.width > screen.height ? screen.width : screen.height;
for (var i = 50; i < a; i+= 50) {
if (i % 100 === 0) {
if(i < screen.width)horizontal.innerHTML += "<span class='num num--visible'>" + i + "</span>";
if(i < screen.height)vertical.innerHTML += "<span class='num num--visible'>" + i + "</span>";
}
}
});
You can create function and use it in two places:
document.addEventListener("DOMContentLoaded", function() {
var horizontal = document.getElementsByClassName("rule--horizontal")[0],
vertical = document.getElementsByClassName("rule--vertical")[0];
loop(horizontal, screen.width);
loop(vertical, screen.height);
});
function loop(element, max) {
for (var i = 50; i < max; i+= 50) {
if (i % 100 === 0) {
element.innerHTML += "<span class='num num--visible'>" + i + "</span>";
}
}
}
You can factor out the if statement if (i % 100 === 0) this is true on 100, 200, etc. Just start i at 100 and increment by 100
document.addEventListener("DOMContentLoaded", function() {
var horizontal = document.getElementsByClassName("rule--horizontal")[0],
vertical = document.getElementsByClassName("rule--vertical")[0];
var createDivs = function (axis, maxSize) {
for (var i = 100; i < maxSize; i += 100) {
axis.innerHTML += "<span class='num num--visible'>" + i + "</span>";
}
};
createDivs(horizontal, screen.width);
createDivs(vertical, screen.height);
});
I am attempting to build an image zoom/panner using JS/jQuery. I have so far managed to get the zoom working using the mousewheel to zoom in/out, but it currently only zooms in on the center point each time.
Like with Google maps I want to be able to zoom in on the point where the mouse cursor is, but am unsure on the code to do this.
I have setup a fiddle with my progress so far:
http://jsfiddle.net/quirksmode/XrKLN/1/
Any help would be massively appreciated :-)
My code is:
// Plugin to allow for button holds
jQuery.fn.mousehold = function (timeout, f) {
if (timeout && typeof timeout == 'function') {
f = timeout;
timeout = 100;
}
if (f && typeof f == 'function') {
var timer = 0;
var fireStep = 0;
return this.each(function () {
jQuery(this).mousedown(function () {
fireStep = 1;
var ctr = 0;
var t = this;
timer = setInterval(function () {
ctr++;
f.call(t, ctr);
fireStep = 2;
}, timeout);
})
clearMousehold = function () {
clearInterval(timer);
if (fireStep == 1) f.call(this, 1);
fireStep = 0;
}
jQuery(this).mouseout(clearMousehold);
jQuery(this).mouseup(clearMousehold);
})
}
}
/**
* CSS3 Transform helper
*/
var cssTransformScale = function (x, y, z) {
return {
'-webkit-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'-moz-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'-ms-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'-o-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
};
};
$(document).ready(function () {
var assetViewer = {
name: 'assetViewer',
defaults: {
$assetWrap: $('#asset-wrap'),
$assetImg: $('.asset-img'),
imgSrc: "http://lorempixel.com/1600/760/",
zoomScale: 0.01,
initialZoom: 1,
currentZoom: 1,
maxZoom: 3,
minZoom: 1,
$zoomIn: $('#zoom-in'),
$zoomOut: $('#zoom-out')
},
init: function (options) {
var me = this;
this.options = $.extend(this.defaults, options);
this.appendImage();
this.bindEvents();
},
appendImage: function () {
var me = this;
this.options.$assetWrap.append('<div class="asset-holder"><div class="asset-inner-wrap"><img class="asset-img" src="' + this.options.imgSrc + '" /></div></div>');
me.options.$assetImg = $(me.options.$assetImg.selector); // Using .selector to refresh the element
},
bindEvents: function () {
var me = this;
me.options.$zoomIn.mousehold(1, function () {
me.zoom("+", 1);
})
me.options.$zoomOut.mousehold(1, function () {
me.zoom("-", 1);
})
me.options.$assetImg.mousewheel(function (event, delta) {
if (delta > 0) me.zoom("+", delta);
else if (delta < 0) me.zoom("-", Math.abs(delta)); // Forces the negative to become a positive
return false; // prevent default
});
},
zoom: function (direction, delta) {
var me = this;
//console.log();
if ((me.options.currentZoom >= me.options.minZoom) && (me.options.currentZoom <= me.options.maxZoom)) {
var scale = (direction === "+") ? me.options.currentZoom += (me.options.zoomScale * delta) : me.options.currentZoom -= (me.options.zoomScale * delta);
// Set the Zoom Bounds
if (me.options.currentZoom <= me.options.minZoom) {
scale = me.options.currentZoom = me.options.minZoom;
}
if (me.options.currentZoom >= me.options.maxZoom) {
scale = me.options.currentZoom = me.options.maxZoom;
}
me.options.$assetImg.css(cssTransformScale(scale, scale, scale));
}
}
}
assetViewer.init();
});
I have done something very similar to what you are trying to achieve and I have a div within a div and then used the left and top CSS attributes of the child div to navigate around the image via a minimap image.