Effect typing when switching slider - javascript

In the slider need realize the effect of "typing" when you switch slides. I use Slick Slider for slider. Work example http://test2.hotweb.com.ua/webbit/.
HTML:
<div class="header-slider-wrap">
<div class="header-slider">
<div class="slider-nav__left nav-btn-slider">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 477.175 477.175"><path d="M145.188 238.575l215.5-215.5c5.3-5.3 5.3-13.8 0-19.1s-13.8-5.3-19.1 0l-225.1 225.1c-5.3 5.3-5.3 13.8 0 19.1l225.1 225c2.6 2.6 6.1 4 9.5 4s6.9-1.3 9.5-4c5.3-5.3 5.3-13.8 0-19.1l-215.4-215.5z"/></svg>
</div>
<div class="slider-nav__right nav-btn-slider">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 477.175 477.175"><path d="M360.73 229.075l-225.1-225.1c-5.3-5.3-13.8-5.3-19.1 0s-5.3 13.8 0 19.1l215.5 215.5-215.5 215.5c-5.3 5.3-5.3 13.8 0 19.1 2.6 2.6 6.1 4 9.5 4 3.4 0 6.9-1.3 9.5-4l225.1-225.1c5.3-5.2 5.3-13.8.1-19z"/></svg>
</div>
<ul class="slider-item-list">
<li class="slider-item" style="background-color: #6495ED">
<div class="slider-text-wrap">
<div class="slider-text" data-text='Example text 1'></div>
</div>
</li>
<li class="slider-item" style="background-color: #BA55D3">
<div class="slider-text-wrap">
<div class="slider-text" data-text='Example text 2'></div>
</div>
</li>
<li class="slider-item" style="background-color: #8DEEEE">
<div class="slider-text-wrap">
<div class="slider-text" data-text='Example text 3'></div>
</div>
</li>
</ul>
</div>
</div>
JavaScript:
printTextSlider();
function printTextSlider() {
var $btn = $('.nav-btn-slider'),
$ul = $('.slider-item-list'),
$activeLi = $ul.find('.slick-active'),
$text = $activeLi.find('.slider-text');
$text.addClass('is-active');
printText($text);
$btn.on('click', function() {
var $activeLi = $ul.find('.slick-active'),
$siblings = $activeLi.siblings().find('.slider-text'),
$text = $activeLi.find('.slider-text'),
id = $text.attr('id');
setTimeout(function() {
$siblings.removeClass('is-active');
}, 1000);
$text.addClass('is-active');
printText($('#'+id));
});
}
function printText(el) {
var a = el.data('text');
a = a.split('');
console.log(a);
el.text('');
var c = a.length;
j = 0;
setInterval(function() {
if(j < c) {
el.text(el.text() + a[j]);
j++;
}
else {
el.removeClass('after-line');
}
}, 100);
}
Style(sass):
.slider-text-wrap {
max-width: 700px;
width: 100%;
margin: 0 auto;
padding-top: 230px;
}
.slider-text {
font-size: 36px;
word-wrap: break-word;
opacity: 0;
}
Proble: when you switch slides, the text displayed is not correct.
Where I'm wrong?
UPDATE: I found some interesting plugin typed.js and rewrite js code for this:
printTextSlider();
function printTextSlider() {
var $btn = $('.nav-btn-slider'),
$ul = $('.slider-item-list'),
$active = $ul.find('.slick-active'),
$span = $active.find('.slider-text'),
text = $span.data('text');
$span.typed({
strings: [text],
typeSpeed: 100,
startDelay: 1300,
showCursor: false,
});
$btn.on('click', function() {
var $active = $ul.find('.slick-active'),
$span = $active.find('.slider-text'),
text = $span.data('text');
printText($span, text);
});
}
function printText(el, text) {
el.typed({
strings: [text],
typeSpeed: 100,
startDelay: 1800,
showCursor: false
});
}
It's work!

Related

JS slider has one too many slides. Can't figure out why

I have a slider which is supposed to show only three slides, but it continues (both automatically or by click) to a fourth blank slide. I don't see where the number of slides is set in the code. Would really appreciate some educated eyes on this.
The JS
$(document).ready(function() {
var $slider = $(".slider"),
$slideBGs = $(".slide__bg"),
diff = 0,
curSlide = 0,
numOfSlides = $(".slide").length-1,
animating = false,
animTime = 500,
autoSlideTimeout,
autoSlideDelay = 6000,
$pagination = $(".slider-pagi");
function createBullets() {
for (var i = 0; i < numOfSlides+1; i++) {
var $li = $("<li class='slider-pagi__elem'></li>");
$li.addClass("slider-pagi__elem-"+i).data("page", i);
if (!i) $li.addClass("active");
$pagination.append($li);
}
};
createBullets();
function manageControls() {
$(".slider-control").removeClass("inactive");
if (!curSlide) $(".slider-control.left").addClass("inactive");
if (curSlide === numOfSlides) $(".slider-control.right").addClass("inactive");
};
function autoSlide() {
autoSlideTimeout = setTimeout(function() {
curSlide++;
if (curSlide > numOfSlides) curSlide = 0;
changeSlides();
}, autoSlideDelay);
};
autoSlide();
function changeSlides(instant) {
if (!instant) {
animating = true;
manageControls();
$slider.addClass("animating");
$slider.css("top");
$(".slide").removeClass("active");
$(".slide-"+curSlide).addClass("active");
setTimeout(function() {
$slider.removeClass("animating");
animating = false;
}, animTime);
}
window.clearTimeout(autoSlideTimeout);
$(".slider-pagi__elem").removeClass("active");
$(".slider-pagi__elem-"+curSlide).addClass("active");
$slider.css("transform", "translate3d("+ -curSlide*100 +"%,0,0)");
$slideBGs.css("transform", "translate3d("+ curSlide*50 +"%,0,0)");
diff = 0;
autoSlide();
}
function navigateLeft() {
if (animating) return;
if (curSlide > 0) curSlide--;
changeSlides();
}
function navigateRight() {
if (animating) return;
if (curSlide < numOfSlides) curSlide++;
changeSlides();
}
$(document).on("mousedown touchstart", ".slider", function(e) {
if (animating) return;
window.clearTimeout(autoSlideTimeout);
var startX = e.pageX || e.originalEvent.touches[0].pageX,
winW = $(window).width();
diff = 0;
$(document).on("mousemove touchmove", function(e) {
var x = e.pageX || e.originalEvent.touches[0].pageX;
diff = (startX - x) / winW * 70;
if ((!curSlide && diff < 0) || (curSlide === numOfSlides && diff > 0)) diff /= 2;
$slider.css("transform", "translate3d("+ (-curSlide*100 - diff) +"%,0,0)");
$slideBGs.css("transform", "translate3d("+ (curSlide*50 + diff/2) +"%,0,0)");
});
});
$(document).on("mouseup touchend", function(e) {
$(document).off("mousemove touchmove");
if (animating) return;
if (!diff) {
changeSlides(true);
return;
}
if (diff > -6 && diff < 6) {
changeSlides();
return;
}
if (diff <= -6) {
navigateLeft();
}
if (diff >= 6) {
navigateRight();
}
});
$(document).on("click", ".slider-control", function() {
if ($(this).hasClass("left")) {
navigateLeft();
} else {
navigateRight();
}
});
$(document).on("click", ".slider-pagi__elem", function() {
curSlide = $(this).data("page");
changeSlides();
});
});
The HTML
<div class="slider-container">
<div class="slider-control left inactive"></div>
<div class="slider-control right"></div>
<ul class="slider-pagi"></ul>
<div class="slider">
<div class="slide slide-0 active">
<div class="slide__bg"></div>
<div class="slide__content">
<!--<svg class="slide__overlay" viewBox="0 0 720 405" preserveAspectRatio="xMaxYMax slice">
<path class="slide__overlay-path" d="M0,0 150,0 500,405 0,405" />
</svg>-->
<div class="slide__text">
<h2 class="slide__text-heading"><b>New</b> featured products</h2>
<h3 class="slide__text-sub-head">Ives<sup>®</sup> hands-free door pulls</h3>
<p class="slide__text-desc">Ives offers hands-free pulls and door opening tools that enable pedestrians to operate the door with an arm or foot to avoid contacting surfaces with their hands. This is a cost-effective solution for retrofitting high-traffic mechanical applications to hands-free.<br><a class="slide__text-link">Learn More</a></p>
</div>
</div>
</div>
<div class="slide slide-1 ">
<div class="slide__bg"></div>
<div class="slide__content">
<!--<svg class="slide__overlay" viewBox="0 0 720 405" preserveAspectRatio="xMaxYMax slice">
<path class="slide__overlay-path" d="M0,0 150,0 500,405 0,405" />
</svg>-->
<div class="slide__text">
<h2 class="slide__text-heading"><b>New</b> featured products</h2>
<h3 class="slide__text-sub-head">LCN<sup>®</sup> touchless actuators</h3>
<p class="slide__text-desc">Allegion offers no-touch actuators that are installed in place of push buttons and comply with ANSI 156.19 low energy standards. A pedestrian simply waves a hand in front of the wall plate, the technology senses the motion and acknowledges intent to enter. No contact with the door or hardware is required.<br><a class="slide__text-link">Learn More</a></p>
</div>
</div>
</div>
<div class="slide slide-2">
<div class="slide__bg"></div>
<div class="slide__content">
<!--<svg class="slide__overlay" viewBox="0 0 720 405" preserveAspectRatio="xMaxYMax slice">
<path class="slide__overlay-path" d="M0,0 150,0 500,405 0,405" />
</svg>-->
<div class="slide__text">
<h2 class="slide__text-heading"><b>New</b> featured products</h2>
<h3 class="slide__text-sub-head">Schlage<sup>®</sup> mobile access solutions</h3>
<p class="slide__text-desc">Schlage Mobile Access Solutions provide comprehensive touchless offering, including mobile enabled multi-technology readers, mobile enabled wireless electronic locks and mobile access credentials.<br><a class="slide__text-link">Learn More</a></p>
</div>
</div>
</div>
</div>
</div>
TIA!
Just tried the following which seems to have corrected the issue.
I changed this line:
numOfSlides = $(".slide").length-1,
To this:
numOfSlides = $(".slide").length-2,
Getting the desired result now...only 3 slides as intended. Hopefully the code is fundamentally sound.

Make all selected css circles active

I am trying to create a progress bar of css circles, in which after clicking on every circle like 1, 2, 3 all the three circles and their connected line will be filled by red color and if go back like 3, 2, 1 then color should be removed.
HTML :
<div class="row well" id="rows">
<ul id="progressbar" class="progressbar">
<li class="cir danger">THOUGHFUL</li>
<li class="cir">PASSION</li>
<li class="cir">POWER OF DESIGN</li>
<li class="cir">BUILDING RELATIONSHIPS</li>
<li class="cir">ENHANCE HUMAN INTERATION</li>
</ul>
</div>
JS :
var header = document.getElementById("rows");
var bar = document.getElementsByClassName("progressbar");
var btns = header.getElementsByClassName("cir");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function () {
var danger = document.getElementsByClassName("danger");
danger[0].className = danger[0].className.replace("danger", "");
this.className += " danger";
});
}
Sample Img:
Referring to above imag, if i click on circle 3 then circle 1,2,3 should be in red color and then if i click circle 2 then circle 3 should be white and 1 & 2 should be red, vice versa.
I have tried to achieve it by JS but classnotfound error .
Any help for this would be appreciated.
Every time a circle is clicked, grab its data-id and activate all circles of an equal or lesser data-id.
let circles = document.querySelectorAll(".circle")
circles.forEach(el => {
el.addEventListener("click", (e) => {
let id = e.target.dataset.id
circles.forEach(el2 => {
if(el2.dataset.id <= id){
el2.classList.add("active")
}else{
el2.classList.remove("active")
}
})
})
})
.circled{display:flex}
.circle{
border-radius:50%;
width:50px;
height:50px;
border: solid 2px #333;
display:inline-flex;
align-items:center;
justify-content:center;
position:relative;
margin-left: 44px;
cursor:pointer;
}
.circle:not(:first-of-type)::before{
height: 2px;
width: 50px;
content:"";
background-color: #333;
position:absolute;
left:-50px;
}
.circle.active{
border-color: #f00;
}
.circle.active:not(:first-of-type)::before{
background-color: #f00;
}
<div class="circles">
<div class="circle active" data-id="1">1</div>
<div class="circle" data-id="2">2</div>
<div class="circle" data-id="3">3</div>
<div class="circle" data-id="4">4</div>
<div class="circle" data-id="5">5</div>
</div>
Not proud of this
var header = document.getElementById("rows");
var bar = document.getElementsByClassName("progressbar");
var btns = header.getElementsByClassName("cir");
Array.prototype.forEach.call(btns,function(btn){
btn.addEventListener('click', function(e){
updateProgress(btn,e)
})
});
function updateProgress(btn,e){
removeDangerFromAll();
for( let btnToCheck of btns){
btnToCheck.classList.add('danger');
if (btnToCheck == btn) {
break;
}
}
}
function removeDangerFromAll(){
Array.prototype.forEach.call(btns,function(btn){
btn.classList.remove('danger');
});
}
UPDATE: Switched to cleaner classList as Other Answer

jQuery animtion stops when user scrolls

I'm using multiple number elements on my site which are counting up after hitting the visible area of the viewport.
That part works until the user manually scrolls the page. If the user scrolls up or down, the animation stops for a second and repeats when the user don't scroll anymore. It looks very buggy.
If I try to replicate the problem in a fiddle, the same code always works without the "stuttering"?
jQuery(function($) {
$(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i, el) {
function visPx() {
var H = $(this).height(),
r = el.getBoundingClientRect(),
t = r.top,
b = r.bottom;
return cb.call(el, Math.max(0, t > 0 ? H - t : (b < H ? b : H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
$(".fig-number").inViewport(function(px) {
// if px>0 (entered V.port) and
// if prop initNumAnim flag is not yet set = Animate numbers
if (px > 0 && !this.initNumAnim) {
this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 10000,
step: function(now) {
$(this).text(Math.ceil(now));
}
});
}
});
});
html,
body {
height: 100%;
}
.spacer {
height: 100%;
width: 100%;
display: block;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">1000</h1>
<h1 class="fig-number">1500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">2000</h1>
<h1 class="fig-number">2500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">3000</h1>
<h1 class="fig-number">3500</h1>
</div>
The working fiddle (same code): https://jsfiddle.net/JSCray/r7g0vn93/3/

How to convert jQuery function into angular js?

I am very new to AngularJs, I have written a slider function in jQuery. Now I want to convert thih function into Angular. Here is my code below::
<div class="slide-container">
<div class="slide-scroller" style="left: 0px;">
<div class="slideContent" style="background-color: #f00;">one</div>
<div class="slideContent" style="background-color: #0f0;">two</div>
<div class="slideContent" style="background-color: #00f;">three</div>
</div>
</div>
<input type="button" id="left">
<input type="button" id="right">
.slide-container {height: 100px; overflow: hidden; position: relative;}
.slide-scroller { height: 100px; overflow:hidden; position: absolute; top: 0px;}
.slide-scroller .slideContent { height: 100px; overflow: hidden; float: left;}
function slider() {
var slideWidth, speed, sc, slideScroller, scSlide, totalSlide, scrollerWidth, maxLeft;
slideWidth = $(window).width(); // [ get the device width ]
speed = 0.6; // [ control speed 1 = 1s]
sc = $(".slide-container"); // [ getting the container ]
slideScroller = $('.slide-scroller'); // [ getting slider scroller ]
scSlide = $('.slideContent'); // [ getting slide contetnts ]
totalSlide = $(scSlide).length; // [ total slide contents ]
scrollerWidth = totalSlide * slideWidth; // [ slide scroller width ]
maxLeft = -parseInt(scrollerWidth) + parseInt(slideWidth); // [maxmimum left slide value]
// adding some initial attributes
$(sc && scSlide).css({width: slideWidth});
$(slideScroller).css({width: scrollerWidth});
$(slideScroller).css('transition', 'all ease '+speed+'s');
// left click function
$("#left").click(function () {
var xvalue = $(slideScroller).css('left'); //console.log('left :: ', xvalue);
var newvalue = parseInt(xvalue) - parseInt(slideWidth); // console.log('newValue :: ', newvalue);
if (newvalue >= maxLeft) {//console.info('no more left left');
$(slideScroller).css('left', newvalue);
}
else {
return false;
}
});
// right click function
$("#right").click(function () {
var xvaluetwo = $(slideScroller).css('left'); console.log('lefttwo :: ', xvaluetwo);
var newvaluetwo = parseInt(xvaluetwo) + parseInt(slideWidth); console.log('newValuetwo :: ', newvaluetwo);
if (newvaluetwo <= 0) {//console.info('no more right left');
$(slideScroller).css('left', newvaluetwo);
}
else {
return false;
}
});
}
$(document).ready(function () {
slider();
});
I have linked jQuery.min library and called the function in document.ready
Please help me how to make in AngularJS
in HTML:
<div class="slide-container" ng-init="initSlider()">
<div class="slide-scroller" ng-repeat="item in sliderList" style="left: 0px;">
<div class="slideContent" style="background-color: {{item.bgColor}}">{item.content}</div>
</div>
</div>
<input type="button" id="left">
<input type="button" id="right">
in Controller:
$scope.initSlider = function(){
slider()
}

How to change the background color of a screen area on hover

I am making a website for a school project, wherein I have left and right drawers. The drawers are hidden and show only when onclick pageX < 100 (left drawer) and pageX > 1200 (right drawer). As the drawers show only onclick(), I want that area to get highlighted in some way (preferably color-change) so that the user knows there is something there. How do I do this?
HTML:
<div id="pgcontainer">
<header>
<div id="navbar">
<div id="rightdrawer">
<ul>
<li>Register</li>
<li>Archives</li>
<li>Contact Us</li>
<li>Our sponsors</li>
</ul>
</div>
</div>
</header>
</div>
JavaScript:
$(function() {
var menuwidth = 240; // pixel value for sliding menu width
var menuspeed = 400; // milliseconds for sliding menu animation time
var $bdy = $('body');
var $container = $('#pgcontainer');
var $hamburger = $('#hamburgermenu');
var $rightmenu = $('#rightdrawer');
var negwidth = "-"+menuwidth+"px";
var poswidth = menuwidth+"px";
$('#pgcontainer').on('click',function(e) {
if(e.pageX < 130) {
if($bdy.hasClass('openmenu')) {
jsAnimateMenuLeft('close');
} else {
jsAnimateMenuLeft('open');
}
}
});
$('.overlay').on('click', function(e) {
if($bdy.hasClass('openmenu')) {
jsAnimateMenuLeft('close');
}
else if($bdy.hasClass('openmenur')) {
jsAnimateMenuRight('close');
}
});
$('a[href$="#"]').on('click', function(e) {
e.preventDefault();
});
function jsAnimateMenuLeft(tog) {
if(tog == 'open') {
$bdy.addClass('openmenu');
$container.animate({marginRight: negwidth, marginLeft: poswidth}, menuspeed);
$hamburger.animate({width: poswidth}, menuspeed);
$('.overlay').animate({left: poswidth}, menuspeed);
}
if(tog == 'close') {
$bdy.removeClass('openmenu');
$container.animate({marginRight: "0", marginLeft: "0"}, menuspeed);
$hamburger.animate({width: "0"}, menuspeed);
$('.overlay').animate({left: "0"}, menuspeed);
}
}
});
I think that the optimal solution here is to add two more elements, position them fixed and add some nice hover styles.
Note that since .leftdrawer-hover and .rightdrawer-hover are children on #pgcontainer clicking on them would act exactly as you need, because click events will bubble to #pgcontainer where you will detect them and show/hide corresponding drawer.
#pgcontainer .leftdrawer-hover,
#pgcontainer .rightdrawer-hover {
content: '';
position: fixed;
top: 0;
bottom: 0;
width: 130px;
display: block;
background: rgba(200, 200, 200, .4);
}
#pgcontainer .rightdrawer-hover {
right: 0;
}
#pgcontainer .leftdrawer-hover:hover,
#pgcontainer .rightdrawer-hover:hover {
background: rgba(0, 0, 0, .7);
cursor: pointer;
}
<div id="pgcontainer">
<div class="leftdrawer-hover"></div>
<div class="rightdrawer-hover"></div>
<!-- other tags -->
</div>

Categories