What approach is being used to create this animated text effect? - javascript

Hope this is in the correct place to ask this question
I've been tasked with recreating the animated text effect on the headings on this page https://studioakademi.com/ On scrolling, the letters in words switch from a glyph style font to the actual font. I've viewed the source code but can't see any clues as to what's making this happen. Can anybody throw some light on it? Or suggest an approach that will do something close to it? I've not been able to find anything from my searching so far.
Any advice greatly appreciated.
Cheers
Grant

take a look at html first:
before you scroll down, the html element containing text looks like this, pay attention to class:
<h1 class="intro-text-fadeout">
Design studio<br>
with digital<br>
focus.
</h1>
After you scroll down this changes into:
<h1 class="intro-text-fadeout faded">
Design studio<br>
with digital<br>
focus.
</h1>
and then take a look at css:
section.frontpage-intro-text h1.intro-text-fadeout {
transition: opacity 400ms ease-in-out;
}
and for faded:
section.frontpage-intro-text h1.intro-text-fadeout.faded {
opacity: 0;
}
so basically when you add class faded to h1 element it fades out in 400ms to 0 opacity, it can be done easily in jquery, proof of concept:
$('h1.intro-text-fadeout').scroll(function(){
if($(this).scrollTop > 100){
$(this).addClass('faded');
}else{
$(this).removeClass('faded');
}
});

function randomtext() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
Get a random character using the above function then use setInterval to randomly change the text in the header and after the interval update the text to what it's supposed to be. This will give you an effect similar to the one on the website.
Update:
<span id='text_to_change'>sometext</span>
Say you have a <span> tag with id text_to_change and some text. You access it in JavaScript like this.
var text = document.getElementById("text_to_change").value
Now we have text with a string with value 'sometext'
Get the length of the string using text.length
Check the example below to get an idea on how it works, play around with the code to get the required output. Hope it Helps!
Example
function randomtext()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function replaceAt(string, index, replace) {
return string.substring(0, index) + replace + string.substring(index + 1);
}
var text_val = "sometext"
var final_text = "IamChangedText"
function callback(i)
{
var j = Math.floor((Math.random() * 25) + 5);
var test = setInterval(function(){
j--;
if(i < final_text.length)
{
text_val=replaceAt(text_val,i,randomtext())
}
if(j>1)
{
clearInterval(test);
if(i < final_text.length)
{
text_val =replaceAt(text_val,i,final_text.charAt(i))
console.log(text_val)
callback(i+1);
}
}
},50);
}
console.log(text_val)
callback(0)

Related

text search using jquery filter delay during backspace

I am using jquery filter to search for names in a big list of names. It works just fine with good speed when I type in the input field. But when I press backspace button to clear the search text there is a delay of more then 4s when there are about 2 or 3 characters left.
I have made a demo to explain my problem
<input type="text" class="search">
<div class="list"></div>
<script>
// Get the list div
let $list = $('.list');
// Form a list of numbers from 1 to 8000
let listHtml = ''
for (let i = 0; i < 8000; i++) {
listHtml += `<div class="list_item"><div class="list_item_value c${i}">${i}</div></div>`;
}
$list.html(listHtml);
// Get all the list items
$listItem = $list.find('.list_item');
$('.search').on('keyup', function(e) {
// Get the search text
let text = $(this).val();
$listItem.filter(function() {
$(this).toggle($(this).find(`.list_item_value`).text().includes(text));
});
});
</script>
I have simplified my problem with this demo by replacing the text search by number search.
One way to fix this problem would be by canceling the ongoing jquery filter process when a backspace is pressed. But I don't know how to do that. Please someone help me fix it.
Consider the following example.
$(function() {
function makeItems(n, t) {
for (var i = 1; i < n; i++) {
$(t).append("<div class='list_item'><div class='list_item_value " + i + "'>" + i + "</div>");
}
}
var $list = $('.list');
makeItems(8000, $list);
$('.search').keyup(function(e) {
var text = $(this).val().toLowerCase();
$(".filtered").removeClass("filtered");
var search = (text.length > 0);
if (search) {
$(".list_item", $list).filter(function(index) {
return $(this).text().indexOf(text) === -1;
}).addClass("filtered");
}
});
});
.filtered {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="search">
<div class="list"></div>
Not too much different from your code. Some reduction of code. When the Search is done, there is a condition to ensure it's not done on an empty value. Also we reset the view each time. Show, Hide, and Toggle have easing and callbacks, so they can be slower at times. Add/Remove class is very quick.
https://ryanpeden.com/javascript-indexof-vs-includes-performance/
So while includes will be a tiny, tiny amount slower because it has to check if you passed it a regex, in reality this will make no difference to how fast your code runs. You should use indexOf if you care about where the substring is in the original string. If you don’t care, just call includes because it makes the intent of your code more clear.
In the end, it's your call if you want to use includes or indexOf for your comparison.

how to use jquery to insert a character at specified position into monospaced textarea

I have a monospaced textarea (not unlike the stackexchange editor). When my user clicks, I need a character to automagically appear on the previous line using jQuery. I know I need to use .click() to bind a function to that event, but the logic of the function eludes me.
Desired Behavior...user will click at position of the asterisk *
Here is some text in my editor.
When I double click at a position*
I want to insert a new line above, with a new character at the same position
The above text should become the following after the function gets run
Here is some text in my editor.
*
When I double click at a position*
I want to insert a new blank line above, at the same position
What I have tried:
I have found the caret jQuery plugin, which has a function called caret() that I can get to find the position of the the asterisk when I click (the position is 74).
<script src='jquery.caret.js'></script>
$('textarea').click(function(e) {
if (e.altKey){
alert($("textarea").caret());
}
});
But I really need to know the position of the character within the line, not the entire textarea. So far this eludes me.
Here's something without using caret.js
$('textarea').dblclick(function(e){
var text = this.value;
var newLinePos = text.lastIndexOf('\n', this.selectionStart);
var lineLength = this.selectionStart - newLinePos;
var newString = '\n';
for(var i=1; i < lineLength; ++i){
newString += ' ';
}
newString += text.substr(this.selectionStart,this.selectionEnd-this.selectionStart);
this.value = [text.slice(0, newLinePos), newString, text.slice(newLinePos)].join('');
});
Here's a fiddle. Credit to this post for 'inserting string into a string at specified position'.
Just realised that doing that on the top line is a bit broken, I'll have a look when I get home!
Update
Fixed the top-line problem.
if(newLinePos == -1){
this.value = newString + '\n' + this.value;
} else {
this.value = [text.slice(0, newLinePos), '\n'+newString, text.slice(newLinePos)].join('');
}
http://jsfiddle.net/daveSalomon/3dr8k539/4/
Assuming you know the position of the caret in the whole text area here's something you might do with it.
function getCaretPosition(text, totalOffset) {
var line = 0, pos = 0;
for (var i = 0; i < Math.min(totalOffset, text.length); i++) {
if (text[i] === '\n') {
line++;
pos = 0;
} else {
pos++;
}
}
return { row: line, col: pos };
}
var caretPosition = getCaretPosititon($("textarea").val(), $("textarea").caret());

Any way to prevent losing focus when clicking an input text out of tinymce container?

I've made this tinymce fiddle to show what I say.
Highlight text in the editor, then click on the input text, highlight in tinyMCE is lost (obviously).
Now, I know it's not easy since both, the inline editor and the input text are in the same document, thus, the focus is only one. But is there any tinymce way to get like an "unfocused" highlight (gray color) whenever I click in an input text?
I'm saying this because I have a customized color picker, this color picker has an input where you can type in the HEX value, when clicking OK it would execCommand a color change on the selected text, but it looks ugly because the highlight is lost.
I don't want to use an iframe, I know that by using the non-inline editor (iframe) is one of the solutions, but for a few reasons, i can't use an iframe text editor.
Any suggestion here? Thanks.
P.S: Out of topic, does any of you guys know why I can't access to tinymce object in the tinyMCE Fiddle ? looks like the tinyMCE global var was overwritten by the tinymce select dom element of the page itself. I can't execute a tinyMCE command lol.
Another solution:
http://fiddle.tinymce.com/sBeaab/5
P.S: Out of topic, does any of you guys know why I can't access to
tinymce object in the tinyMCE Fiddle ? looks like the tinyMCE global
var was overwritten by the tinymce select dom element of the page
itself. I can't execute a tinyMCE command lol.
Well, you can access the tinyMCE variable and even execute commands.
this line is wrong
var colorHex = document.getElementById("colorHex")
colorHex contains input element, not value.
var colorHex = document.getElementById("colorHex").value
now it works ( neolist couldn't load, so I removed it )
http://fiddle.tinymce.com/DBeaab/1
I had to do something similar recently.
First off, you can't really have two different elements "selected" simultaneously. So in order to accomplish this you're going to need to mimic the browser's built-in 'selected text highlight'. To do this, you're going to have to insert spans into the text to simulate highlighting, and then capture the mousedown and mouseup events.
Here's a fiddle from StackOverflow user "fullpipe" which illustrates the technique I used.
http://jsfiddle.net/fullpipe/DpP7w/light/
$(document).ready(function() {
var keylist = "abcdefghijklmnopqrstuvwxyz123456789";
function randWord(length) {
var temp = '';
for (var i=0; i < length; i++)
temp += keylist.charAt(Math.floor(Math.random()*keylist.length));
return temp;
}
for(var i = 0; i < 500; i++) {
var len = Math.round(Math.random() * 5 + 3);
document.body.innerHTML += '<span id="'+ i +'">' + randWord(len) + '</span> ';
}
var start = null;
var end = null;
$('body').on('mousedown', function(event) {
start = null;
end = null;
$('span.s').removeClass('s');
start = $(event.target);
start.addClass('s');
});
$('body').on('mouseup', function(event) {
end = $(event.target);
end.addClass('s');
if(start && end) {
var between = getAllBetween(start,end);
for(var i=0, len=between.length; i<len;i++)
between[i].addClass('s');
alert('You select ' + (len) + ' words');
}
});
});
function getAllBetween(firstEl,lastEl) {
var firstIdx = $('span').index($(firstEl));
var lastIdx = $('span').index($(lastEl));
if(lastIdx == firstIdx)
return [$(firstEl)];
if(lastIdx > firstIdx) {
var firstElement = $(firstEl);
var lastElement = $(lastEl);
} else {
var lastElement = $(firstEl);
var firstElement = $(lastEl);
}
var collection = new Array();
collection.push(firstElement);
firstElement.nextAll().each(function(){
var siblingID = $(this).attr("id");
if (siblingID != $(lastElement).attr("id")) {
collection.push($(this));
} else {
return false;
}
});
collection.push(lastElement);
return collection;
}
As you can see in the fiddle, the gibberish text in the right pane stays highlighted regardless of focus elsewhere on the page.
At that point, you're going to have to apply your color changes to all matching spans.

Issues with text formatting after jQuery

I have used code form here: Overflowed text with html in another div - to get text to flow over in a new div. However, now I have formatting issues with the text.
The first word of every paragraph is somehow followed by a line-break.
You can see an example here: http://jsfiddle.net/hm2yfw61/9/
var currentCol = $('.box:first');
var text = currentCol.html();
currentCol.html('');
text = text.replace(/ (?![^<>]*>)/gi, '%^%');
var wordArray = text.split('%^%');
$.fn.hasOverflow = function () {
var div = document.getElementById($(this).attr('id'));
return div.scrollHeight > div.clientHeight;
};
for (var x = 0; x < wordArray.length; x++) {
var word = wordArray[x];
currentCol.append(word + ' ');
if (currentCol.hasOverflow()) {
currentCol = currentCol.next('.box');
}
}
Does anyone know how I can fix this?
Thanks.
-----UPDATE: I've updated the jsfiddle with the working solutions suggested in reference for others who may face similar problems ------
This might be a bit hacky, but try the following:
Add the following CSS rule
.box > p:first {
display: none;
}
Add "nbsp; " (including the space) at the beginning of each string in .box > p tags.
<p> Jumo handango
Updated Fiddle

Generating random divs multiple times on load

let me just give a quick story. I have made a page. (VERY simple - two divs with a different background image, see here.)
Anyway, I need to make it so that when a new page loads, the two divs that I have load in a random order over and over, filling the entire screen content. So there's no pattern of the first div and then the second, it's just randomly generated. Sort of like a huge grid, with the two divs repeated with no pattern.
My question is...is that possible? I assume I'd need to know PHP, but I have no knowledge of it.
Thanks guys, I appreciate all help!
http://jsfiddle.net/uYPRq/
jquery
var div1 = '<div class="one">';
var div2 = '<div class="two">';
var len =
Math.floor(window.innerWidth/30)*Math.floor(window.innerHeight/30);
for (x = 0; x < len; x++) {
if ( Math.random() > 0.5 ) {
$(div1).appendTo('body');
}
else {
$(div2).appendTo('body');
}
}
css
div.one, div.two {
height:30px;
width:30px;
float:left;
}
div.one { background-color:#EBE1E4; }
div.two { background-color:#F0F5DF; }
edit:
changed screen.availWidth to window.innerWidth
Something like so? Just loop through how ever many times you like and add elements in.
for (i = 0; i < 300; i++) {
var type1 = document.createElement("div");
var type2 = document.createElement("div");
type1.innerHTML = "div1";
type2.innerHTML = "div2";
type1.setAttribute("class", "type1");
type2.setAttribute("class", "type2");
document.body.appendChild(type1);
document.body.appendChild(type2);
}
No PHP needed. This can be done client-side using Javascript (Jquery might be easier).

Categories

Resources