Consistent filling of SVG's rectangles - javascript

How to make each of these squares filled with red colour consistently left to right; and when one filled with red, previous will have default colour?
#foo > rect {
height: 32px;
width: 32px;
}
<svg id=foo height=32 width=160>
<rect x=0 y=0 />
<rect x=64 y=0 />
<rect x=128 y=0 />
</svg>
This animation must be repeatable.

If you are open to a CSS solution you can simulate such effect using background animation where you can easily scale to any number of square but without fading:
.rect {
height: 32px;
width:calc(40px*10); /* 10 Squares*/
background:
/* This gradient will make the red color to fade from the first to the last*/
linear-gradient(red,red) 0 0/32px 100% no-repeat,
/* This gradient will create the squares (32px of black then 8px of transparent)*/
repeating-linear-gradient(to right,black 0 32px,transparent 32px 40px);
margin:0 5px;
animation:change 10s steps(10) infinite;
}
#keyframes change{
to {
background-position:calc(100% + 32px) 0,0 0;
}
}
<div class="rect"></div>
With CSS variable you can control the different values:
.rect {
--s: 32px; /* Square size */
--nb: 10; /* Square number */
--gap: 8px; /* gap between squares */
--c1:black;
--c2:red;
height: var(--s);
width:calc((var(--gap) + var(--s))*var(--nb));
background:
linear-gradient(var(--c2),var(--c2)) 0 0/var(--s) 100% no-repeat,
repeating-linear-gradient(to right,var(--c1) 0 var(--s),#fff var(--s) calc(var(--s) + var(--gap)));
margin:5px;
animation:change calc(var(--nb)*1s) steps(var(--nb)) infinite;
}
#keyframes change{
to {
background-position:calc(100% + var(--s)) 0,0 0;
}
}
<div class="rect"></div>
<div class="rect" style="--nb:8;--s:50px;--c1:green;--c2:yellow"></div>
<div class="rect" style="--nb:15;--s:10px;--c2:blue"></div>

Use CSS keyframes:
#foo > rect {
height: 32px;
width: 32px;
animation: anim 3s infinite;
}
#foo > rect:nth-of-type(1){
animation-delay: 0s;
}
#foo > rect:nth-of-type(2){
animation-delay: 1s;
}
#foo > rect:nth-of-type(3){
animation-delay: 2s;
}
#keyframes anim{
0% { fill: black; }
50% { fill: red; }
100% { fill: black; }
}
<svg id=foo height=32 width=160>
<rect x=0 y=0 />
<rect x=64 y=0 />
<rect x=128 y=0 />
</svg>

Related

React inlined SVG paths are not responding to css animations

I uploaded my code and svgs to this github repo.
I have some svgs of some circles, blobs and triangles. I am trying to make the circles shake, like how the guy shakes in this code pen when you hover on him, I am trying to make the blobs move like waves like in this code pen, and I'm trying to make the triangles spin around. The blobs and triangles are not responding at all, even though I can see that they have the styling applied when I inspect the html. The circles have some effect, but not the one I want.
Here is the code for each
circles.scss
.circles > circle {
animation: shake 2.2s cubic-bezier(.36,.07,.19,.97) both;
}
#keyframes shake {
10%, 90% {
transform: translate3d(-1px, 0, 0);
}
20%, 80% {
transform: translate3d(2px, 0, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 0, 0);
}
40%, 60% {
transform: translate3d(4px, 0, 0);
}
}
triangles.scss
.triangles > g > path {
animation: triangle-animation 2.2s cubic-bezier(.36,.07,.19,.97) both;
}
#keyframes triangle-animation {
10%, 90% {
tranform: rotate(5deg);
}
20%, 80% {
tranform: rotate(90deg);
}
30%, 50%, 70% {
tranform: rotate(180deg);
}
40%, 60% {
tranform: rotate(30deg);
}
100% {
tranform: rotate(0deg);
}
}
waves.scss
.waves > path {
animation: wave-animation 4s infinite alternate;
// animation-duration: 4s;
// animation-iteration-count: infinite;
// animation-direction: alternate;
}
#keyframes wave-animation {
0% {
margin-left:0px;
margin-top:0px;
}
50% {
margin-left:-2000px;
margin-top:200px;
}
100% {
margin-left:0px;
margin-top:0px;
}
}
And this is my main App.js file
import React from 'react';
import Blobs from 'svg/Blobs.svg'
import Circles from 'svg/Circles.svg';
import Triangles from 'svg/Triangles.svg';
export default () => (
<div>
<Circles className="circles" />
<Blobs className=" w-100 h-100 waves" />
<Triangles className='w-100 triangles' />
</div>
);
The styles are imported in index.js
Thank you
Create components with the svg code inside then add your css classes ...
I advise you to start from scratch and create your own svg, it's easier than using already created svg.
(check the demo at the bottom of the page with the triangles, circles and waves)
App.js
import React from 'react';
import './style.css';
import Triangles from './svg/Triangles';
export default function App() {
return (
<div>
<Triangles />
</div>
);
}
Triangles.js
import React from 'react';
export default function Triangles() {
return (
<div className="triangles">
<svg className="triangle one">
<path d="M150 0 L30 200 L270 200 Z" />
</svg>
<svg className="triangle two">
<path d="M120 0 L30 180 L200 200 Z" />
</svg>
<svg className="triangle three">
<path d="M10 0 L40 280 L190 170 Z" />
</svg>
</div>
);
}
style.css
/* Triangles */
.triangles {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 50vh;
}
.triangle {
position: absolute;
fill: rgb(23, 233, 224);
fill-opacity: 0.4;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
.triangle.one {
height: 210px;
width: 300px;
animation-duration: 5000ms;
}
.triangle.two {
height: 150px;
width: 400px;
animation-duration: 9000ms;
}
.triangle.three {
height: 120px;
width: 300px;
animation-duration: 3000ms;
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
Demo : Stackblitz

How can i link this to an event on leaflet?

I've find a beautiful button in html/css that I have add on my leaflet map. (Adding the lines to my previous code)
I am blocked because this is not a real <button> and i don't find anything on Stackoverflow which answer to my question :(
I would like to add any functions which use Javascript, even a simple like add a Pop up when click on the button or anything which related to adding a little bit of interactivity like when click on the button, the zoom go on a specific place of the map.
I just want to know how to link this button to JavaScript.
Find below the section of my code that i want be linked to a function.
#import url('https://fonts.googleapis.com/css?family=Poppins:900i');
* {
box-sizing: border-box;
}
body {
height: 100vh;
display: flex;
justify-content: right;
align-items: right;
}
.wrapper {
display: flex;
justify-content: center;
z-index: 10000;
}
.cta {
right: auto;
margin-left: 500px;
top: 520px;
position: relative;
left: 500px;
display: flex;
padding: 3px 31px;
text-decoration: none;
font-family: 'Poppins', sans-serif;
font-size: 30px;
color: white;
background: #ffa500;
transition: 1s;
box-shadow: 6px 6px 0 black;
transform: skewX(-15deg);
}
.cta:focus {
outline: none;
}
.cta:hover {
transition: 0.5s;
box-shadow: 10px 10px 0 #FBC638;
}
.cta span:nth-child(2) {
transition: 0.5s;
margin-right: 0px;
}
.cta:hover span:nth-child(2) {
transition: 0.5s;
margin-right: 45px;
}
span {
transform: skewX(15deg)
}
span:nth-child(2) {
width: 20px;
margin-left: 30px;
position: relative;
top: 12%;
}
/**************SVG****************/
path.one {
transition: 0.4s;
transform: translateX(-60%);
}
path.two {
transition: 0.5s;
transform: translateX(-30%);
}
.cta:hover path.three {
animation: color_anim 1s infinite 0.2s;
}
.cta:hover path.one {
transform: translateX(0%);
animation: color_anim 1s infinite 0.6s;
}
.cta:hover path.two {
transform: translateX(0%);
animation: color_anim 1s infinite 0.4s;
}
/* SVG animations */
#keyframes color_anim {
0% {
fill: white;
}
50% {
fill: #FBC638;
}
100% {
fill: white;
}
}
<div class="wrapper">
<a class="cta" href="#">
<span>Datacenter SG</span>
<span>
<svg width="66px" height="43px" viewBox="0 0 66 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="arrow" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path class="one" d="M40.1543933,3.89485454 L43.9763149,0.139296592 C44.1708311,-0.0518420739 44.4826329,-0.0518571125 44.6771675,0.139262789 L65.6916134,20.7848311 C66.0855801,21.1718824 66.0911863,21.8050225 65.704135,22.1989893 C65.7000188,22.2031791 65.6958657,22.2073326 65.6916762,22.2114492 L44.677098,42.8607841 C44.4825957,43.0519059 44.1708242,43.0519358 43.9762853,42.8608513 L40.1545186,39.1069479 C39.9575152,38.9134427 39.9546793,38.5968729 40.1481845,38.3998695 C40.1502893,38.3977268 40.1524132,38.395603 40.1545562,38.3934985 L56.9937789,21.8567812 C57.1908028,21.6632968 57.193672,21.3467273 57.0001876,21.1497035 C56.9980647,21.1475418 56.9959223,21.1453995 56.9937605,21.1432767 L40.1545208,4.60825197 C39.9574869,4.41477773 39.9546013,4.09820839 40.1480756,3.90117456 C40.1501626,3.89904911 40.1522686,3.89694235 40.1543933,3.89485454 Z" fill="#FFFFFF"></path>
<path class="two" d="M20.1543933,3.89485454 L23.9763149,0.139296592 C24.1708311,-0.0518420739 24.4826329,-0.0518571125 24.6771675,0.139262789 L45.6916134,20.7848311 C46.0855801,21.1718824 46.0911863,21.8050225 45.704135,22.1989893 C45.7000188,22.2031791 45.6958657,22.2073326 45.6916762,22.2114492 L24.677098,42.8607841 C24.4825957,43.0519059 24.1708242,43.0519358 23.9762853,42.8608513 L20.1545186,39.1069479 C19.9575152,38.9134427 19.9546793,38.5968729 20.1481845,38.3998695 C20.1502893,38.3977268 20.1524132,38.395603 20.1545562,38.3934985 L36.9937789,21.8567812 C37.1908028,21.6632968 37.193672,21.3467273 37.0001876,21.1497035 C36.9980647,21.1475418 36.9959223,21.1453995 36.9937605,21.1432767 L20.1545208,4.60825197 C19.9574869,4.41477773 19.9546013,4.09820839 20.1480756,3.90117456 C20.1501626,3.89904911 20.1522686,3.89694235 20.1543933,3.89485454 Z" fill="#FFFFFF"></path>
<path class="three" d="M0.154393339,3.89485454 L3.97631488,0.139296592 C4.17083111,-0.0518420739 4.48263286,-0.0518571125 4.67716753,0.139262789 L25.6916134,20.7848311 C26.0855801,21.1718824 26.0911863,21.8050225 25.704135,22.1989893 C25.7000188,22.2031791 25.6958657,22.2073326 25.6916762,22.2114492 L4.67709797,42.8607841 C4.48259567,43.0519059 4.17082418,43.0519358 3.97628526,42.8608513 L0.154518591,39.1069479 C-0.0424848215,38.9134427 -0.0453206733,38.5968729 0.148184538,38.3998695 C0.150289256,38.3977268 0.152413239,38.395603 0.154556228,38.3934985 L16.9937789,21.8567812 C17.1908028,21.6632968 17.193672,21.3467273 17.0001876,21.1497035 C16.9980647,21.1475418 16.9959223,21.1453995 16.9937605,21.1432767 L0.15452076,4.60825197 C-0.0425130651,4.41477773 -0.0453986756,4.09820839 0.148075568,3.90117456 C0.150162624,3.89904911 0.152268631,3.89694235 0.154393339,3.89485454 Z" fill="#FFFFFF"></path>
</g>
</svg>
</span>
</a>
</div>
When you want to display a popup or something on a leaflet map, your posted code should contain your leaflet code. Also it is very helpful when you create a live demo, for example on jsfiddle.
But now to your question:
You can add a event over the default way addEventListener or with the leaflet library to a element. Here I use it over the leaflet library:
But first add a id to your button <div class="wrapper" id='testId'>
var button = document.getElementById('testId')
L.DomEvent.on(button,'click',function(e){
console.log('Button clicked')
});
When you want to open a popup on a specific location call:
L.DomEvent.on(button,'click',function(){
var latlng = map.getCenter(); // or [47.478058, 9.720154]
L.popup().setContent('Test').setLatLng(latlng).openOn(map)
});
I think your next question would be "How can I zoom to a marker":
This is a little bit difficult, because we need to know to which marker you want to zoom. This means that you have to save your marker to a global variable, so it can used in the button click event.
var latlng = map.getCenter(); // or [47.478058, 9.720154]
var marker = L.marker(latlng).addTo(map);
L.DomEvent.on(button,'click',function(){
var zoomlvl = 16;
map.flyTo(marker.getLatLng(),zoomlvl)
});

How to make half the border of a circle transparent

I have a minigame that the user has 60 seconds to solve. To indicate the remaining time, I use a number that will start at 60 and start going down 1 per second until reaching 0. This number will be inside a transparent circular div with a border:
.circle {
width: 100px;
height: 100px;
border: 3px solid #2F4491;
border-radius: 100%;
}
I'm trying to make the border dissapear proportionally to the remaining time: The border will be fully visible at the beginning (60s remaining), only the left side visible when the user only has 30s remaining, and so on.
Any idea on how to achieve this?
Try this.
var time = 60;
var initialOffset = '440';
var i = 1
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
var interval = setInterval(function() {
$('h2').text(i);
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset-((i+1)*(initialOffset/time)));
i++;
}, 1000);
.item {
position: relative;
float: left;
}
.item h2 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440; /* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item html">
<h2>0</h2>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#78cef1" fill="none"/>
</g>
</svg>
</div>
Set border-right-color and border-bottom-color to transparent when the time is below 30s. Also, you will have to rotate the object -45deg, so you will have it half-right and half-left.
When fade out, do the same with bottom and top.

SVG doesn't fill once the animation is over

My name is Daniel Götz and i'm currently working on my portfolio website but i have a problem. My SVG animation Doesn't fill once it is over.
My website : http://20162.hosts.ma-cloud.nl/portfoliowebsite/
If you scroll down to the H1 called: "Mijn skills" You can see the Photoshop logo being animated. But i want to fill once the animation is over.
Is there some way i can let it fill once the animation is over?
HTML:
<div class="photoshop">
<svg id="mySVG" class="finishe" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 486 486"><defs><style>.a{fill:#fff;stroke:#fff;stroke-miterlimit:10;}</style></defs><title>adobesave</title><path class="a" d="M321.27,328.414c-16.269,0-37.082-7.252-47.173-13.307l-9.743,39.2c13.307,7.252,33.866,12.3,56.916,12.3,50.361,0,76.376-24.124,76.376-57.012-.379-25.891-14.412-42.887-47.932-54.333C328.177,247.626,321.4,243.3,321.4,235.044c0-8.988,7.506-14.412,20.813-14.412,15.136,0,30.177,5.8,38.185,10.122l9.714-37.839c-10.817-5.424-29.168-10.091-49.76-10.091-43.58,0-71.676,24.88-71.676,57.644-.379,20.938,13.655,40.774,50.139,52.976,20.432,6.906,25.856,11.194,25.856,20.182C344.668,322.644,337.762,328.414,321.27,328.414Z" transform="translate(0.5 0.5)"/><path class="a" d="M141.687,276.194h0v86.845H87.353V123.446C104.225,120.61,128,118.4,161.489,118.4c33.9,0,58.021,6.4,74.167,19.456,15.64,12.2,25.983,32.417,25.983,56.194,0,23.744-7.881,43.957-22.42,57.643-18.6,17.6-46.417,25.479-78.834,25.479A139.4,139.4,0,0,1,141.687,276.194Zm.1-114.182h0v71.675c4.7,1.011,10.373,1.357,18.257,1.357,29.168,0,47.3-14.758,47.3-39.669-.125-22.3-15.545-35.572-43.01-35.572C153.261,159.8,145.629,160.907,141.782,162.012Z" transform="translate(0.5 0.5)"/><path class="a" d="M0,0V485H485V0ZM455,455H30V30H455Z" transform="translate(0.5 0.5)"/></svg>
</div>
CSS:
.photoshop {
height: 100px;
width: 100px;
opacity: 0;
}
.js-photoshop-animate{
opacity: 1;
}
.rzzhgcav_0 {
stroke-dasharray: 27046 27048;
stroke-dashoffset: 27047;
animation: rzzhgcav_draw_0 4000ms ease-in-out 0ms forwards;
}
#keyframes rzzhgcav_draw_0 {
100% {
stroke-dashoffset: 0;
}
}
/* Style */
#mySVG * {
fill-opacity: 0;
transition: fill-opacity 1s;
}
#mySVG finished * {
fill-opacity: 1;
}
JAVASCRIPT:
var $photoshop = $('.photoshop');
$photoshop.waypoint(function(){
console.log('Waypoint!');
$photoshop.addClass('js-photoshop-animate rzzhgcav_0');
}, {offset: '90%'} );
/* JavaScript */
new Vivus('mySVG', {}, function (obj) {
obj.el.classList.add('finished');
});
Include multiple attributes in your animation, leave off the transition:
Start and end of the individual property animations can overlap if you leave out the property you want to "run through" a keyframe:
If a property is not specified for a keyframe, or is specified but invalid, the animation of that property proceeds as if that keyframe did not exist.
.rzzhgcav_0 {
stroke-dasharray: 27046 27048;
stroke-dashoffset: 27047;
animation: rzzhgcav_draw_0 5000ms 0ms forwards;
}
#keyframes rzzhgcav_draw_0 {
0% {
stroke-dashoffset: 27047;
fill-opacity: 0
animation-timing-function: ease-in-out
}
50% {
fill-opacity: 0
animation-timing-function: linear
}
80% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
fill-opacity: 1
}
}

Animate dot after dot from an image using CSS3 or jQuery

I want to animate dot after dot from the below image but my problem is with the curved section of the image (bottom of the image).
At the start, all dots should be hidden and then one by one each dot should be animated into view.
I have the below code:
<div id="dots1"></div>
#dots1 {
-moz-transition: height 1s linear;
-o-transition: height 1s linear;
-webkit-transition: height 1s linear;
transition: height 1s linear;
position: absolute;
left: 50%;
z-index: 1;
margin: 0 0 0 -1px;
width: 3px;
height: 0;
background: url(image/pic.png) 0 0 no-repeat;
}
You can achieve this effect using two SVG path elements like in the below snippet. Two paths in the form of the curved line that you need is created. One path (which is at the bottom) has the dot pattern for the stroke (black colored) and another duplicate path which is on top. The duplicate path stroke is set such that for one full length of the path it is white in color and for another length it is transparent.
An animation is added on the duplicate path to animate stroke's offset. As offset is animated, the white portion of the stroke slowly moves out of view and the transparent portion starts coming into view. As the white portion starts going out of view, the black dots below it start getting revealed.
It is a bit complex to understand at start but once you get familiar with path, stroke-dasharray and stroke-dashoffset it will look simple.
svg {
height: 400px;
}
path {
fill: none;
}
path.dot {
stroke: black;
stroke-dasharray: 0.1 4;
stroke-linecap: round;
}
path.top {
stroke: white;
stroke-width: 2;
stroke-dasharray: 250;
stroke-linecap: round;
animation: dash 15s linear forwards;
}
#keyframes dash {
from {
stroke-dashoffset: 0;
}
to {
stroke-dashoffset: -250;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg viewBox='0 0 100 100'>
<path d='M1,1 1,45 C1,60 30,60 30,75 C30,90 1,90 1,100' class='dot' />
<path d='M1,1 1,45 C1,60 30,60 30,75 C30,90 1,90 1,100' class='top' />
</svg>
Try the following:
HTML
<div id="dots">
<img src="http://i.stack.imgur.com/oxUh8.png">
</div>
jQuery
$("#dots").css("height", "514px");
CSS
#dots{
overflow: hidden;
height: 10px;
transition: all 3s cubic-bezier(.5, 1, 0, .5);
}
See: https://jsfiddle.net/brezkryx/

Categories