My goal is to get a randomized shine effect on certain text using CSS animation.
I already have a working code, just want to know if there a more effective/simple solution.
HTML:
<span class="foo">
<span class="bar">
</span>
</span>
CSS:
#keyframes masked-animation {
0% {background-position: -1000px 0}
50% {background-position: 1000px 0}
100% {background-position: 1000px 0}
}
.foo{
text-align: center;
font-size: 40px;
font-weight: bold;
display: block;
color: red;
position: absolute;
}
.bar{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
color: rgba(0,0,0,0);
background-image: linear-gradient(-45deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.67) 48%, rgba(255,255,255,0.9) 50%, rgba(255,255,255,0.67) 52%, rgba(255,255,255,0) 100%);
background-repeat: no-repeat;
-webkit-background-clip: text;
animation-name: masked-animation;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
background-size: 400% 100%;
}
JS:
$('.foo')[0].childNodes[0].nodeValue = "Text";
$('.foo > .bar').css({
"animation-duration" : 8 + Math.round(Math.random()*40)/10 + "s",
"animation-delay" : Math.round(Math.random()*100)/10 + "s"
}).text("Text");
In order for the animation to look properly, it needs to be above the element/text. Having it on the same element will render it behind.
I tried using ::before but I can't select it with JS since it doesn't actually exist in the DOM.
This needs to be applied to multiple elements and text inside <span> changes every so often.
JSFiddle
An alternative may be to create and directly manipulate a style sheet in javascript. In this way, iterating over the elements is handled by the browser rather than in javascript.
Setting up such a stylesheet is described in MDN's CSSStyleSheet.insertRule() examples.
There is also a jQuery library for these kind of manipulations.
And a working example:
var styleElement = document.createElement('style');
document.head.appendChild(styleElement);
var styleSheet = styleElement.sheet,
ruleIdx = styleSheet.insertRule('.target{}',styleSheet.cssRules.length),
rule = styleSheet.cssRules[ruleIdx],
colorize = function() {
var color = Math.random() * 360;
rule.style.color = 'hsl('+color+',100%,50%)';
},
interval = setInterval(colorize,1000);
colorize();
<div class="target" style="font-size:5em;font-weight:bold;font-family:sans-serif">TEST</div>
Related
I'm using class binding on an element which then should have its scaleY() change from 1 to 0. When I tried the transition with a :hover selector it worked perfectly but when I actually try it with class binding it just pops off without the desired transition.
I looked online and most of the already answered question were about the CSS that was incorrect such as this example (angular ng-class appending classes does not trigger css3 transition).
Here's the code :
filledPortionis an array containing 10 booleans if they're set to true then it adds the filled class, which it does ! I'm gonna repeat myself but Angular does add/remove the class as it should my only problem is that it skips my transition (which is working when I tried using it with an :hover selector)
component.html
<div class="bar" [class.end]="typeEnd">
<span *ngFor="let portion of filledPortion; let i = index" class="portion" [class.filled]="portion"></span>
</div>
component.scss
.bar {
.portion {
position: relative;
width: 2rem;
height: 1.5rem;
clip-path: polygon(100% 0, 0 0, 50% 100%);
&::before {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: bottom;
transform: scaleY(0);
background-color: var(--red);
transition: transform .250s cubic-bezier(0.4, 0.0, 0.2, 1);
z-index: 1;
}
&.filled::before {
transform: scaleY(1);
}
}
}
.end {
.portion {
&::before , &::after {
background-color: #fff;
}
}
}
So I have an image viewer which has a zoom functionality, which works via the transform: scale() property.
Animating the zoom is no problem with transition: transform .3s.
To make the zoom on the mousewheel go to where the mousewheel is pointed, I calculated the correct position to set the new origin, but when I set it, it just jumps there with no animation.
What I have tried:
Setting transition for the transform-origin property → Doesn't work
Doing it manually in JS with setTimeout and slowly setting the transform-origin at the right position → plays the zoom animation and then jumps
Is there any way to animate both transform: scale() and transform-origin in one go?
Dupe
As the last question has been closed as a duplicate of How to have multiple CSS transitions on an element?, here is a snippet, to show you that this is not my question.
const img = document.querySelector('#container img');
let on = true;
const toggleEffect = () => {
if(on) {
img.style.transform = 'scale(2.5)';
img.style.transformOrigin = '80% 80%';
} else {
img.style.transform = 'scale(1.4)';
img.style.transformOrigin = '20% 20%';
}
on = !on;
};
#container {
width: 500px;
height: 300px;
overflow: hidden;
background-color: red;
}
#container img {
height: 100%;
width: 100%;
object-fit: contain;
transform: scale(1.4);
transform-origin: 20% 20%;
transition: transform .3s, transform-origin .3s;
}
<div id="container">
<img src="https://images.unsplash.com/photo-1482066490729-6f26115b60dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=2004&q=80"/>
</div>
<button onclick="toggleEffect()">Toggle</button>
EDIT: Technically this is a duplicated. (Chrome Bug in some versions)
- Using both transition:
body, div {
width: 100%;
height: 100vh;
overflow: hidden;
}
div {
background-color: gray;
width: auto;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
transform: scale(1.1);
transform-origin: 50% -30px -100px;
transition: transform-origin .2s ease-in-out, transform 4s ease-in-out;
}
div:hover {
transform: scale(1.7);
transform-origin: 100px 100px;
}
<div>Test</div>
- Using animation with#keyframes:
body,div {
width: 100%;
height: 100vh;
}
div {
width: auto;
display: flex;
justify-content: center;
align-items: center;
transform-origin: 0 0 0;
animation: scale-origin 3s infinite;
font-size: 30px;
}
#keyframes scale-origin {
0% {
transform: scale(.5);
transform-origin: 100px 100px 1000px;
}
100% {
transform: scale(1.1);
transform-origin: left 500px -30px
}
}
<div>Test</div>
For me the only way to get around this bug was to ensure a redraw of the element on each "animation" (in this case transition) frame as you can clearly see via getComputedStyle that the transform-origin is correctly transitioned!
Basically I added eventlisteners for the transitionstart and transitionend and on each animationframe toggle some style attribute that enforces a redraw (f.e. in my case margin-left from 0 to 1 to 0px until the animation is finished)
function forceRedraw(ts) {
this.style.marginLeft = this.style.marginLeft == '1px' ? '0px':'1px';
if (this.classList.contains('transitioning'))
requestAnimationFrame(forceRedraw.bind(this));
}
In my example I transition rotation and the transform-origin (from top left to bottom left) at the same time.
https://codepen.io/ftav/pen/QWvYEPj
Depending on which element you modify this might have more or less of a performance impact. It works fine for me. I just wish they would fix the bug and this workaround could go away.
I have an h1 and a positioned over a canvas element. It ends up looking like this:
(note the weird black boxes around the text)
If it's relevant, this text is part of an overlay that fades in/out on mouseover (handled with css :hover). The code is very simple and exactly what you'd expect, i think, but i'm happy to post if the answer isn't obvious.
Edit: Chrome-related? It actually looks fine on Safari
Any ideas?
Edit: relevant code (i think):
<div class="col-sm-6">
<canvas class="preview-canvas">
</canvas>
<div class="rollover-overlay">
<h1 class="game-title">NAME</h1>
<a class="play-button">play</a>
</div>
</div>
--
.col-sm-6 {
position: relative;
}
.rollover-overlay {
/* width and height set dynamically */
background-color: transparent;
position: absolute;
top: 0;
left: 15;
text-align: center;
transition: background-color 300ms;
}
.game-title {
opacity: 0;
transition: opacity 300ms;
}
a.play-button {
opacity: 0;
background-color:transparent;
transition: opacity 300ms, color 100ms, border-color 100ms;
}
.rollover-overlay:hover {
background-color: rgba(0, 0, 0, .5);
}
.rollover-overlay:hover .game-title,
.rollover-overlay:hover a.play-button {
opacity: 1;
}
--
I'm trying to create the following effect for any element using only jQuery/plugins:
In particular it should use a transform for the scale rather than width and height animation and be usable on any DOM element.
Is there a plugin available for jQuery which will achieve this effect? It should be quite simple: duplicate the dom object with clone(), reposition the clone over the original absolutely then animate a scale transform and opacity on the new element. However, I suspect it's not as simple as this.
Any ideas?
You don't need jQuery to accomplish that animation. You can use CSS3 animations and transform properties. Check out the following example I created:
http://jsbin.com/purik/1/
HTML:
<div class="logos">
<div class="logo"></div>
<div class="logo animated"></div>
</div>
CSS:
.logos {
position: relative;
}
.logo {
width: 100px;
height: 70px;
background: #CC0000 url(http://www.w3schools.com/images/w3logo.png) 50% 50% no-repeat;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.logo.animated {
position: absolute;
left: 0;
top: 0;
animation: scale-fadeout 2s infinite;
-webkit-animation: scale-fadeout 2s infinite;
}
#keyframes scale-fadeout {
0% {
transform: scale(1);
opacity: 1;
}
5% {
opacity: 1;
transform: scale(1.05);
}
100% {
opacity: 0;
transform: scale(1.35);
}
}
#-webkit-keyframes scale-fadeout {
0% {
-webkit-transform: scale(1);
opacity: 1;
}
5% {
opacity: 1;
-webkit-transform: scale(1.05);
}
100% {
opacity: 0;
-webkit-transform: scale(1.35);
}
}
This works if the parent element is position: relative, and the element itself is position: absolute.
Clones the element and then animates it to change the size, change the values of left and top, and the set opacity: 0.
Fiddle: http://jsfiddle.net/Ej38P/1/
I need to add a fade effect on my javascript function
Javascript
<script type="text/javascript">
window.onload=function() {
loginBtn = document.getElementById('loginBtn');
fader = document.getElementById('login_fader');
login_box = document.getElementById('login_box');
closebtn = document.getElementById('closelogin');
loginBtn.onclick=function(){
fader.style.display = "block";
login_box.style.display = "block";
}
closebtn.onclick=function() {
fader.style.display = "none";
login_box.style.display = "none";
}
}
</script>
HTML
<div id="login_fader"> </div>
<div id="login_box">
<table class="table-login">
<th>Login or Register</th>
<th><a id="closelogin">X</a></th>
<tr>
<td>Login</td>
<td>Register</td>
</tr>
</table>
</div>
CSS
<style type="text/css">
#loginBtn {
float: right;
margin-top: -6%;
cursor:pointer;
}
#login_fader {
background: black;
opacity: .5;
-moz-opacity: .5;
-filter: alpha(opacity=50);
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 5;
display: none;
}
#login_box {
width: 320px;
height: 200px;
border: 1px white solid:
background: #5a5a5a;
position: fixed;
top: 25%;
left: 35%;
z-index: 10;
display: none;
}
.table-login {
background: #FFF;
border-radius: 8px;
box-shadow: 0 0 5px 2px;
opacity: 0.95;
}
#closelogin {
float:right;
cursor:pointer;
}
</style>
Js fiddle
http://jsfiddle.net/U3n4j/
I have tried using the transition properties from css3 and tried applying both to login_box and login_fader.
I found some functions on the net but don't know how to link them to my already made function and i was thinking if there are any properties directly that i can link them to my function.
Proper way to fade in a static box in css3 and js 1.7 ++
This is a example using only webkit and modern javascripts classList.add
but you can add the other prefixes.-moz,-ms,-o
in this example i show only the animation.
css
.box{
width:100%;
height:100%;
position:fixed;
left:0;top:-100%;/*notice TOP -100%*/
opacity:0;
-webkit-transition:opacity 700ms ease,top 0 linear 700ms;/*notice TOP delay*/
background-color:rgba(0,0,0,0.7);
}
.box.active{
-webkit-transition:opacity 700ms ease,top 0 linear 0;
/*top transition not needed but could help to understand*/
top:0;
opacity:1;
}
js
function show(){
box.classList.add('active');
}
function hide(){
box.classList.remove('active');
}
var box=document.getElementsByClassName('box')[0],
button=document.getElementsByTagName('button')[0];
button.addEventListener('click',show,false);
box.addEventListener('click',hide,false);
DEMO
http://jsfiddle.net/RAu8Q/ not working anymore
http://jsfiddle.net/RAu8Q/17/ new syntax 10-2015
if you have any questions just ask.
I can't tell exactly what effect you're trying to achieve, but if you're going to use CSS transitions, then you need to be transitioning between numerical properties. I.e., you can't expect a fade to occur simply by transitioning from display:block to display:none. You'd want to use opacity instead.
First of all, don't try to use css transitions in conjunction with display property, that won't work! Instead, try transitioning other properties. Let's take opacity for instance (we'll simulate display: none/block functionality by setting opacity to 0/1)
Secondly, set the start value for opacity to 0 on the desired HTML element (the one you'd like to animate). Specify which property to animate (opacity in our case):
transition: opacity 1s;
-moz-transition: opacity 1s;
-webkit-transtion: opacity 1s;
When the login button is clicked, set opacity to 1:
loginBtn.onclick=function() {
fader.style.opacity = 1;
login_box.style.opacity = 1;
}
When the close button is clicked, set opacity back to 0:
closebtn.onclick=function() {
fader.style.opacity = 0;
login_box.style.opacity = 0;
}
Link to fiddle.
I believe that what you want to do needs css animations. So just create an animation class that fades out the target element and apply it after the user logs in.
#keyframes fadeOut {
from: {
opacity:1;
},
to: {
opacity:0;
}
}
then use apply it on the class
.fadeOut {
animation:fadeOut 0.25s forwards;
}
EXAMPLE
http://jsfiddle.net/zgPrc/