How can i pass prop to sass keyframe percent from jsx - javascript

Hi in my react project i need to create dynamic keyframes. I need to pass percent variable's value from jsx code. How can i do it? My SCSS Code :
:root {
--percent: 95%;
--dim: 0.75;
--period: 1s;
--delay: 1s;
}
$percent: 95%;
$dim: var(--dim);
$period: var(--period);
$delay: var(--delay);
#mixin animation($percent,$dim, $period, $delay) {
#keyframes blink {
#{$percent} {
opacity: 0
}
100% {
opacity: $dim
}
}
animation: blink $period infinite $delay ;
}
.MarkerWithId{
#include animation($percent, $dim, $period, $delay)
}
I tried to change the percent with JavaScript after page render but it didnt make any change.And I cant use var(--percent) for $percent

Related

Why is this keyframe animation not applied when using styled-jsx?

I tried adding the animation on a separate line without any condition, but than the transition is not applied. I also tried backticks instead of double quotes for the animation property without success.
How to have the both the animation applied when clicked is false and play the transition for the radius when clicked is true?
import { useState } from "react";
export default function Home() {
const [clicked, setClicked] = useState(false);
return (
<>
<main>
<svg onClick={() => setClicked((c) => !c)}>
<circle cx="50%" cy="40%" stroke="black" strokeWidth={2} fill="gray" />
</svg>
</main>
<style jsx>{`
svg {
width: 100%;
height: 100%;
}
circle {
r: ${clicked ? "10%" : "5%"};
animation: ${clicked ? "none" : "bounce 2s infinite"};
transition: r 0.8s ease-in-out;
}
#keyframes bounce {
0% {
r: 5%;
}
50% {
r: 6%;
}
100% {
r: 5%;
}
}
`}</style>
</>
);
}
This has to do with how styled-jsx applies their css rules.
each <style jsx> tag will be transpiled by babel into a piece of js code that will generate and keep track of an actual <style type="txt/css"/> tag in the html.
That tag will contain a unique ID, if you inspect that tag it will look something like this:
<style type="text/css" data-styled-jsx="">
svg.jsx-1097321267 {
width: 100%;
height: 100%;
}
circle.jsx-1097321267 {
r: 5%;
-webkit-animation: bounce 2s infinite;
animation: bounce 2s infinite;
-webkit-transition: r 0.8s ease-in-out;
transition: r 0.8s ease-in-out;
}
#-webkit-keyframes bounce-jsx-1097321267 {
0% {
r: 5%;
}
50% {
r: 6%;
}
100% {
r: 5%;
}
}
#keyframes bounce-jsx-1097321267 {
0% {
r: 5%;
}
50% {
r: 6%;
}
100% {
r: 5%;
}
}
</style>
Notice how the animation is also generated with the same ID.
bounce-jsx-1097321267.
Any static references/classes in the styles-jsx tag also get this id.
This is all done through babel at compile time.
The resulting js code will do all that referencing for you.
A problem arises when a assigning the css code dynamically.
It seems, that the ${clicked ? "none" : "bounce 2s infinite"}; rule fails to add the generated id to bounce animation name.
This might be by design or might be a bug, or simply a limitation in styled-jsx. IDK.
You have a couple of options to work around this,
probably the easiest way is the make the css style static, and add a class when new styling should be applied.
IE
circle {
r: 5%;
animation: bounce 2s infinite;
transition: r 0.8s ease-in-out;
}
.is-clicked {
animation: none;
r: 10%;
}
and applying a class to circle like
className={clicked && "is-clicked"}
, that way the animation name will be contain an id, and any rule using that animation will also receive the same id.
code sandbox for reference

Create one CSS animation from 3 separate

I am beginner to animation in CSS and I have exported from desing file CSS animation code for animation like this.
#keyframes first {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes second {
from {
opacity: 1;
}
to {
opacity: 1;
}
}
#keyframes third{
from {
opacity: 1;
}
to {
opacity: 0;
}
}
animation: ${first} 307ms ease-in-out 0ms normal,${second} 2193ms linear 307ms normal,
${third} 503ms ease-in-out 2500ms normal;
However I wonder if it is possible to make it in one animation? If I want to have the same times like in generated version. If so, in what way?

vue enter transition not working properly

i'm working on a project where i have to render some components with an enter and leave animation, when a component enters the screen it has to enter form the bottom, and when it leaves, it has to do it going upwards, the desired behavior is that when i change the :is property of the component tag, the current component goes upwards and the next one comes from the bottom, the code looks like this:
<template>
<div class="home">
<transition name="section">
<component :is="activeSection"></component>
</transition>
</div>
</template>
<script>
import comp1 from './comp1';
import comp2 from './comp2';
export default {
components: {
comp1,
comp2
},
data() {
activeSection: 'comp1'
}
</script>
<style scoped>
.section-enter {
top: 100vh;
}
.section-enter-to {
top: 0vh;
}
.section-enter-active {
animation-name: 'slideIn';
animation-duration: 1s;
}
.section-leave {
top: 0vh;
}
.section-leave-active {
animation-name: 'slideOut';
animation-duration: 1s;
}
.section-leave-to {
top: -100vh;
}
#keyframes slideIn {
from {
top: 100vh;
}
to {
top: 0
}
}
#keyframes slideOut {
from {
top: 0vh;
}
to {
top: -100vh;
}
}
</style>
but the actual behavior is that the first component goes upwards but the second appears inmediatly after without animation.
if i render one at a time (not destructing one and rendering another with the same action) everything works perfectly. I dont know what is happening.
There are a few problems in your CSS.
CSS Transitions and CSS Animations
A transition can be implemented using either CSS Transitions or CSS Animations. Your CSS incorrectly mixes the two concepts in this case.
In particular, the slideIn keyframes and .section-enter/.section-enter-to rules are effectively performing the same task of moving .section into view. However, this is missing a transition rule with a non-zero time, required to animate the change, so the change occurs immediately. The same issue exists for the slideOut keyframes and leave rules.
.section-enter {
top: 100vh;
}
.section-enter-to {
top: 0;
}
.section-enter-active {
transition: .5s; /* MISSING RULE */
}
.section-leave {
top: 0;
}
.section-leave-to {
top: -100vh;
}
.section-leave-active {
transition: .5s; /* MISSING RULE */
}
Removing the keyframes, and adding the missing rules (as shown above) would result in a working CSS Transition.
demo 1
Using CSS Animations
Alternatively, you could use keyframes with CSS Animations, where the animation is applied only by the *-active rules, and no *-enter/*-leave rules are used. Note your question contained unnecessary quotes in animation-name: 'slideIn';, which is invalid syntax and would be silently ignored (no animation occurs). I use a simpler shorthand in the following snippet (animation: slideIn 1s;).
.section-enter-active {
animation: slideIn 1s;
}
.section-leave-active {
animation: slideOut 1s;
}
#keyframes slideIn {
from {
top: 100vh;
}
to {
top: 0;
}
}
#keyframes slideOut {
from {
top: 0;
}
to {
top: -100vh;
}
}
demo 2
Optimizing CSS Transitions
You could also tweak your animation performance by using translateY instead of transitioning top.
/* top initially 0 in .wrapper */
.section-leave-active,
.section-enter-active {
transition: .5s;
}
.section-enter {
transform: translateY(100%);
}
.section-leave-to {
transform: translateY(-100%);
}
demo 3
Use a Mixin
Thanks for the explanation #tony19
please use a mixin for this so the logic can be repeated easily.
Also, your slideIn and slideOut can be combined by using reverse:
#mixin animationmixin($type:'animation', $style:'', $duration:1s) {
#keyframes #{$type}-#{$style} { // register animation
0% { opacity: 1; transform: none; } // reset style
100% { #content; } // custom style
}
.#{$style} { // add '.section'
&-enter-active, &-leave-active { // add '.section-enter-active', ...
transition: #{$duration};
}
&-enter, &-leave-to {
animation: #{$type}-#{$style} #{$duration}; // use animation
}
&-leave, &-enter-to {
animation: #{$type}-#{$style} #{$duration} reverse; // use animation in reverse
}
}
}
Use it like this:
#include animationmixin($style:'section') { // set custom styling
transform: translateY(100%);
};
And like this:
#include animationmixin($style:'fade') {
opacity: 0;
transform: scale(0.9);
};

How do I make a div flash from 0 opacity to 1, continuously without clicking?

It's "Scroll Down" text, and I just need it to smoothly flash back and forth from 0 opacity to 1 the whole time the user is on the page.
Here's the HTML and CSS:
<div class="begin-scroll">SCROLL<br>
<span>TO BEGIN</span>
</div>
.begin-scroll{
font-family:'Charliedontsurf';
font-size:43px;
color:#FFFFFF;
position:absolute;
bottom:20%;
width: 100%;
text-align: center;
line-height:0.7em;
opacity:0;
}
.begin-scroll span{
font-size:34px;
}
This is the code that works for the type of effect I want (minus the continuous flashing):
jQuery(document).ready(function($) {
$('.begin-scroll').delay(3500).fadeTo(1000,1).fadeTo(1000,0).fadeTo(1000,1).fadeTo(1000,0).fadeTo(1000,1);
});
This is the kind of code I want, but the console log was throwing a "too much recursion" error:
jQuery(document).ready(function($) {
$('.begin-scroll').delay(3500).fadeTo(1000,1,pulsatingOut());
function pulsatingOut(){
$('.begin-scroll').fadeTo(1000, 0, pulsatingIn());
}
function pulsatingIn(){
$('.begin-scroll').fadeTo(1000, 1, pulsatingOut());
}
});
I'm not too fond of jQuery, so forgive me if this is a poorly put together and/or dumb question. Oh, and if you want to replace the jQuery altogether with plain 'ol javascript to solve this, please feel free, any solution helps.
Must it be Javascript/jQuery? This can be solved in CSS using animations and keyframes.
#-webkit-keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#-moz-keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#-o-keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#box {
-webkit-animation: NAME-YOUR-ANIMATION 2s infinite; /* Safari 4+ */
-moz-animation: NAME-YOUR-ANIMATION 2s infinite; /* Fx 5+ */
-o-animation: NAME-YOUR-ANIMATION 2s infinite; /* Opera 12+ */
animation: NAME-YOUR-ANIMATION 2s infinite; /* IE 10+, Fx 29+ */
}
<div id="box" style="width: 50px; height: 50px; background-color: red;"></div>
Remove the () from your complete parameters in the .fadeTo call. You want to simply pass a reference of that function, not the result.
;(function($){
$(function(){
// store a reference (slight cache improvement)
var $el = $('.begin-scroll');
// declare the functions
function pulsatingOut(){
$el.fadeTo(1000, 0, pulsatingIn);
}
function pulsatingIn(){
$el.fadeTo(1000, 1, pulsatingOut);
}
// call first one and have it loop through
pulsatingIn();
});
})(jQuery);
.begin-scroll { width: 100px; height: 100px; background-color: #f0f; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="begin-scroll"></div>
This is similar to Brad's answer, but a more basic approach.
As Brad said, you will want to pass a callback to the fadeTo method. Callbacks are also known as delegates, function references, etc. As soon as you add the parentheses at the end, you are telling JavaScript to execute that function reference.
Since I had already developed my fiddle while Brad was answering, here's what I came up with. It's not as self-contained, but it works and gives you a simplified idea. I did have to change your text color to black.
jsfiddle: http://jsfiddle.net/o5qgq6LL/1/
function pulsatingIn(){
$(this).fadeIn(1000, pulsatingOut);
}
function pulsatingOut(){
$(this).fadeOut(1000, pulsatingIn);
}
$('.begin-scroll').delay(3500).fadeIn(1000, pulsatingOut);
.begin-scroll{
font-family:sans-serif;
font-size:43px;
color:#000;
position:absolute;
bottom:20%;
width: 100%;
text-align: center;
line-height:0.7em;
display:none;
}
.begin-scroll span{
font-size:34px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="begin-scroll">SCROLL<br>
<span>TO BEGIN</span>
</div>

jQuery Animate() and BackgroundColor

I'm trying to create a simple pulse effect by changing the background color using JQuery. However, I can't get the backgroundColor to animate.
function show_user(dnid) {
/* dnid is HTML ID of a div. */
if (! $(dnid).is(':visible')) {
$(dnid).show()
}
$('html, body').animate({scrollTop: $(dnid).offset().top});
$(dnid).animate({backgroundColor: "#db1a35"}, 1200);
}
What's strange is that this alternate animation works:
$(dnid).animate({opacity: "toggle"}, 1200);
But it's not what I want at all.
Additionally the show() and scroll functionality in the function work fine. It's just the background color animation that doesn't.
The function above is called by this link
Locate Me
Could someone help me animate the background color?
=========
Thanks everyone for the help. Lots of similar answers. Here's what I ended up with
In my header
<script src="http://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Then in my show_user function right after the scroll animation.
var bgcol = $(dnid).css('backgroundColor');
$(dnid).animate({backgroundColor: "#db1a35"}, 2000);
$(dnid).animate({backgroundColor: bgcol}, 2000);
That gives a relatively quick red "pulse" that will draw the user's eyes.
Again, thanks for the help.
jQuery cannot animate colours by default. In order to animate colours, use the official jQuery.Color plugin.
All animated properties should be animated to a single numeric value, except as noted below; most properties that are non-numeric cannot be animated using basic jQuery functionality (For example, width, height, or left can be animated but background-color cannot be, unless the jQuery.Color() plugin is used).
Source
jQuery supports animation between any numeric CSS properties, which does not include colors. However, there are other libraries that make animating colors possible. One such library is the aptly-named jQuery Color. Its readme page shows several examples of how to use it to animate between colors using the jQuery .animate() function
Use the CSS animation property and keyframes
See it in action
HTML
<div></div>
CSS
div {
background-color: red;
height: 200px; width: 200px;
-webkit-animation: pulse 1s ease-in 0 infinite normal both;
-moz-animation: pulse 1s ease-in 0 infinite normal both;
-o-animation: pulse 1s ease-in 0 infinite normal both;
animation: pulse 1s ease-in 0 infinite normal both;
}
#-webkit-keyframes pulse {
0% { background-color: red; }
65% { background-color: #7F0093; }
100% { background-color: blue; }
}
#-moz-keyframes pulse {
0% { background-color: red; }
65% { background-color: #7F0093; }
100% { background-color: blue; }
}
#-ms-keyframes pulse {
0% { background-color: red; }
65% { background-color: #7F0093; }
100% { background-color: blue; }
}
#-o-keyframes pulse {
0% { background-color: red; }
65% { background-color: #7F0093; }
100% { background-color: blue; }
}
#keyframes pulse {
0% { background-color: red; }
65% { background-color: #7F0093; }
100% { background-color: blue; }
}
you must first set the background to the from color or it wont do anything 2nd time around.
You also typoed the css property 'background-color' and put it in quotes like i didn't :)
$(dnid).css({'background-color': "#ffffff"});
$(dnid).animate({'background-color': "#db1a35"}, 1200);
Just add this below your jQuery script and you are done:
<script src="https://cdn.jsdelivr.net/jquery.color-animation/1/mainfile"></script>

Categories