First of all, it is working 100% fine for me on Chrome, but works just as title described when on Firefox
I'm trying to make a simple animation (using transitions) to run indefinitely when mouseover and to slowly go back to initial position when mouseout
The problem is that it is not behaving the same way in Firefox
As requested, here's a minimized and simplified code that reproduces my current issue:
var arcs = $("#logoSec");
var greenarc = $(".greenarc");
var garcMs = 2100; // In ms
var arcsAnimBool = false; // If false, stops the anim loop
greenarc.css({
transition: "transform " + (garcMs * 1) + "ms ease-in-out"
});
function greenArcNormal() {
if (!arcsAnimBool) return;
greenarc.css("transform", "rotate(70deg)");
setTimeout(greenArcRevert, garcMs); // Call the reverse rotation after garcMs ms
}
function greenArcRevert() {
if (!arcsAnimBool) return;
greenarc.css("transform", "rotate(-70deg)");
setTimeout(greenArcNormal, garcMs); // Call the normal rotation after garcMs ms
}
arcs.hover(
function() { // On mouseover
arcsAnimBool = true;
greenarc.css({
transition: "transform " + (garcMs * 1) + "ms ease-in-out"
});
greenArcNormal();
},
function() { // On mouseout
arcsAnimBool = false; // Set to false to stop the infinite loop of greenArcRevert/Normal
greenarc.css("transform", "rotate(0deg)"); // Revert arc back to initial position
greenarc.css({
transition: "transform " + (garcMs * 0.5) + "ms ease-in-out"
});
}
);
#ArcsLogo {
height: 550px;
}
#logoSec {
display: flex;
background-color: #fdfdfd;
}
<div id="logoSec">
<svg class="arcs" version="1.1" id="ArcsLogo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-12 30 383.4 407.5" style="enable-background:new 0 0 383.4 407.5;" xml:space="preserve">
<style type="text/css">
.greenarc {
fill: #00ff00;
transform-origin: 50% 50%;
}
.graycircle {
fill: #5d5d5d;
transform-origin: 50% 50%;
}
.redarc {
fill: #ff0000;
transform-origin: 50% 50%;
}
</style>
<path id="GreenArc" class="greenarc" d="M201.1,62.7c-3.2,0-6.3,0.1-9.4,0.3c77.7,5.5,136.2,72.9,130.7,150.6
c-4.9,70-60.7,125.8-130.7,130.7c3.1,0.2,6.3,0.4,9.4,0.4c77.9,0,141-63.1,141-141S279,62.7,201.1,62.7L201.1,62.7z" />
<circle id="GrayCircle" class="graycircle" cx="191.7" cy="203.7" r="21.2" />
<path id="RedArc" class="redarc" d="M60.2,203.7c0-84.6,65.9-154.6,150.4-159.6c-3.1-0.2-6.3-0.3-9.5-0.3
C112.8,43.2,40.7,114.2,40,202.5c-0.7,88.3,70.3,160.4,158.6,161.1c0.8,0,1.7,0,2.5,0c3.2,0,6.3-0.1,9.5-0.3
C126.2,358.3,60.2,288.3,60.2,203.7z" />
</svg>
</div>
(Simplified code in jsfiddle)
https://jsfiddle.net/Ferdam/htxcwanu/28/
(Old full code: https://jsfiddle.net/Ferdam/9kz52e6h/3/)
I have little experience with HTML/JS/JQuery/CSS so I might be missing something basic, I don't know.
Any help is appreciated. Thanks!
Edit:
Quoting directly what I answered to nivoli:
I forgot to mention that I tried using keyframes before, but the
problem is that I couldn't get it to work like the code I provided
because whenever I hoverout the elements just 'teleport' back to
initial position, which is why I started using css transitions.
I just couldn't find a way to animate the elements back to initial position
using keyframes
No javascript necessary; just use css animations. I only did the green one for you:
#ArcsLogo {
height: 550px;
}
#logoSec {
background-color: #fefefe;
}
.greenarc {
fill: #00ff00;
transform-origin: 50% 50%;
transform: rotate(70deg);
animation: myRotate 4200ms alternate infinite ease-in-out;
}
.graycircle {
fill: #5d5d5d;
transform-origin: 50% 50%;
}
.redarc {
fill: #ff0000;
transform-origin: 50% 50%;
}
#keyframes myRotate {
0% {
transform: rotate(70deg);
}
100% {
transform: rotate(-70deg);
}
}
<div id="logoSec">
<svg class="arcs" version="1.1" id="ArcsLogo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-12 30 383.4 407.5" style="enable-background:new 0 0 383.4 407.5;" xml:space="preserve">
<path id="GreenArc" class="greenarc" d="M201.1,62.7c-3.2,0-6.3,0.1-9.4,0.3c77.7,5.5,136.2,72.9,130.7,150.6
c-4.9,70-60.7,125.8-130.7,130.7c3.1,0.2,6.3,0.4,9.4,0.4c77.9,0,141-63.1,141-141S279,62.7,201.1,62.7L201.1,62.7z" />
<circle id="GrayCircle" class="graycircle" cx="191.7" cy="203.7" r="21.2" />
<path id="RedArc" class="redarc" d="M60.2,203.7c0-84.6,65.9-154.6,150.4-159.6c-3.1-0.2-6.3-0.3-9.5-0.3
C112.8,43.2,40.7,114.2,40,202.5c-0.7,88.3,70.3,160.4,158.6,161.1c0.8,0,1.7,0,2.5,0c3.2,0,6.3-0.1,9.5-0.3
C126.2,358.3,60.2,288.3,60.2,203.7z" />
</svg>
</div>
They key is to define the keyframes, which I just copied from the transform declarations you were making in javascript. Then by adding the animation rule to the greenarc class, we tell it to
use the keyframes myRotate (change the name to whatever you want)
take 4200ms to move from 0% to 100%. I doubled it because I think your logic took 2100ms to move from rotate(0) to rotate(70).
alternate the direction of the animation so that it goes back-and-forth rather than moving in one direction, then snapping back to where it started.
repeat the animation infinitely
use ease-in-out as you were doing in javascript to slow down as it gets closer to the ends.
See the animation documentation for more details and examples.
Related
I am createing a reset button for a sumulation as part of a web app. when you click the button it spins the reset icon. To do this I am using transform rotate to spin a text element, but when I spin it it it ends up lower than when it started. I have no idea why this is happening but googling the answer has got me nowhere.
any help is appreciated thx.
keyframes:
#keyframes spin360 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}
I call the keyframes in javascript using this function:
function spin() {
document.getElementById("resetButtonSvg").style.animation = "spin360 0.5s ease forwards";
}
*note it is called resetButtonSvg because I was planning to use an SVG but instead I ended up using Unicode.
just change your html to something like this
<button onclick="spin()">
<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" id="resetButtonSvg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 179.019 179.019" style="enable-background:new 0 0 179.019 179.019;" xml:space="preserve">
<g>
<g>
<path style="fill:#010002;" d="M138.121,138.357c-13.02,13.008-30.312,20.174-48.714,20.174c-37.955,0-68.84-30.867-68.876-68.81
l14.046,14.064c0.931,0.925,2.429,0.925,3.359,0c0.919-0.931,0.919-2.434,0-3.359L19.315,81.797L0.698,100.426
c-0.931,0.925-0.931,2.429,0,3.359c0.459,0.465,1.068,0.692,1.671,0.692c0.615,0,1.223-0.233,1.677-0.692l11.826-11.832
c1.235,39.531,33.689,71.328,73.512,71.328c19.673,0,38.164-7.661,52.079-21.57c0.925-0.925,0.925-2.429,0-3.353
C140.562,137.426,139.052,137.426,138.121,138.357z"/>
<path style="fill:#010002;" d="M178.32,75.234c-0.919-0.925-2.423-0.925-3.353,0L163.152,87.06
c-1.247-39.531-33.701-71.322-73.518-71.322c-19.685,0-38.17,7.661-52.085,21.57c-0.931,0.925-0.931,2.429,0,3.353
c0.919,0.931,2.429,0.931,3.353,0c13.014-13.008,30.312-20.174,48.714-20.174c37.949,0,68.84,30.861,68.888,68.81l-14.058-14.064
c-0.925-0.925-2.429-0.925-3.359,0c-0.919,0.931-0.919,2.434,0,3.359l18.623,18.623l18.617-18.623
C179.251,77.668,179.251,76.164,178.32,75.234z"/>
</g>
</g>
</svg>
</button>
and also apply this css on the button and the svg
button {
display: flex;
align-items: center;
padding: 10px;
}
svg {
width: 25px;
height: 25px;
}
I'm making a pomodoro clock in React and apply an animated filter: drop-shadow on an svg circle timer to make it look like it pulses.
This works fine on my Firefox desktop browser, but it makes my whole app laggy on Firefox mobile on my Android device. The app works fine on the Chrome mobile browser.
I noticed the app is still laggy even if I remove the animation and only apply a static filter: drop-shadow to the svg element. Is there a fix for this, or perhaps another way to achieve the effect I want?
Here is a codesandbox link for my app.
The relevant svg code is in PomodoroTimer.jsx, or here:
<svg width="17em" height="17em" viewBox="0 0 20em 20em">
<circle
cx="8.5em"
cy="8.5em"
r="5.8em"
fill="none"
stroke="#FFF"
strokeWidth=".05em"
/>
</svg>
<svg
className="pulse"
width="17em"
height="17em"
viewBox="0 0 20em 20em"
>
<circle
cx="8.5em"
cy="8.5em"
r="5.8em"
fill="none"
stroke="#FFF"
strokeWidth=".2em"
strokeDasharray="36.442em"
strokeDashoffset={36.442 * this.props.offsetModifier + "em"}
/>
</svg>
And the relevant CSS is in PomodoroTimer.css, or here:
svg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
transform: rotate(-90deg);
}
#-webkit-keyframes svg_pulse {
0% {
filter: drop-shadow(0 0 0.5em #fff);
}
50% {
filter: drop-shadow(0 0 1.5em #fff);
}
100% {
filter: drop-shadow(0 0 0.5em #fff);
}
}
#keyframes svg_pulse {
0% {
filter: drop-shadow(0 0 0.5em #fff);
}
50% {
filter: drop-shadow(0 0 1.5em #fff);
}
100% {
filter: drop-shadow(0 0 0.5em #fff);
}
}
.pulse {
-webkit-animation: svg_pulse 3s linear infinite;
animation: svg_pulse 3s linear infinite;
}
I have a back to top button that is supposed to appear when scrolling past the top part of the page, and disappears when it goes to the top of the page.
It appears in my local site copy when testing, but on the internet, it isn't showing and only the text link shows instead.
The site is at: https://www.ivanteong.com
The back to top button is implemented with the following:
Bottom of HTML page but above the JavaScript sources:
Top</div>
JavaScript sources at the bottom of the HTML page (When I put it in header there is problem with the menu scrolling):
<!-- JS -->
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/waypoints.min.js"></script>
<script src="../js/counterup.min.js"></script>
<script src="../js/inview.min.js"></script>
<script src="../js/easypiechart.js"></script>
<script src="../js/magnific-popup.min.js"></script>
<script src="../js/main.js"></script>
<script src="../js/backtotop.js"></script>
CSS styling for this in main.css:
.cd-top {
display: inline-block;
height: 40px;
width: 40px;
position: fixed;
bottom: 40px;
right: 10px;
z-index: 1000;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
/* image replacement properties */
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
background: GREY url(../images/cd-top-arrow.svg) no-repeat center 50%;
visibility: hidden;
opacity: 0;
border-radius: 10px;
-webkit-transition: opacity .3s 0s, visibility 0s .3s;
-moz-transition: opacity .3s 0s, visibility 0s .3s;
transition: opacity .3s 0s, visibility 0s .3s;
}
.cd-top.cd-is-visible, .cd-top.cd-fade-out, .no-touch .cd-top:hover {
-webkit-transition: opacity .3s 0s, visibility 0s 0s;
-moz-transition: opacity .3s 0s, visibility 0s 0s;
transition: opacity .3s 0s, visibility 0s 0s;
}
.cd-top.cd-is-visible {
/* the button becomes visible */
visibility: visible;
opacity: 1;
}
.cd-top.cd-fade-out {
/* if the user keeps scrolling down, the button is out of focus and becomes less visible */
opacity: .5;
}
.no-touch .cd-top:hover {
background-color: #FF432E;
opacity: 1;
}
backtotop.js:
jQuery(document).ready(function($){
// browser window scroll (in pixels) after which the "back to top" link is shown
var offset = 0,
//browser window scroll (in pixels) after which the "back to top" link opacity is reduced
offset_opacity = 1500,
//duration of the top scrolling animation (in ms)
scroll_top_duration = 1500,
//grab the "back to top" link
$back_to_top = $('.cd-top');
//hide or show the "back to top" link
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $back_to_top.addClass('cd-is-visible') : $back_to_top.removeClass('cd-is-visible cd-fade-out');
if( $(this).scrollTop() > offset_opacity ) {
$back_to_top.addClass('cd-fade-out');
}
});
//smooth scroll to top
$back_to_top.on('click', function(event){
event.preventDefault();
$('div,body,html').animate({
scrollTop: 0 ,
}, scroll_top_duration
);
});
});
cd-top-arrow.svg:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
<polygon fill="#FFFFFF" points="8,2.8 16,10.7 13.6,13.1 8.1,7.6 2.5,13.2 0,10.7 "/>
</svg>
This is a caching issue. I can't be 100% sure but I suspect that it has something to do with Cloudflare, which I use to manage my DNS, enforce HTTPS and redirect traffic from non-www to www. Paul LeBeau found that the css file is not updated, and I discovered that it is not updated for the www version, but the non-www is updated. After I loaded up these 2 variants of CSS, I don't know what happened but it works again. Maybe I "forced" Cloudflare to update the CSS file to the latest version and it couldn't use the cached copy of the CSS for the www site.
UPDATE: I'm sure this is Cloudflare's caching issue. I got the same problem again after changing the CSS for a loading animation for page loading. This problem is resolved if I want to make sure that Cloudflare only caches the latest copy of the files, by purging everything on Cloudflare's cache. Then it will have no problems loading up the latest code for my DNS.
How to create an cross browser (Mozilla, Chrome, Safari), animated SVG donut?
Currently I got this: https://jsfiddle.net/odnmhvm6/1/
This seems to be fine and exactly what I want (macOS, Chrome) but some problems appear: (ordered by priority)
Its oversized r="3200" to fit mostly all resolutions, how to make it responsive? -> Later I would add content in the inner-circle (solved by viewBox attribute )
Do not work on mobile (iPhone 6, Safari & Chrome) (done by using fixed values instead of calc())
Without the CSS Offset of .circle > stroke-dashoffset > -50 it laggs at start
I'm not that comfortable with SVG and that's the best result I reached so far, maybe I made it completly wrong for my purpose?
It should be responsive, fill out the complete screen always and work well with the common browsers. JS would be fine too, but is it necessary to reach it?
.item {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
svg {
width: 100%;
height: 100%;
}
.circle {
stroke-dasharray: 20106.192982975;
stroke-dashoffset: 20106.192982975;
-webkit-animation: circle-in 3s ease-in-out forwards, fade-in 0.5s ease-out forwards;
}
#-webkit-keyframes circle-in {
to {
stroke-dashoffset: 0;
}
}
<div class="item">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<g>
<circle id="circle" class="circle" r="3200" cy="50%" cx="50%" stroke-width="6200" stroke="#000000" fill="none"/>
</g>
</svg>
</div>
I'm trying to make an SVG circle bigger on a click event and it works just fine in Chrome 52 (haven't tried it on older versions) but in Firefox the CSS transition has no effect. Is there a way to make Firefox behave the same way as Chrome without too much JavaScript?
HTML:
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="50%" cy="50%" r="15"/>
</svg>
CSS:
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
circle {
-webkit-transition: ease 0.7s all;
-moz-transition: ease 0.7s all;
-ms-transition: ease 0.7s all;
-o-transition: ease 0.7s all;
transition: ease 0.7s all;
}
JS:
$(document).ready(function() {
$("body").click(function() {
if($("circle").attr("r") == 15) {
$("circle").attr("r", function() {
if ($(window).height() > $(window).width()) {
return Math.sqrt(Math.pow($(window).width(), 2) + Math.pow($(window).height(), 2));
}
return (Math.sqrt(Math.pow($(window).width(), 2) + Math.pow($(window).height(), 2)));
});
} else {
$("circle").attr("r", 15);
}
});
});
https://jsfiddle.net/xgscn4f1/
In SVG 1.1, which is the current standard, only certain attributes can by styled with CSS. The list of those properties can be found here:
SVG 1.1 property index
Note that r is not in this list.
In the upcoming SVG2 standard, most attributes will be stylable. But browsers have only just started to implement SVG2 features. Right now you can modify and transition r in Chrome, but not yet in other browsers.
You will need to use another technique to animate r. Either using SVG SMIL animation, or use one of the various SVG JS libraries that have animation functions.
You can animate any attributes of SVG elements easy with pure JS, including radius of circle, just give ID to element:
var c1 = document.getElementById("c1");
var strokeLength = 300;
c1.setAttribute("stroke-dasharray", "" + (strokeLength) + " 700");
function changeR(el) {
var n1 = 0;
var ch1 = 1;
var elT = setInterval(elTF, 5);
function elTF() {
el.setAttribute("r", n1);
if (n1 == 0) {
ch1 = 1;
} else if (n1 == 100) {
ch1 = -1;
}
n1 += ch1;
}
}
changeR(c1);
<svg width="250" height="200">
<circle id="c1" cx="100" cy="100" r="50" fill="transparent" stroke="blue" stroke-width="10" stroke-linecap="butt" stroke-dasharray="300 500" />
</svg>
Can animate stroke length too, via "stroke-dasharray" attribute, first parameter, second is for empty space.