I'm working on a react component that would render a loading animations.
Here is the js file
import React from 'react'
import './css/CircleSpinner.css'
const CircleSpiner = () => {
return (
<div className="lds-circle" >
</div>
)
}
export default CircleSpiner
The CSS is on a separate file and the component doesn't render the animations as expected. Any help would be appreciated.
Here's the code sandbox for the above.
You need content or draw the circle:
.lds-circle > div {
display: inline-block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
border: 1px solid #000;
color: black;
animation: lds-circle 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
You are missing border: 1px solid #000; or content so you can view the circle.
Also define the CircleSpiner and use it on your app.js:
CircleSpiner.js
import React from 'react'
const CircleSpiner = () => {
return (
<div>
</div>
)
}
App.js
export default CircleSpiner
import "./styles.css";
import CircleSpiner from "./CircleSpiner"
export default function App() {
return (
<div className="App">
<div className="lds-circle">
<CircleSpiner></CircleSpiner>
</div>
</div>
);
}
Your CSS does not correspond to your html. Specifically, this rule here:
.lds-circle > div {
display: inline-block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
color: black;
animation: lds-circle 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
The .lds-circle > div selector means "any div which is a direct descendent of .lds-circle". You don't have any descendents of your class so it targets nothing. The second issue is that you are providing a color property which styles foreground elements like text, but you (presumably) want a background-color property to see the background of the div element.
So, putting those two together:
.lds-circle > div {
display: inline-block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
background-color: black;
animation: lds-circle 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
#keyframes lds-circle {
0%,
100% {
animation-timing-function: cubic-bezier(0.5, 0, 1, 0.5);
}
0% {
transform: rotateY(0deg);
}
50% {
transform: rotateY(1800deg);
animation-timing-function: cubic-bezier(0, 0.5, 0.5, 1);
}
100% {
transform: rotateY(3600deg);
}
}
<div class="lds-circle" >
<div></div>
</div>
Related
I want to make
background-color: green;
border: 5px solid green;
for a button only for 0.5 seconds effect after a click, to animate a click. How can I do it?
You'll need to use some JavaScript to detect the click and change change the styles. You could possibly make do with a CSS animation, but you'd still need JavaScript to trigger it, so I'm not sure it's worth the effort to make it work in CSS anyways:
function setStyles(el, styles) {
Object.entries(styles).map(
([property, value]) => el.style[property] = value
)
}
const btn = document.querySelector("button")
btn.addEventListener("click", () => {
// capture original styles
const origStyles = {
background: btn.style.background,
border: btn.style.border,
}
// set temp styles
setStyles(btn, {
background: "green",
border: "5px solid green",
})
// reset original styles after 0.5 seconds
window.setTimeout(() => setStyles(btn, origStyles), 500)
})
<button>Click Me</button>
.foo-button {
/* Disable OS styling */
appearance: none;
border: none;
/* Rounded corners */
border-radius: 4px;
/* Text padding */
padding: 6px 12px;
/* Normal color */
background: #2442a0;
/* Text style */
color: white;
text-shadow: 0 0 1px rgba(0, 0, 0, .3);
/* Animation (“transition” timing) */
transition: .5s background;
}
.foo-button:active {
animation-duration: .5s;
animation-name: blink;
animation-fill-mode: forwards;
animation-iteration-count: 1;
background: green;
}
#keyframes blink {
0% {
background: green;
}
100% {
background: #2442a0;
}
}
<button class="foo-button">Button Text</button>
I have a basic setup. When I increase the height, I get a smooth increase. When decreased, I should get a smooth decrease but instead a sharp decrease.
<div className="foo <!-- -->">Hey</div>
You may have noticed className and <!-- -->, I'm using react. <!-- --> gets replaced with the class to decrease the height.
// SCSS
.foo {
height 400px;
// background props
transition: all 250ms ease-out
}
.foo.decreaseClass {
height: 40px;
transition: all 250ms ease-in
}
When the new class is attached, the div becomes
<div className="foo decreaseClass">Hey</div>
How to get both transitions down/up?
It's because you're not properly closing the height declaration in .foo. You're using a comma instead of a semi-colon, rendering both height and transition declarations invalid. Also note the same declaration should contain a colon between the style property name and its value (height: 400px;).
Therefore, your element only has defined height and transition only when having both classes.
See it working:
document.querySelector('.foo').addEventListener('click', function(event) {
event.target.classList.toggle('decreaseClass')
})
.foo {
height: 200px;
transition: all 250ms ease-out;
border: 1px solid
}
.foo.decreaseClass {
height: 40px;
transition-timing-function: ease-in
}
<div class="foo">Hey</div>
Use CSS #keyframe animation and alternate properties. infinite is added just for demo purposes. Instead of height I added transform:scaleY(1) to (10).
Demo
body {
overflow: hidden
}
.test {
width: 200px;
margin: 10px;
background: red;
font-size: 32px;
text-align: center;
color: white
}
.B {
height: 40px;
animation: animB 1s alternate infinite;
transform-origin: top;
}
#keyframes animB {
0% {
transform: scaleY(1);
}
100% {
transform: scaleY(10);
}
}
<div class='test B'>TEST</div>
I'm trying to animate a width of an element using data from an API upon page load and I'm using Vue js. What I've done is I used inlined css and apply width value (from API data). I'm able to add the element width but it has no animation.
Vue template edited:
<li v-for="(stats, index) in teamStats[0]">
<div class="bar">
<span :style="'width:'+ stats +'%;'">
{{stats}}
</span>
</div>
</li>
Sass:
.bar {
span {
text-align: $l;
right: 0;
width: 0%;
-webkit-transition: width 1s;
-moz-transition: width 1s;
-o-transition: width 1s;
transition: width 1s;
}
}
You'll probably need to use the JavaScript transition hooks. Here's an example.
new Vue({
el: '#app',
data: {
stats: [],
},
created() {
// Simulate loading data from server
setTimeout(() => {
this.stats = [0.1, 0.15, 0.32, 0.55, 0.88, 0.96];
}, 500);
},
methods: {
onEnter(el) {
var stat = +el.dataset.stat;
var index = +el.dataset.index;
el.style.transitionDelay = index * 0.05 + 's';
el.style.width = (stat * 100) + '%';
el.style.backgroundColor = `hsl(${50 - 50 * stat | 0}, 100%, 50%)`;
},
},
});
.bars {
width: 400px;
}
.bar {
margin: 5px 0;
height: 30px;
display: flex;
align-items: center;
justify-content: flex-end;
color: white;
font-family: sans-serif;
font-weight: bold;
padding: 5px;
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
}
.bar.v-enter-active {
transition: all 1s cubic-bezier(0, 1, 0.5, 1);
}
.bar.v-enter {
/* Needs !important to override inline styles */
opacity: 0;
width: 0% !important;
background-color: hsl(50, 100%, 50%) !important;
}
<script src="https://cdn.rawgit.com/vuejs/vue/dev/dist/vue.min.js"></script>
<div id="app">
<transition-group tag="div" class="bars" #enter="onEnter">
<div class="bar" v-for="stat, index of stats" :key="stat" :data-stat="stat" :data-index="index">
{{ (stat * 100 | 0) }}%
</div>
</transition-group>
</div>
I'm doing an animation that gets triggered with adding a class to a element. Now on removal of the class I want the animation to go the other way, I figured out to how to reverse the animation, the problem is onload that it triggers it. What can I do to prevent it, what can I change, what am I missing?
the full html/css/js are in the fiddle
here are the good parts,
#keyframes expand {
20% {
opacity: 0;
width: 5rem;
}
70%, 100% {
opacity: 1;
transform: translate(0, 0);
width: 100%;
}
}
#keyframes contract {
0% {
transform: translate(0, 0);
width: 100%;
}
100% {
transform: translate(0, -6rem);
width: 5rem;
}
}
[data-am-button~="buy"] {
margin-bottom: .5rem;
transform: translate(0, -6rem);
width: 5rem;
animation: contract 500ms forwards;
span {
display: none;
}
.is-expanded & {
animation: expand 500ms forwards;
}
}
So instead of putting the animation on the button by default. Add the animation to a .is-contracted class.
Then toggle between these 2 classes when clicking the button. This means that nothing is animated on the page load. Only the button clicking.
CSS changes:
[data-am-button~="buy"] {
margin-bottom: .5rem;
transform: translate(0, -6rem);
width: 5rem;
//animation: contract 500ms forwards; <-- Removed this
span {
display: none;
}
.is-expanded & {
animation: expand 500ms forwards;
}
.is-contracted & {
animation: contract 500ms forwards;// <-- added it to this new class
}
JS changes:
$('.js-expander').on('click', function() {
var $this = $(this);
var $parent = $this.parents('.product-info');
if ( $parent.hasClass('is-expanded') ){
$parent.removeClass('is-expanded')
$parent.addClass('is-contracted')
} else {
$parent.addClass('is-expanded')
$parent.removeClass('is-contracted')
}
});
Here's a fiddle : https://jsfiddle.net/BradChelly/Lugnmmpe/7/
I'm trying to set the keyframes of a pulsate animation in ReactJS. I tried just setting the keyframes inside the inline style but that doesn't work.
My code
const NewRelpyheButton = ({style = {}, open, handleOPenSettings}) => {
var bar = {
color: '#000',
padding: '1em 0',
fontSize: '20px',
textAlign: 'center',
cursor: 'pointer',
position: 'fixed',
bottom: '0',
width: '100%',
zIndex: '10',
animation: 'pulse 1.2s ease-in-out',
animationIterationCount: 'infinite',
}
Object.assign(style, {});
let openModal;
if (open) {
openModal = <Modal><NewRelpyhe/></Modal>
}
return (
<div>
{openModal}
<Bar color='purple' style={bar} onClick={handleOpenSettings}>
create a new relphye site
</Bar></div>
)
}
I'm trying to mimic this in css:
.element {
width: 100%;
height: 100%;
animation: pulse 5s infinite;
}
#keyframes pulse {
0% {
background-color: #001F3F;
}
100% {
background-color: #FF4136;
}
}
html,
body {
height: 100%;
}
If you like to keep all your styling tightly coupled to your components, give Styled Components a go. They have a helper for keyframes
e.g.
import styled, { keyframes } from 'styled-components'
const pulse = keyframes`
from {
background-color: #001F3F;
}
to {
background-color: #FF4136;
}
`
const Bar = styled.div`
color: #000;
padding: 1em 0;
font-size: 20px,
text-align: center;
cursor: pointer;
position: fixed;
bottom: '0',
width: 100%;
z-index: 10;
animation: ${pulse} 1.2s ease-in-out;
animation-iteration-count: infinite;
`
Then use like so:
<Bar>I pulse</Bar>
Here's how we will achieve it without adding any dependency.
{/*Your Js File Code */}
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import React from "react";
import "./test.css";
class Anim extends React.Component {
constructor(props) {
super(props);
this.state = {
animationName: ""
};
}
addStylesheetRules(rules) {
var styleEl = document.createElement("style");
document.head.appendChild(styleEl);
var styleSheet = styleEl.sheet;
styleSheet.insertRule(rules, 0);
}
clickHdl() {
let animationName = `animation${Math.round(Math.random() * 100)}`;
let keyframes = `
#-webkit-keyframes ${animationName} {
10% {-webkit-transform:translate(${Math.random() * 300}px, ${
Math.random() * 300
}px)}
90% {-webkit-transform:translate(${Math.random() * 300}px, ${
Math.random() * 300
}px)}
100% {-webkit-transform:translate(${Math.random() * 300}px, ${
Math.random() * 300
}px)}
}`;
this.addStylesheetRules(keyframes);
this.setState({
animationName: animationName
});
}
render() {
let style = {
animationName: this.state.animationName,
animationTimingFunction: "ease-in-out",
animationDuration: "0.6s",
animationDelay: "0.0s",
animationIterationCount: 1,
animationDirection: "normal",
animationFillMode: "forwards"
};
return (
<div>
<button type="button" onClick={this.clickHdl.bind(this)}>
Animation!
</button>
<div className="box" style={style}></div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Anim />
</StrictMode>,
rootElement
);
{/*Css Code test.css */}
.box {
width: 30px;
height: 30px;
background: red;
border-radius: 50%;
cursor: pointer;
}
Demo: https://codesandbox.io/s/reverent-sun-qjo91?file=/src/index.js