text as background. need 2nd background, need expert - javascript

My text is like background (body image) using
-webkit-background-clip: text;
-webkit-text-fill-color:transparent;
I would like to add moving element like on example below, but as you see if text color is set to yellow, everything is visible, but when text is set same as background image you wont see output.
Here is my HTML
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 100px;
position: absolute;
background-color: red;
}
#animate{
position:relative;
text-align:center;
-webkit-background-clip: text;
-webkit-text-fill-color:transparent;
z-index:20;}
#normal{
position:relative;
color:yellow;
z-index:22;
text-align:center;}
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id ="myContainer">
<div id ="myAnimation"></div>
<p id="animate">some text with background color</p>
<p id="normal">some text with yellow color</p>
</div>
My Javascript
<script>
function myMove() {
var elem = document.getElementById("myAnimation");
var pos = 0;
var id = setInterval(frame, 10);
var len = 50;
var hei = 100;
function frame() {
if (pos == 80 && len <250) {
pos=80;
len++;
elem.style.width = len + "px";
}
else if (len >249) {
hei--;
elem.style.height = hei + "px";
}
else {
pos++;
elem.style.left = pos + 'px';
}
}
}
</script>
In example I have set the background color as yellow and box as red. in My main project i have full HD img and around 50 shapes to create animated text. Main problem is that when box(shape) cover text with id #animate the text taking box background when it should stay with main body background(img)

job done xD example pmwebdev.co.uk
code for background:
body{
background-image: url("bg.png");
background-size: cover;
background-attachment: fixed;
}
code for text:
#slide1text{
text-decoration-style: bold;
margin: 0px;
font-size: 30px;
text-align: center;
background-image: url("bg.png");
background-size: cover;
background-attachment: fixed;
-webkit-background-clip: text;
-webkit-text-fill-color:transparent;
color: red;
position: relative;
z-index: 20;
}

Related

Can I use requestAnimationFrame to smooth out scroll behaviour?

I have a small scroll effect which simulate that a logo will disappear if a lower div will scroll over it.
Currently I'm checking if two divs are intersecting. If this is true, then the height of the div of the logo will decrease with the scroll position of the div beneath.
Unfortunately, my demo is not foolproof and some fragments of the logo are still visible.
Is there a way to do this jank-free? Maybe with requestAnimationFrame?
function elementsOverlap(el1, el2) {
const domRect1 = el1.getBoundingClientRect();
const domRect2 = el2.getBoundingClientRect();
return !(
domRect1.top > domRect2.bottom ||
domRect1.right < domRect2.left ||
domRect1.bottom < domRect2.top ||
domRect1.left > domRect2.right
);
}
const el1 = document.querySelector(".logo");
const el2 = document.querySelector(".clickblocks");
let scrollPositionEl2;
let heightDifference;
const logoHeight = el1.offsetHeight;
document.addEventListener("DOMContentLoaded", () => {
var scrollDirectionDown;
scrollDirectionDown = true;
window.addEventListener("scroll", () => {
if (this.oldScroll > this.scrollY) {
scrollDirectionDown = false;
} else {
scrollDirectionDown = true;
}
this.oldScroll = this.scrollY;
// test
if (scrollDirectionDown) {
if (elementsOverlap(el1, el2) === true) {
scrollPositionEl2 = el2.getBoundingClientRect().top;
heightDifference = logoHeight - scrollPositionEl2 + 100;
//console.log(logoHeight - heightDifference);
el1.style.height = `${logoHeight - heightDifference}px`;
}
} else {
//scrolling up
scrollPositionEl2 = el2.getBoundingClientRect().top - 100;
el1.style.height = `${scrollPositionEl2}px`;
//console.log(logoHeight);
}
});
});
#import url("https://fonts.googleapis.com/css2?family=Inter:wght#900&display=swap");
.wrapper {
max-width: 100vw;
margin: 0 auto;
background-image: url("https://picsum.photos/1920/1080");
background-size: cover;
background-attachment: fixed;
height: 1200px;
position: relative;
&::after {
content: "";
position: absolute;
background: rgba(0, 0, 0, 0.3);
width: 100%;
height: 100%;
inset: 0;
}
}
body {
margin: 0;
}
main {
width: 100%;
height: 100vh;
position: relative;
z-index: 1;
}
.clickblocks {
width: 100%;
height: 200px;
display: grid;
grid-template-columns: repeat(12, (minmax(0, 1fr)));
}
.clickblock {
transition: all ease-in-out 0.2s;
backdrop-filter: blur(0px);
border: 1px solid #fff;
height: 100%;
grid-column: span 6 / span 6;
font-size: 54px;
font-weight: 700;
padding: 24px;
font-family: "Inter", sans-serif;
color: white;
text-transform: uppercase;
&:hover {
backdrop-filter: blur(10px);
}
}
.logo {
background: url("https://svgshare.com/i/ivR.svg");
width: 100%;
background-repeat: no-repeat;
background-position: top;
position: fixed;
top: 100px;
}
.logo-wrapper {
position: relative;
}
<div class="wrapper">
<main>
<div class="logo-wrapper" style="height: 390px">
<div class="logo" style="height: 300px">
</div>
</div>
<div class="clickblocks">
<div class="clickblock">
Some Content
</div>
</div>
</main>
</div>
Few things here to optimize your performance.
getBoundingClientRect() is a rather expensive calculation. If there are NO other options it's fine.
The Intersection Observer API is a lot more performant, and you can set the root element on the API. Then observe the element that is moving. This should be able to telly you if their are colliding.
Whenever you do scroll based logic, you should really try and throttle the logic so that the scroll any fires ever 16.6ms. That will reduce the number of times the calculations are made, and speed things up on the FE.
Learn how to use Google Chrome's performance tab. It can be overwhelming at first, but it gives you the ability to drill into the exact piece of code that's slowing your site down.
Learn about JS's event loop, and what's really going on under the hood. This video by Jake Archibald really help me understand it.
Hope this helped, sorry that I didn't give you an actual solution.

Hiding/Showing CSS elements does not work?

THE WHOLE CODE IN JSFIDDLE
I have been struggling to effectively remove the code and css created in the function Seifenblasen_blasen()
function Seifenblasen_blasen(){
btn1.style.display = 'none';
document.getElementById("text").innerHTML="Bubble"
const section = document.querySelector('section')
const createElement = document.createElement('spawn')
var size = Math.random() * 60;
createElement.style.width = 30 + size + 'px';
createElement.style.height = 30 + size + 'px';
createElement.style.left = Math.random() * innerWidth + "px";
section.appendChild(createElement);
setTimeout(() => {
createElement.remove()
},8000)
}
const Blaseninterval = setInterval(Seifenblasen_blasen, 100)
created CSS:
section {
width: 100%;
height: 100vh;
overflow: hidden;
background: #1F69FA;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
section.text{
font-size: 10em;
color: #333;
margin: 0 auto;
text-align: center;
font-family: consolas;
background-color:#1F69FA;
pointer-events: none;
border: none;
}
section spawn {
position: absolute;
bottom: -80px;
background: transparent;
border-radius: 50%;
pointer-events: none;
box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.5);
animation: animate 4s linear infinite;
}
section spawn:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
transform: scale(0.25) translate(-70%, -70%);
background: radial-gradient(#fff, transparent);
opacity: 0.6;
border-radius: 50%;
}
#keyframes animate {
0% {
transform: translateY(0%);
opacity: 1;
}
99% {
opacity: 1;
}
100% {
transform: translateY(-2000%);
opacity: 0;
}
section span {
margin-top: 700px;
font-size: 1em;
color: #333;
margin: 0 auto;
font-family: consolas;
background-color: #1F69FA;
border: none;
position: absolute;
}
HTML:
<section id="section">
<div class="content">
<button id="btn"></button>
<button id="btn1"></button>
</div>
</section>
to then execute the next function function next(). This removal is needed because when I don't remove the elements from the first function the second wont work. I could just do document.head.innerHTML = "" but that would then also remove the css needed for the button appearing in the next function. So then I tried to make variables with const
const btn = document.getElementById('text');
const btn1 = document.getElementById('text1');
const section = document.querySelector('section')
// in function Seifenblasen_blasen()
btn1.style.display = 'none';
// in function next()
section.style.display = 'none';
btn.style.display = 'none';
btn1.style.display = 'block';
to hide and show only parts of the css without removing the css entirely to keep the styling intact, but now nothing works anymore.(the button on the next Screen doesn't show up at all and the first button does not contain any styling) My endgoal is that I can essentially switch between two screens one showing the bubbles and one the bouncy balls and when I click on the button it goes on. (for example start is bubbles. I click -> Bounce, click again -> back to Bubbles and so on)

Linecolor of active line in textarea

Is it possible to highlight the current line in a text area with a background color?
Example:
textarea {
resize: none;
background-color: #202020;
line-height: 20px;
color: #FFFFFF;
height: 1200px;
width: 1000px;
}
<textarea spellcheck="false">
test
test
test
test
test
test
test
test
</textarea>
It is quite tricky formatting text within a textarea element.
This snippet takes a slightly different direction, it puts a div behind the textarea and on each keyup (and click) it finds the position of the caret (start of the selection) and copies characters from the textarea to the div up to that point, substituting the <br> for the newline (decimal value 10) character.
The div expands in height as lines are added or CSS decides it needs to do a line break. The div has a background image which is a linear gradient of 20px red from the bottom, this means its last line is highlighted and it will move up and down as things are deleted/added to the textarea.
function keyupnclick() {
highlight.innerHTML = '';
let x = textarea.selectionStart;
let str = '';
let i = 0;
for (i; i <= x; i++) {
let ch = textarea.value[i];
let chcode = textarea.value.charCodeAt(i);
if (chcode == 10) {
ch = '<br>';
}
str = str + ch;
}
highlight.innerHTML = str;
}
const textarea = document.querySelector('textarea');
const highlight = document.querySelector('.highlight');
textarea.addEventListener('keyup', keyupnclick);
textarea.addEventListener('click', keyupnclick);
.container {
background-color: #202020;
width: 1000px;
position: relative;
}
.highlight,
textarea {
/* ensure the highlighted div and the textarea have the same izing styles */
font-family: 'arial', sans-serif;
font-size: 16px;
line-height: 20px;
width: 1000px;
}
.highlight {
position: absolute;
height: auto;
background-image: linear-gradient(to top, red 0, red 20px, transparent 20px, transparent 100%);
color: transparent;
}
textarea {
resize: none;
background-color: transparent;
color: #FFFFFF;
height: 1200px;
position: relative;
}
<div class="container">
<div class="highlight"></div>
<textarea spellcheck="false">
test
test
test
test
test
test
test
test
test
</textarea>
</div>
Note: the highight div and the textarea are inside a div of the same dimensions as textarea in order to get the background gray color.

How to use more than one setInterval()?

I want to make the 'box' in the code move to the right and then go back to the left. I tried to use 2 setInterval but it didn't works (or maybe i don't know how to use 2 setInterval).
var box = document.getElementById("box");
var pos = 0;
var toRight = setInterval(move, 10);
function move() {
if (pos >= 150) {
clearInterval(toRight);
} else {
pos++;
box.style.left = pos + "px";
}
}
#container {
width: 200px;
height: 200px;
background-color: red;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
}
<div id="container">
<div id="box"></div>
</div>
<p id="demo"></p>
I tried so many ways and the code still doesn't run, can some one show me the way to make the 'box' move back from the right side. Thank you.
Your code was a good start, and #j08691's comment is the right direction to take it.
Use 1 interval function but keep track of which direction the box is moving and toggle it when desired.
let box = document.getElementById("box");
let pos = 0, right = true;
setInterval(() => {
pos += right * 2 - 1;
if (pos === 0 || pos === 150)
right = !right;
box.style.left = pos + "px";
}, 10);
#container {
width: 200px;
height: 200px;
background-color: red;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
}
<div id="container">
<div id="box"></div>
</div>
As an alternative you could also use css animations and skip the javascript part entirely:
#keyframes move {
from { left: 0; }
to { left: calc(100% - 50px); }
}
#container {
width: 200px;
height: 200px;
background-color: red;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
animation: move 2s linear alternate infinite;
}
<div id="container">
<div id="box"></div>
</div>
<p id="demo"></p>

On click button show div after time period finish

I am wordpress user and I have a website. Its' bounce rate is high so I want a loader that will show a div onclick button after specific time period finish.
Note: when the time period will start it must show a loader in circle to user but the time period should be completed in background. User should not see seconds stuff like that only see a loader.
function move() {
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(id);
document.getElementById('content').style.display='block';
} else {
width++;
elem.style.width = width + '%';
}
}
}
#myProgress {
width: 110%;
float:center;
background-color: #ddd;
}
#myBar {
width: 1%;
height: 30px;
background-color: #4CAF50;
}
#content{
display:none;
}
#button{padding:1em;
margin:auto;}
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button onclick="move()">Download Movie</button>
<div id="conten"><br>
<p>hello loader is successful</p>
</div>
<script src="build/app.js?v=4" type="text/javascript"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-114581422-1"></script>
Inside your function frame(), you are setting the DOM element with ID content to be visible document.getElementById('content').style.display='block'; and also in the CSS as #content.
But in the HTML, you have defined the ID of the div tag to be conten instead of content... (you missed the ending t in the html).
Edit: You have mentioned that you need a circular loader animation instead of the progress bar. Just replace the progress bar with a loader. You could create a simple circular loader using just html and CSS. When the progress is not yet 100%, display the loading animation. On completion, just hide it.
function move() {
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(id);
document.getElementById('loader').style.display = 'none';
document.getElementById('content').style.display = 'block';
} else {
width++;
document.getElementById('loader').style.display = 'block';
}
}
}
#myProgress {
width: 110%;
float: center;
background-color: #ddd;
}
#myBar {
width: 1%;
height: 30px;
background-color: #4CAF50;
}
#content {
display: none;
}
#button {
padding: 1em;
margin: auto;
}
.loader {
border: 8px solid #000000; /* black */
border-top: 8px solid #ffffff; /* white */
border-radius: 50%;
width: 45px;
height: 45px;
animation: spin 2s linear infinite;
display: none;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loader" id="loader">
</div>
<br>
<button onclick="move()">Download Movie</button>
<div id="content"><br>
<p>hello loader is successful</p>
</div>
<script src="build/app.js?v=4" type="text/javascript"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-114581422-1"></script>

Categories

Resources