How to animate multi-line typing inside <textarea>? - javascript

How can I animate multiline typing effect inside a text area?
I want to be able to enter input inside this textarea and upon clicking a button, I'll get some text from an api and then I want it to be typed-like inside the text area. Here's the piece of code which was working fine when I used but on replacing it with textarea it's not working. It's writting all the lines parallelly with this very long cursor, also its coloring the complete background of
.xxx {
word-break: break-all;
font-family: monospace;
color:#0000;
background:
linear-gradient(-90deg,black 5px,#0000 0) 10px 0,
linear-gradient(black 0 0) 0 0, aqua;
background-size:calc(var(--n)*1ch) 200%;
-webkit-background-clip:padding-box,text;
background-clip:padding-box,text;
background-repeat:no-repeat;
animation:
b .4s infinite steps(1),
t calc(var(--n)*.1s) steps(var(--n)) forwards;
}
#keyframes t{
from {background-size:0 200%;
}
}
#keyframes b{
50% {background-position:0 -100%,0 0
}
}
HTML
<div class="text-container">
<textarea id="output-text" style="--n:1000" rows="10" cols="50"></textarea>
</div>
I'm dynamically adding this class to the textarea tag after getting text from API.
Also, how do I put background color as the animation does its work? Right now, its coloring the background before the typing effect starts.
I modified the code from this example right here

Related

How to hide an element behind a smaller one?

I am creating an AutoComplete component but I am having a problem because I want the suggestions to animate into existence by sliding down. I am using the transform: translateY CSS in order to have it be performant on mobile.
So basically what I need to have happen is for the suggestions to hide behind the textbox, and to slide down and appear when the user begins typing. This only slightly works because the suggestions list is taller than the textbox. As a result, it can't fully hide behind textbox as it clips out of the top.
I have created a working example that demonstrates the problem at this link, and also have reproduced the code here (try typing into the textbox):
document.querySelector(".autocomplete").oninput = e => {
let value = e.target.value;
if (value.length > 0) {
document.querySelector(".suggestions").classList.add("open");
} else {
document.querySelector(".suggestions").classList.remove("open");
}
}
.autocomplete {
border: 1px solid #ddd;
padding: 5px;
width: 500px;
background-color: yellow;
z-index: 1;
position: relative;
}
.suggestions {
border: 1px solid #ddd;
height: 125px;
width: 500px;
transform: translateY(-30px);
transition: .25s;
background-color: #eef;
}
.open {
transform: translateY(0);
}
<p>Some text and a paragraph preceding the autocomplete</p>
<div>
<input class="autocomplete" />
<div class="suggestions">apple, banana, carrot, dog</div>
</div>
I would like to make the transform: translateY(-30px); instead to be transform: translateY(-130px);, but then it clips before the textbox. I want it to hide behind the textbox instead. Also, I don't think I can use scale here because I don't want it to look bad and distorted while animating in.
Depending on the state of the application, I may have different elements preceding this, so while a bandage solution of "put something before it" might work, it seems sloppy and not very scalable.
Is there any way to do this?
you can add a placeholder="type here" for your input and then in your css sheet add
input:not(:placeholder-shown)+div {
display: block;
}
.autocomplete {
display: none;
}
working pen:
https://codepen.io/yael-screenovate/pen/KKVxrrj

Make so that div changes color for a brief time when clicked

I've got a setup where I'm using divs as buttons, and when they're clicked they add to ingredients to my burger.
JS:
<div id="ingredientBox">
<Ingredient
ref="ingredient"
v-for="item in currentIngredients"
v-on:increment="addToBurger(item)"
:item="item"
:lang="lang"
:ui-labels="uiLabels"
:key="item.ingredient_id">
</Ingredient>
</div>
With CSS:
.ingredient {
border: 1px solid #f5f5f28a;
padding: 0.8em;
width: 23vh;
height: 19vh;
background-color: green;
border-radius: 25px;
margin: 10px;
text-align: center;
}
I now want the div to react visually when clicked (maybe change color for like 0.2 seconds or something. I've looked around and only find info on how to change color permanently, is there a simple way of changing the color for just a brief moment?
You can use CSS keyframe animation to pull this off:
#keyframes animate-burger-button {
0% {
background: red;
}
50% {
background: yellow;
}
100% {
background: green;
}
}
#ingredientBox:active {
animation: animate-burger-button 0.8s forwards;
}
I would also add another note to try and use a button instead of a div, make accessibility a lot easier.
You could do something like
#ingredientBox:active {
color: red;
}
You could use setTimeout to add a class to the button and then remove it.
code:
buttonTrigger() {
element.classList.add('somesyle'); // add colour changing class to element
setTimeout(() => {
element.classList.remove('somestyle'); //remove the class after 0.2 seconds
}, 200)
}
EDIT
I was going to also suggest using CSS keyframes but #AlexanderKaran already suggested it. That is a good option too.

Dynamic "Terminal" Style Text Box

I am trying to create a text box that is styled like a terminal window, On the bottom where you would usually type, right above that I would like some words that if you click on a word it would then print a specific paragraph into the "Terminal" Window.
I am using this for a personal website about coding. I would like to be able to click on the bar below on the "About" button and have it print an "About Coding" paragraph one letter at a time, kinda like you see in old 90s movies.
I need a place to start, maybe what the box should be coded in and or what that kind of thing is called. I cant for the life of me remember.
scoured the internet trying to find something similar and didnt come up with anything.
None to show yet.
There are a few ways you can approach this project. It is all based on what your end goal is (not just for the Terminal window page, but for the whole website in general). If this is something really small that doesn’t need for any data to persist (like having users, posts and etc) - you can go as simple as plain Javascript + HTML. You can also get really fancy with it and pick a front-end framework like Vue.js, React.js, Angular.js and etc. There are many different tools that you can use (here is a list from GitHub: https://github.com/collections/front-end-javascript-frameworks).
However, if we are looking to specifically tackle the task at hand - I would recommend using plain old Javascript with HTML.
Here is a small start for you, hope it helps (please see / run the snippet).
function kenobi() {
const customContent = document.createElement('div');
customContent.innerHTML = 'Hello there, General Kenobi!';
customContent.id = 'custom-content';
const referenceNode = document.querySelector('#you-are-a-bold-one');
referenceNode.parentNode.insertBefore(customContent, referenceNode.nextSibling);
}
.terminal {
max-width: 400px;
height: 150px;
padding: 8px;
font-family: Arial, sans-serif;
font-size: 14px;
border: 1px solid;
}
.wrapper {
display: flex;
}
#custom-content {
max-width: 250px;
overflow: hidden; /* Ensures the content is not revealed until the animation */
border-right: .15em solid orange; /* The typwriter cursor */
white-space: nowrap; /* Keeps the content on a single line */
letter-spacing: .15em; /* Adjust as needed */
animation:
typing 3.5s steps(40, end),
blink-caret .75s step-end infinite;
}
/* The typing effect */
#keyframes typing {
from { width: 0 }
to { width: 100% }
}
/* The typewriter cursor effect */
#keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: grey; }
}
<html>
<head>
<meta charset="UTF-8">
<title>Terminal Window</title>
</head>
<body>
<div class="terminal">
<div>Last login: Sun May 19 23:31:48 on ttys000</div>
<div class="wrapper">
<div class="intro" id="you-are-a-bold-one">~ $ </div>
</div>
</div>
<button class="about-button" onclick="kenobi()">About</button>
</body>
</html>

How can call a selected class on window.onload

I have made a simple javascript which during window.onload fades in the body when finished.
I want to create an overlay with a specific class instead which shall do the reverse. I want the overlay to simply fade out and after the animation the object would be destroyed or set as display:none.
<style>
body {
opacity: 0;
transition: opacity 500ms ease-in-out;
}
</style>
<script>window.onload = function() {setTimeout(function(){document.body.style.opacity="100";},500);};</script>
How to accomplish this in the best way possible?
You asked with a jQuery tag so i anwser you with a jQuery code.
$(function() {
var $overlay = $('#overlay');
$overlay.css('opacity', 0);
setTimeout(function() {
$overlay.remove();
}, 500);
});
#overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: white;
transition: opacity 500ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text
</div>
<div id="overlay"></div>
You can achieve this by adding a class to <body> on load and defining any styles and transitions in CSS.
While this technique ensures inheritance throughout your document, enabling any number of solutions, the most straightforward is to utilise an :after pseudo element on your <body>:
window.onload = function () {
// add a 'ready' class once the window has loaded
document.body.classList.add("ready");
};
body {
background: red;
color: white;
text-align: center;
}
/* this creates your overlay without unnecessary HTML markup */
body::after {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
/* transition the overlay out when body has a 'ready' class */
body.ready::after {
opacity: 0;
visibility: hidden;
/* transitioning visibility to "hidden" allows a seamless opacity transition */
transition-property: opacity, visibility;
/* Set your animation duration here */
transition-duration: 0.4s;
}
<h1>Awesome content</h1>
Sidenote: To allow for users without javascript enabled (who would otherwise see a blank screen), you might also consider allowing a 'no-js' class on <html> (replaced with 'js' in your <head>). Your css pseudo declaration would then be: html.js body::after{...}. More info: What is the purpose of the HTML "no-js" class?

expanding a div to reveal overflow on click

I am looking at this example on this website. I wanted to create an effect similar like that where you have a <div> that has some <p> in it and there's a button to show the full expanded description. I've analyzed the html and it looks like this:
<div class="product-description">
<div class="desc-wrap" itemprop="description">
<p>Material: wool
<br>6 Colors: Black, Yellow, Gray, Wine Red, Green, Navy Blue
<br>Size: One size only
<br>Recommended for size SMALL
<br>It has been noted by customers that these skirts are short.
<br>*Please check the measurement picture for sizing information. There are no refunds on orders that were messed up on your behalf.
</p>
<p>Note: Due to the difference between different monitors, the color may be off a tiny bit.</p>
<p>WORLDWIDE SHIPPING!
</p>
</div>
<div class="desc-fade"></div>
<div class="open-link" style="display: block;">Expand Full Description</div>
</div>
I assume that there's a javascript function that expands the box on click. But what is that? How do I reproduce this same effect?
Here's an example for exectly what you wanted: http://jsfiddle.net/kedem/D9NCP/
css:
.product-description {
height:150px;
overflow: hidden;
position:relative;
}
.product-description.open {
height:auto;
overflow: hidden;
position:relative;
}
.desc-fade {
width: 200%;
margin-left: -50%;
height: 30px;
background: #fff;
z-index: 1;
position: absolute;
-webkit-box-shadow: 0 0 20px 30px #fff;
-moz-box-shadow: 0 0 20px 30px #fff;
box-shadow: 0 0 20px 30px #fff;
bottom: 0;
left: 0;
opacity: 1;
-webkit-transition: opacity 250ms, 1s;
-moz-transition: opacity 250ms, 1s;
-o-transition: opacity 250ms, 1s;
transition: opacity 250ms, 1s;
}
.open-link {
position:absolute;
bottom: 15px;
z-index:2;
}
jquery:
$(function () {
var wrapHeight = $(".product-description .desc-wrap").height();
var descHeight = $(".product-description").height();
if (wrapHeight <= descHeight) {
$(".product-description .desc-fade").hide();
$(".product-description .open-link").hide();
}
$(".product-description .open-link").click(function () {
$(this).hide();
$(".product-description .desc-fade").hide();
$(".product-description").animate({
height: wrapHeight
}, 1000);
});
});
Does this works for you?
JSFIDDLE Demo
HTML
<div class="div-wrapper">
<div class="hider">
<p>Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown Here goes your text that is partially shown </p>
</div>
Show all
</div>
CSS
/* this first one is not necesary */
.div-wrapper {
width:300px;
border:solid 1px #000;
}
.div-wrapper>.hider {
height: 100px;
transition: ease-in-out all 0.2s;
overflow:hidden;
}
JQUERY
$(document).ready(function(e) {
$('.open-link').click(function(e) {
var $wrapper = $(this).parent().find('.hider');
$wrapper.css('height',$wrapper.find('p').height());
$(this).remove();
})
});
let me know if it's useful.
Using DOM inspector, it will help you understanding the trick. First they use a constant height for the container. Onclick remove the text and expand the div by setting a bigger height.
However, we have to determine the total height of the div so we shouldn't hide the expanded part from the start
http://jsfiddle.net/2SMF2/2/
$('.expand').click(function () {
$('#test').removeClass('collapsed', 'fast')
$(this).remove();
});
How about this:
http://jsfiddle.net/VvBRh/
What I have done:
$('.open-link a').click(function(){
if($(".desc-wrap").css("height") == "60px") {
//Find auto height of div and save it
$('.desc-wrap').css('height', 'auto');
var autoHeight = $('.desc-wrap').height();
//Revert back to 2 lines
$('.desc-wrap').css('height', '60px');
//Animate to the saved autoHeight
$(".desc-wrap").animate({height: autoHeight}, 1000);
} else {
//Shrink back to 2 lines (you can remove this if you want)
$(".desc-wrap").animate({height: "60px"}, 1000);
}
return false;
});
You will also need to add a little css to get inital settings:
.desc-wrap { height: 60px; overflow: hidden }
I'm sure this could be more elegant, and you could derive the height of 2 lines instead of fixed px, but I'll leave that up to you to decide ;)
Here is the complete code
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
$(document).ready(function() {
var $divView = $('div.view');
var innerHeight = $divView.removeClass('view').height();
$divView.addClass('view');
$('div.slide').click(function() {
$('div.view').animate({
height: (($divView.height() == 110)? innerHeight : "110px")
}, 500);
return false;
});
});
</script>
<style>
.view{
overflow:hidden;
height: 110px;
}
.total{
border:1px solid;
/*height:130px;
overflow-y:auto;*/
}
</style>
</head>
<body>
<div class="total">
<div class="view">
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
<p>shown/hidden depending on the toggle above. </p>
</div>
<div class="slide" style="cursor: pointer;">Show/Hide</div>
</div>
</body>
</html>

Categories