Simple play/pause CSS animation button with switching icon - javascript

Could anyone help me by adding a simple play/pause button to my text scrolling animation?. I need the button to work as an icon only using <i class="fa-regular fa-circle-play"></i> and <i class="fa-regular fa-circle-pause"></i> but display only one icon at a time according to the animation state.
I'm using the js code for flipping from #guradio
// for selecting the input field on clicking over the flip text
function selectText() {
const input = document.getElementById('searchInput');
input.focus();
input.select();
}
// for flipping the text
$('#searchInput').keyup(function() {
if ($(this).val().length == 0) {
$('#text-flip').show();
} else {
$('#text-flip').hide();
}
}).keyup();
#text-flip {
height:20px;
overflow:hidden;
margin-top: -20px;
}
#text-flip > div > div {
color: rgb(43, 43, 43);
padding-left: 60px;
height:45px;
margin-bottom:45px;
display:inline-block;
font-size: inherit
}
#text-flip div:first-child {
animation: show 10s linear infinite;
}
#keyframes show {
0% {margin-top:-270px;}
5% {margin-top:-180px;}
33% {margin-top:-180px;}
38% {margin-top:-90px;}
66% {margin-top:-90px;}
71% {margin-top:0px;}
99.99% {margin-top:0px;}
100% {margin-top:-270px;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="#" method="get">
<input id="searchInput" placeholder="Search: "/>
<div id="text-flip" onclick="selectText()">
<div><div>Third Text</div></div>
<div><div>Second Text</div></div>
<div><div>First Text</div></div>
</div>
</form>

I updated your code.
let isPlayed=true;
// for flipping the text
$('#searchInput').keyup(function() {
if ($(this).val().length == 0) {
$('#text-flip').show();
} else {
$('#text-flip').hide();
}
}).keyup();
function btnClicked() {
if(isPlayed)
$(".controlBtn").html("<i class='fa-solid fa-circle-play' onclick='btnClicked()'></i>");
else
$(".controlBtn").html("<i class='fa-solid fa-circle-pause' onclick='btnClicked()'></i>");
$("#text-flip div:first-child").toggleClass("flip-animation");
isPlayed = !isPlayed;
}
function selectText() {
const input = document.getElementById('searchInput');
input.focus();
input.select();
}
#text-flip {
height:20px;
overflow:hidden;
margin-top: -20px;
}
#text-flip > div > div {
color: rgb(43, 43, 43);
padding-left: 60px;
height:45px;
margin-bottom:45px;
display:inline-block;
font-size: inherit
}
#text-flip div:first-child {
animation: show 10s linear infinite;
}
#keyframes show {
0% {margin-top:-270px;}
5% {margin-top:-180px;}
33% {margin-top:-180px;}
38% {margin-top:-90px;}
66% {margin-top:-90px;}
71% {margin-top:0px;}
99.99% {margin-top:0px;}
100% {margin-top:-270px;}
}
.controlBtn {
margin-top: 10px;
}
#text-flip div.flip-animation:first-child {
animation-play-state: paused !important;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="#" method="get">
<input id="searchInput" placeholder="Search: "/>
<div id="text-flip" class="flip-animation" onclick="selectText()">
<div><div>Third Text</div></div>
<div><div>Second Text</div></div>
<div><div>First Text</div></div>
</div>
</form>
<div class="controlBtn"><i class="fa-solid fa-circle-pause" onclick="btnClicked()"></i></div>

Related

Animate Bar programmatically

I would like a bar to animate from left to right. I have a numerical input. After the submit click, the bar should then be animated.
Unfortunately, I don't know how to trigger the animation. I deliberately set the initial width value to 150px to show that the animation actually works, but it not works if be triggered programmatically.
btn = document.getElementById("btn");
btn.addEventListener('click', () => {
const val = document.querySelector('input').value
draw(val);
})
function draw(val) {
bar = document.getElementById("bar");
bar.style.setProperty('--width', (val * 10) + "px");
}
:root {
--width: 150px;
}
#bar{
background:red;
height:50px;
margin:50px;
transform-origin:top;
animation: grow 2s forwards;
}
#keyframes grow {
from {
width:0px;
}
to {
width:var(--width);
}
}
<input value="5">
<button id="btn">draw</button>
<div id="bar"></div>
Instead of animation, use CSS transtion. Then (almost) any change to an element would be animated.
const runIt = () => {
$('.bar').css('width', '100%');
};
.bar {
height: 5px;
border-radius: 5px;
background: blue;
transition: 2s;
width: 10px;
margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bar"></div>
<button onclick="runIt()">Run</button>
This seems like a perfect use for CSS Transitions. Rather than adding an animation to the element, just set its width to have a transition time. Then, any time you change the width, it will be animated.
const btn = document.getElementById("btn");
btn.addEventListener('click', () => {
const val = document.querySelector('input').value
draw(val);
})
function draw(val) {
bar = document.getElementById("bar");
bar.style.setProperty('width', (val * 10) + "px");
}
#bar{
background:red;
width: 0;
height:50px;
margin:50px;
transform-origin:top;
transition: width 2s; /* Any time the width changes, it will be animated of 2 seconds */
}
<input value="5">
<button id="btn">Click Me</button>
<div id="bar"></div>

Scroll from div to next div (different height)

I have got page with 5 div's. My div's have different heigh (it's adaptive). How I can go to next div by mouse when I scroll half of the current div?
I trying fullpage.js and onepage.js but it not working for me, because my div must be different height
#first {
width:100vw;
height:700px;
background-color:lightyellow;
text-align:center;
}
#second {
width:100vw;
height:700px;
background-color:lightblue;
text-align:center;
}
#third {
width:100vw;
height:1000px;
background-color:lightpink;
text-align:center;
}
#fourht {
width:100vw;
height:1500px;
background-color:lightgreen;
text-align:center;
}
#fiveth {
width:100vw;
height:800px;
background-color:lightgray;
text-align:center;
}
<div id="first">1 div</div>
<div id="second">2 div</div>
<div id="third">3 div</div>
<div id="fourht">4 div</div>
<div id="fiveth">5 div</div>
you're need get the height current active elem, and give for container transform translate( 0, -height ) on scroll, onepage and fullpage for there are work with this.
var $container = $('.container');
var $elem = $container.find('.elem');
var $active = $container.find('.active').height();
$(window).on('scroll',function(){
$container.css({"transform":"translate(0, -" + $active + "px)"});
});
body{
height: 100%;
}
.container{
transition: 1s all;
}
#first {
width:100vw;
height:700px;
background-color:lightyellow;
text-align:center;
}
#second {
width:100vw;
height:700px;
background-color:lightblue;
text-align:center;
}
#third {
width:100vw;
height:1000px;
background-color:lightpink;
text-align:center;
}
#fourht {
width:100vw;
height:1500px;
background-color:lightgreen;
text-align:center;
}
#fiveth {
width:100vw;
height:800px;
background-color:lightgray;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="first" class="elem active">1 div</div>
<div id="second" class="elem">2 div</div>
<div id="third" class="elem">3 div</div>
<div id="fourht" class="elem">4 div</div>
<div id="fiveth" class="elem">5 div</div>
</div>
I created my version. Look at this https://codepen.io/damates/pen/VXdKjR .
Jquery:
$("#nextDiv, #previousDiv").click(function(){
actualTopOffset = $(window).scrollTop();
areas = $(".area");
find = false;
newPosition = 0;
type = $(this).attr("data-type");
areasCount = $(areas).length;
$.each(areas, function(index, val) {
if(type == "next"){//if we click to go next area
if($(areas).length > (index+1)){
if(actualTopOffset < $(areas[index+1]).offset().top && !find){// ask if area has top offset higher. If yes set new position
find = true;
newPosition = $(areas[index+1]).offset().top;
}
}
}else if(type == "prev"){ //if we click to go previous area
areasCount--;
if((areasCount) >= 0){
if(actualTopOffset > $(areas[areasCount]).offset().top && !find){// ask if area has top offset lower. If yes set new position
find = true;
newPosition = $(areas[areasCount]).offset().top;
}
}
}
});
if(find){ //If we found new position scroll on new position
$('html, body').animate({
scrollTop: newPosition
}, 1000);
}
});
CSS:
#first {
width:100vw;
height:700px;
background-color:lightyellow;
text-align:center;
}
#second {
width:100vw;
height:700px;
background-color:lightblue;
text-align:center;
}
#third {
width:100vw;
height:1000px;
background-color:lightpink;
text-align:center;
}
#fourht {
width:100vw;
height:1500px;
background-color:lightgreen;
text-align:center;
}
#fiveth {
width:100vw;
height:800px;
background-color:lightgray;
text-align:center;
}
#nextDiv, #previousDiv{
position: fixed;
top: 20px;
background: red;
}
#previousDiv{
top: 0px;
}
HTML:
<div id="first" class="area">1 div</div>
<div id="second" class="area">2 div</div>
<div id="third" class="area">3 div</div>
<div id="fourht" class="area">4 div</div>
<div id="fiveth" class="area">5 div</div>
<div id="previousDiv" data-type="prev">Previous div</div>
Next div
EDIT VERSION WITH SCROLL
I change the script for scrolling. Look at to https://codepen.io/damates/pen/VXdKjR

CSS: How to add smooth shift to div width upon text change?

If anyone can phrase this question better than I can, please advise and I will alter (or edit yourself).
Here's my current jsfiddle: https://jsfiddle.net/5v7mzadu/
My HTML:
<div class="text-cycler">
WE <div class="c-text" id="ctext-1">CARE</div>
<div class="c-text" id="ctext-2">THINK</div>
<div class="c-text" id="ctext-3">SEE</div>
<div class="c-text" id="ctext-1">KNOW</div>
</div>
My CSS:
.text-cycler {
text-align:center;
font-size:25px;
}
.c-text {
display:inline-block
}
My Javascript:
var divs = $('div[id^="ctext-"]').hide(),
i = 0;
(function cycle() {
divs.eq(i).fadeIn(400)
.delay(1000)
.fadeOut(400, cycle);
i = ++i % divs.length;
})();
As you can see the second word fades in/out,. I'd like to add a smooth transition to the div, so that the width of the div container does NOT abruptly change width size. (so that the width "snap" is more smooth)
Can anyone help?
I believe you needed the animation over the content and text alignment center.
And indeed this must solve your purpose.
I have added span{white-space: nowrap; vertical-align: text-top;} to force it to align in single line, and added jQuery animate method to animate the width of the rotating text
And here's the fiddle for you to play around
var divs = $('div[id^="ctext-"]').hide(),
i = 0;
(function cycle() {
divs.eq(i)
.animate(400, function() {
$('.x').animate({
width: $(this).innerWidth()
});
})
.fadeIn(400)
.delay(1000)
.fadeOut(400, cycle);
i = ++i % divs.length;
})();
.text-cycler {
text-align: center;
font-size: 25px;
}
span {
white-space: nowrap;
vertical-align: text-top;
}
.c-text {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text-cycler">
<span> WE </span>
<span class="x">
<div class="c-text" id="ctext-1">CARE</div>
<div class="c-text" id="ctext-2">THINK</div>
<div class="c-text" id="ctext-3">SEE</div>
<div class="c-text" id="ctext-1">KNOW</div>
</span>
</div>
See this snippet
var divs = $('div[id^="ctext-"]').hide(),
i = 0;
(function cycle() {
divs.eq(i).fadeIn(400)
.delay(1000)
.fadeOut(400, cycle);
i = ++i % divs.length;
})();
.text-cycler {
font-size:25px;
position:fixed; /*added*/
padding-left:40% /*added*/
}
.c-text {
display:inline-block
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text-cycler" align="center">
WE <div class="c-text" id="ctext-1">CARE</div><div class="c-text" id="ctext-2">THINK</div><div class="c-text" id="ctext-3">SEE</div><div class="c-text" id="ctext-1">KNOW</div>
</div>
JavascriptLess way.
If you want to get funky. (No seriously, this is more a funky solution than usable)
.text-cycler {
width:75%;
margin:auto;
user-select: none;
text-align:center;
font-size:5vw;
}
.text-cycler:after {
content:"";
display:inline-block;
animation: change;
animation-duration: 10s;
animation-iteration-count: infinite;
}
#keyframes change {
0% {
content: "CARE";
opacity: 0;
}
3% {
opacity: 1;
}
22% {
opacity: 1;
}
25% {
content: "CARE";
opacity: 0;
}
25.1% {
content: "THINK";
}
28% {
opacity: 1;
}
47% {
opacity: 1;
}
50% {
content: "THINK";
opacity: 0;
}
50.1% {
content: "SEE";
}
53% {
opacity: 1;
}
72% {
opacity: 1;
}
75% {
content: "SEE";
opacity: 0;
}
75.1% {
content: "KNOW";
}
78% {
opacity: 1;
}
97% {
opacity: 1;
}
100% {
content: "KNOW";
opacity: 0;
}
}
<div class="text-cycler">
WE
</div>

Expanding search bar not expanding before search

There are 2 problems when running this search.
1: When clicking the magnifier, instead of just opening the search bar, it searches immediately. 2: if more than 2 characters are typed and then the search bar is closed (by click off it) then reopened (by clicking back on it) the search button and search text doesn't align properly. https://jsfiddle.net/mkLj7dap/
HTML:
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<meta charset="UTF-8">
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
</head>
<div class=" top-search">
<div class="ty-search-block">
<form action="www.example.com/" name="search_form" method="get" class="cm-processed-form">
<input type="hidden" name="subcats" value="Y">
<input type="hidden" name="pcode_from_q" value="Y">
<input type="hidden" name="pshort" value="Y">
<input type="hidden" name="pfull" value="Y">
<input type="hidden" name="pname" value="Y">
<input type="hidden" name="pkeywords" value="Y">
<input type="hidden" name="search_performed" value="Y">
<input type="text" name="hint_q" value="" id="search_input" title="" class="ty-search-block__input cm-hint"><button title="" class="ty-search-magnifier" type="submit"><i class="material-icons">search</i></button>
<input type="hidden" name="dispatch" value="products.search">
</form>
</div>
</div>
</body>
</html>
CSS:
.cm-processed-form{
position:relative;
min-width:50px;
width:0%;
height:50px;
float:right;
overflow:hidden;
-webkit-transition: width 0.1s;
-moz-transition: width 0.1s;
-ms-transition: width 0.1s;
-o-transition: width 0.1s;
transition: width 0.1s;
}
.ty-search-block__input{
top:0;
right:0;
border:0;
outline:0;
background:#dcddd8;
width:100%;
height:50px;
margin:0;
padding:0px 55px 0px 20px;
font-size:20px;
color:red;
}
.ty-search-block__input::-webkit-input-placeholder {
color: #d74b4b;
}
.ty-search-block__input:-moz-placeholder {
color: #d74b4b;
}
.ty-search-block__input::-moz-placeholder {
color: #d74b4b;
}
.ty-search-block__input:-ms-input-placeholder {
color: #d74b4b;
}
.ty-search-magnifier{
width:50px;
height:50px;
display:block;
position:absolute;
top:0;
font-family:verdana;
font-size:22px;
right:0;
padding-top:10px;
margin:0;
border:0;
outline:0;
line-height:30px;
text-align:center;
cursor:pointer;
color:#dcddd8;
background:#172b3c;
}
.cm-processed-form-open{
width:100%;
}
JS:
$(document).ready(function(){
var submitIcon = $('.ty-search-magnifier');
var inputBox = $('.ty-search-block__input');
var searchBox = $('.cm-processed-form');
var isOpen = false;
submitIcon.click(function(){
if(isOpen == false){
searchBox.addClass('cm-processed-form-open');
inputBox.focus();
isOpen = true;
} else {
searchBox.removeClass('cm-processed-form-open');
inputBox.focusout();
isOpen = false;
}
});
submitIcon.mouseup(function(){
return false;
});
searchBox.mouseup(function(){
return false;
});
$(document).mouseup(function(){
if(isOpen == true){
$('.ty-search-magnifier').css('display','block');
submitIcon.click();
}
});
});
function buttonUp(){
var inputVal = $('.ty-search-block__input').val();
inputVal = $.trim(inputVal).length;
if( inputVal !== 0){
$('.ty-search-magnifier').css('display','none');
} else {
$('.ty-search-block__input').val('');
$('.ty-search-magnifier').css('display','block');
}
}
Change the script as bellow to prevent the default click event, when search box not expanded:
submitIcon.click(function (event) {
if (isOpen == false) {
event.preventDefault();
searchBox.addClass('cm-processed-form-open');
inputBox.focus();
isOpen = true;
} else {
searchBox.removeClass('cm-processed-form-open');
inputBox.focusout();
isOpen = false;
}
});

Two identical elements needing to do the same function, but are conflicting

So I have a plus/minus divs, which, when the buttons are clicked, will either add or subtract a value. My issue is that when I place two of these on a page, they conflict with each other.
How can I adjust these so that they won't conflict?
You can see the working code here: http://codepen.io/maudulus/pen/yjnHv
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="css.css">
<script type="text/javascript" src="main.js"></script>
</head>
<div class="doors">
<div class="miniDoor left">-</div>
<input id="middle" placeholder="0"/>
<div class="miniDoor right">+</div>
</div>
<br><br><br><br><br><br><br>
<div class="doors">
<div class="miniDoor left">-</div>
<input id="middle" placeholder="0"/>
<div class="miniDoor right">+</div>
</div>
$(function(){
$('.left').on('click',function() {
subtractInputValue(this)
});
$('.right').on('click',function() {
addInputValue(this)
});
});
function addInputValue(thisDiv) {
inputVal = $(thisDiv).parent().children('input').val()
if (inputVal == "") {
$(thisDiv).parent().children('input').val(1)
} else {
$('#middle').val(eval(inputVal) +1)
}
}
function subtractInputValue(thisDiv) {
inputVal = $(thisDiv).parent().children('input').val()
if (inputVal == "") {
$(thisDiv).parent().children('input').val(-1)
} else {
$('#middle').val(eval(inputVal) -1)
}
}
You are using #middle as an ID in two places, the IDs need to be unique (I updated the IDs to something unique, they are arbitrary). So, jQuery finds the first ID it sees and updates it, that is why the top one gets updated when you click the bottom one. A simple fix is to use $(thisDiv).parent().children('input') when you want to update the value. That way you ensure you find the proper input to update.
Here is a working codepen that I forked of your original.
Also, you should not be using eval. There are better ways to convert a string into an int. Here is a good explanation as to why eval is a bad idea.
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="css.css">
<script type="text/javascript" src="main.js"></script>
</head>
<div class="doors">
<div class="miniDoor left">-</div>
<input id="middle1" placeholder="0"/>
<div class="miniDoor right">+</div>
</div>
<br><br><br><br><br><br><br>
<div class="doors">
<div class="miniDoor left">-</div>
<input id="middle2" placeholder="0"/>
<div class="miniDoor right">+</div>
</div>
$(function(){
$('.left').on('click',function() {
subtractInputValue(this)
});
$('.right').on('click',function() {
addInputValue(this)
});
});
function addInputValue(thisDiv) {
inputVal = $(thisDiv).parent().children('input').val()
if (inputVal == "") {
$(thisDiv).parent().children('input').val(1)
} else {
$(thisDiv).parent().children('input').val(eval(inputVal) +1) // change it here
}
}
To extend tokyovariable's answer
The easiest way to find the input element would be:
$(thisDiv).closest('.doors').find(':input');
and forget about eval. You can use $.isNumeric to check if it's a number.
This is a simplified version:
$(function(){
$('.left').on('click',function() {
calculateValue(this, -1, -1);
});
$('.right').on('click',function() {
calculateValue(this, +1, 1);
});
});
function getInput(thisDiv)
{
return ($(thisDiv).closest('.doors').find(':input'));
}
function calculateValue(thisDiv, op, defaultValue)
{
var elem = getInput(thisDiv);
var value = elem.val();
elem.val(!$.isNumeric(value) ? defaultValue : (parseInt(value) + op) );
}
$(function(){
$('.left').on('click',function() {
calculateValue(this, -1, -1);
});
$('.right').on('click',function() {
calculateValue(this, +1, 1);
});
});
function getInput(thisDiv)
{
return ($(thisDiv).closest('.doors').find(':input'));
}
function calculateValue(thisDiv, op, defaultValue)
{
var elem = getInput(thisDiv);
var value = elem.val();
elem.val(!$.isNumeric(value) ? defaultValue : (parseInt(value) + op) );
}
.miniDoor {
font-style: bold;
height:30px;
width:30px;
background:#333;
padding:10px;
font-size:20px;
text-align:center;
color:#fff;
line-height:1.5em;
/* transition: all .3s ease-in-out;*/
transition:all .3s;
transition-timing-function: cubic-bezier(0,0,0,1);
transform-style: preserve-3d;
float:left;
}
.miniDoor.right {
-webkit-transition: background .7s;
-moz-transition: background .7s;
transition: background .7s;
}
.miniDoor.right:hover {
background: #6B6A6A;
background: rgba(107, 106, 106, 0.8);
-webkit-transform: scale(0.93);
-moz-transform: scale(0.93);
-ms-transform: scale(0.93);
transform: scale(0.93);
color: #fff;
}
.miniDoor.left {
-webkit-transition: background .7s;
-moz-transition: background .7s;
transition: background .7s;
}
.miniDoor.left:hover {
background: #6B6A6A;
background: rgba(107, 106, 106, 0.8);
-webkit-transform: scale(0.93);
-moz-transform: scale(0.93);
-ms-transform: scale(0.93);
transform: scale(0.93);
color: #fff;
}
#middle1, #middle2{
border:0;
height:50px;
width:75px;
background:#333;
padding:10px;
font-size:20px;
text-align:center;
color:#fff;
line-height:1.5em;
/* transition: all .3s ease-in-out;*/
transition:all .3s;
transition-timing-function: cubic-bezier(0,0,0,1);
transform-style: preserve-3d;
float:left;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="doors">
<div class="miniDoor left">-</div>
<input id="middle1" placeholder="0"/>
<div class="miniDoor right">+</div>
</div>
<br><br><br><br><br><br><br>
<div class="doors">
<div class="miniDoor left">-</div>
<input id="middle2" placeholder="0"/>
<div class="miniDoor right">+</div>
</div>

Categories

Resources