Fabricjjs SVG with javascript doesnot supports in canvas - javascript

I'm trying to develop a component-> timer, which is an SVG file with timer functionality(written in javascript). The Svg file is given below.
<svg id="Timer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 223.26 67.89">
<!--Styles for blink circles animation-->
<style>
#import url('http://fonts.cdnfonts.com/css/nexa-bold');
#keyframes up-right {
0% {
transform: scale(1);
opacity: .25
}
50% {
transform: scale (1, 5);
opacity: 1;
}
100% {
transform: scale(1);
opacity: .25;
}
}
.circle {
border-radius: 50%;
width: 80px;
height: 80px;
opacity: .25;
}
.red {
background-color: red;
position: absolute;
top: 50%;
left: 50%;
-webkit-animation: up-right 1s infinite;
-moz-animation: up-right 1s infinite;
-o-animation: up-right 1s infinite;
animation: up-right 1s infinite;
}
</style>
<defs>
<linearGradient id="linear-gradient" x1="833.87" y1="1338.03" x2="833.87" y2="1384.21"
gradientTransform="translate(-792.51 -1332.57)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#474747" />
<stop offset="1" stop-color="#333" />
</linearGradient>
<clipPath id="clip-path">
<rect x="20.94" y="11.97" width="40.86" height="20.43" transform="translate(82.73 44.37) rotate(180)"
fill="none" />
</clipPath>
<linearGradient id="linear-gradient-2" x1="833.87" y1="1340.41" x2="833.87" y2="1384.36"
gradientTransform="translate(-792.51 -1334.64)" xlink:href="#linear-gradient" />
<linearGradient id="linear-gradient-3" x1="763.61" y1="1337" x2="763.61" y2="1383.18"
gradientTransform="translate(-651.98 -1330.51)" xlink:href="#linear-gradient" />
<clipPath id="clip-path-2">
<rect x="91.2" y="13" width="40.86" height="20.43" transform="translate(223.26 46.43) rotate(180)"
fill="none" />
</clipPath>
<linearGradient id="linear-gradient-4" x1="763.61" y1="1339.38" x2="763.61" y2="1383.33"
gradientTransform="translate(-651.98 -1332.58)" xlink:href="#linear-gradient" />
<linearGradient id="linear-gradient-5" x1="693.34" y1="1337" x2="693.34" y2="1383.18"
gradientTransform="translate(-511.45 -1330.51)" xlink:href="#linear-gradient" />
<clipPath id="clip-path-3">
<rect x="161.47" y="13" width="40.86" height="20.43" transform="translate(363.79 46.43) rotate(180)"
fill="none" />
</clipPath>
<linearGradient id="linear-gradient-6" x1="693.34" y1="1339.38" x2="693.34" y2="1383.33"
gradientTransform="translate(-511.45 -1332.58)" xlink:href="#linear-gradient" />
</defs>
<g style="isolation:isolate">
<g id="Layer_1" data-name="Layer 1">
<rect width="223.26" height="67.89" rx="5.59" fill="#fff" opacity="0.15" />
<rect x="4.51" y="2.92" width="215.16" height="62.3" rx="5.59" fill="#fff" opacity="0.07" />
<rect x="17.36" y="8.44" width="48" height="49.98" rx="5.84" transform="translate(82.73 66.86) rotate(180)"
fill="#fff" opacity="0.09" />
<rect x="20.94" y="11.97" width="40.86" height="42.92" rx="5.84"
transform="translate(82.73 66.86) rotate(180)" fill="url(#linear-gradient)" />
<g clip-path="url(#clip-path)">
<rect x="20.94" y="11.97" width="40.86" height="40.85" rx="5.84"
transform="translate(82.73 64.8) rotate(180)" fill="url(#linear-gradient-2)" />
</g>
<rect x="87.63" y="9.47" width="48" height="49.98" rx="5.84" transform="translate(223.26 68.92) rotate(180)"
fill="#fff" opacity="0.09" />
<rect x="91.2" y="13" width="40.86" height="42.92" rx="5.84" transform="translate(223.26 68.92) rotate(180)"
fill="url(#linear-gradient-3)" />
<g clip-path="url(#clip-path-2)">
<rect x="91.2" y="13" width="40.86" height="40.85" rx="5.84"
transform="translate(223.26 66.86) rotate(180)" fill="url(#linear-gradient-4)" />
</g>
<rect x="157.89" y="9.47" width="48" height="49.98" rx="5.84"
transform="translate(363.79 68.92) rotate(180)" fill="#fff" opacity="0.09" />
<rect x="161.47" y="13" width="40.86" height="42.92" rx="5.84"
transform="translate(363.79 68.92) rotate(180)" fill="url(#linear-gradient-5)" />
<g clip-path="url(#clip-path-3)">
<rect x="161.47" y="13" width="40.86" height="40.85" rx="5.84"
transform="translate(363.79 66.86) rotate(180)" fill="url(#linear-gradient-6)" />
</g>
<!--Time Display Text-->
<!-- <text transform="translate(30.07 42.83) scale(1.02 1)" font-size="24" fill="#fff" x="-2"
font-family="Nexa, sans-serif">
<tspan xml:space="preserve"></tspan>
</text> -->
<text transform="translate(24.25 41.95) scale(1.02 1)" font-size="24" fill="#00f9a6"
font-family="Nexa, sans-serif" x="2">
<tspan xml:space="preserve"></tspan>
</text>
<text transform="translate(94.19 41.95) scale(1.02 1)" font-size="24" fill="#00f9a6"
font-family="Nexa, sans-serif" x="1.2">
<tspan xml:space="preserve"></tspan>
</text>
<text transform="translate(164.94 41.97) scale(1.02 1)" font-size="24" fill="#00f9a6"
font-family="Nexa, sans-serif">
<tspan xml:space="preserve"></tspan>
</text>
<!--Time Display Text-->
<circle cx="77.18" cy="28.28" r="5.06" fill="#00f9a6" opacity="0.19" />
<circle class="circle red" cx="77.18" cy="28.28" r="3.07" fill="#00f9a6" opacity="0.11" />
<circle cx="77.18" cy="43.85" r="5.06" fill="#00f9a6" opacity="0.19" />
<circle class="circle red" cx="77.18" cy="43.85" r="3.07" fill="#00f9a6" opacity="0.11" />
<circle cx="147.3" cy="29.14" r="5.06" fill="#00f9a6" opacity="0.19" />
<circle class="circle red" cx="147.3" cy="29.14" r="3.07" fill="#00f9a6" opacity="0.11" />
<circle cx="147.3" cy="44.72" r="5.06" fill="#00f9a6" opacity="0.19" />
<circle class="circle red" cx="147.3" cy="44.72" r="3.07" fill="#00f9a6" opacity="0.11" />
</g>
</g>
<!-- Script For Time Display -->
<script type="text/javascript">
<![CDATA[
var hr = document.getElementsByTagName('tspan')[0];
var min = document.getElementsByTagName('tspan')[1];
var sec = document.getElementsByTagName('tspan')[2];
function time() {
var d = new Date();
var s = d.getSeconds();
var m = d.getMinutes();
var h = d.getHours();
hr.textContent = ("0" + h).substr(-2);
min.textContent = ("0" + m).substr(-2);
sec.textContent = ("0" + s).substr(-2);
}
setInterval(time, 1000);
]]>
</script>
</svg>
We tried this code, which is working for all images except this SVG with scripts
fabric.loadSVGFromURL(controller.value, (objects, options) => {
const image = fabric.util.groupSVGElements(objects, options);
image.set({
left: !_initPositionOfElement ? 50 : _initPositionOfElement.x + 10,
top: !_initPositionOfElement ? 50 : _initPositionOfElement.y + 10,
angle: 0,
padding: 0,
cornerSize: 15,
shadow: new fabric.Shadow(shadow),
lockRotation: false,
hasRotatingPoint: false,
perPixelTargetFind: true,
//minScaleLimit: 1,
scaleX: 1,
scaleY: 1,
});
this.canvas.add(image);
this.canvas.setActiveObject(image);
this.canvas.renderAll();
});
Is there any way to create a timer component in Fabricjs. Please help us with relevant information.

Related

How to animate svg height with CSS upward?

I am working with a svg element and I want to animate the height increasing upwards of these elements. But they are growing downward from the top probably due to SVG coordinate system. How can I make it go upwards from the bottom?
window.onload = function () {
var x1 = document.querySelector('svg').viewBox.baseVal.height;
var a = document.getElementById('wrapper1');
var bgArray = [];
for (var i = 1; i < a.children.length; i++) {
bgArray.push((a.children[i].getBBox().height / x1) * 100);
};
bgArray.forEach((x, i) => a.children[i + 1].style.setProperty("--h1", x + '%'));
bgArray.forEach((x, i) => a.children[i + 1].style.setProperty("--del", (i + 1) + 's')); //for staggered
}
.r1,
.r2 {
visibility: hidden;
animation: moveHeight 2s ease-in var(--del) 1 forwards;
}
#keyframes moveHeight {
0% {
visibility: visible;
height: 0%;
}
100% {
visibility: visible;
height: var(--h1);
}
}
<!DOCTYPE html>
<html>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g class="wrapper1" id="wrapper1" >
<rect x="10" y="20" width="120" height="120" stroke="black" fill="none"></rect>
<rect class="r1" id="r1" x="10" y="80" width="20" height="60" stroke="none" fill="orange"></rect>
<rect class="r2" id="r2" x="31" y="100" width="20" height="40" stroke="none" fill="green"></rect>
<!---->
</g>
</svg>
<script src="index.js"></script>
</body>
</html>
You could draw the bars but cover them and then gradually uncover them.
This covers them by adding white bars and shrinking those.
window.onload = function() {
var x1 = document.querySelector('svg').viewBox.baseVal.height;
var a = document.getElementById('wrapper1');
var bgArray = [];
for (var i = 1; i < a.children.length; i++) {
bgArray.push((a.children[i].getBBox().height / x1) * 100);
};
bgArray.forEach((x, i) => a.children[i + 1].style.setProperty("--h1", x + '%'));
bgArray.forEach((x, i) => a.children[i + 1].style.setProperty("--del", (i + 1) + 's')); //for staggered
}
.shrink {
animation: moveHeight 2s ease-in var(--del) 1 forwards;
}
#keyframes moveHeight {
0% {
height: var(--h1);
}
100% {
height: 0;
}
}
<!DOCTYPE html>
<html>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g class="wrapper1" id="wrapper1" >
<rect x="10" y="20" width="120" height="120" stroke="black" fill="none"></rect>
<rect class="r1" id="r1" x="10" y="80" width="20" height="60" stroke="none" fill="orange"></rect>
<rect class="r1 shrink" x="10" y="80" width="20" height="60" stroke="none" fill="white"></rect>
<rect class="r2" id="r2" x="31" y="100" width="20" height="40" stroke="none" fill="green"></rect>
<rect class="r2 shrink" x="30" y="99" width="22" height="41" stroke="none" fill="white"></rect>
<!---->
</g>
</svg>
<script src="index.js"></script>
</body>
</html>
Note, at some zoom levels a screen pixel of the underneath bars can be left showing (giving a faint vertical line at the start). To get round that the second white bar has been moved one left and made one wider (and similarly for height). Somewhat hacky so I hope someone can come up with a more straightforward solution.
I have looked into this brilliant answer but I had trouble visualizing and adapting it to my scenario. So after I figured out, I am trying to visually explain and show how to adapt to different scenarios.
The basic markup is following
<!DOCTYPE html>
<html>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="wrapper1" id="wrapper1" x="10" y="345" width="120" height="180" stroke="teal" fill="none"></rect>
<line class="upper clone" x1="10" y1="80" x2="220" y2="80" style="stroke:rgb(110, 31, 194);stroke-width:1" />
<g class="elements">
<line class="upper" x1="10" y1="80" x2="220" y2="80" style="stroke:rgb(87, 202, 91);stroke-width:1"/>
<rect class="r0" id="r0" x="10" y="80" width="83" height="180" stroke="brown" fill="none"></rect>
<rect class="r1" id="r1" x="10" y="80" width="20" height="60" stroke="none" fill="orange"></rect>
<rect class="r2" id="r2" x="31" y="80" width="20" height="10" stroke="none" fill="green"></rect>
<rect class="r3" id="r3" x="52" y="80" width="20" height="100" stroke="none" fill="blue"></rect>
<rect class="r4" id="r4" x="73" y="80" width="20" height="140" stroke="none" fill="magenta"></rect>
<line class="lower" x1="10" y1="260" x2="220" y2="260" style="stroke:rgb(87, 202, 91);stroke-width:1"/>
</g>
<line class="lower clone" x1="10" y1="260" x2="220" y2="260" style="stroke:rgb(218, 149, 22);stroke-width:1" />
<g class="wrapper2" id="wrapper2">
<rect x="140" y="0" width="50" height="700" stroke="red" fill="none"></rect>
</g>
</svg>
<script src="index2.js"></script>
</body>
</html>
For ease of understanding, I have created the two lines called upper and lower which are the start and end of all the rects. I have also cloned those lines where the transform will not apply.
The thumb rule of converting svg coordinate system to cartesian coordinate is to
use this transform="translate(0, maxY) scale(1, -1)".
The maxY is actually max total of (y+height). In this case it is 260. now this value can be manipulated to correctly place the rects prior to animation
<g class="elements" transform="translate(0,260) scale(1, -1)"> positions
<g class="elements" transform="translate(0,340) scale(1, -1)"> 260+rectY(80)=340 positions
<g class="elements" transform="translate(0,425) scale(1, -1)"> 260+rectY(80)+(wrapperY 345 -260) positions
and lastly positions at the bottom of the wrapper
<g class="elements" transform="translate(0,605) scale(1, -1)"> 260+rectY(80)+(wrapperY 345 -260)+wrapperHeight 180 = 605
Putting everything together with javascript and css
//converting svg coordinates to cartesian coordinates
// transform="translate(0, maxY) scale(1, -1)".
// or transform="scale(1, -1) translate(0, -maxY)".
window.onload = function app() {
var bgArray1 = []; //to collect only height
var bgArray2 = []; //to collect height + y
var wrapperElement = document.getElementById('wrapper1');
var wrapperY = wrapperElement.getBBox().y //what is the y coordinate of wrapper rect
var wrapperHeight = wrapperElement.getBBox().height;
var getRect = document.querySelectorAll('[class^="r"]');
for (var i = 0; i < getRect.length; i++) {
var _bBox = getRect[i].getBBox(); // getting the bBox for each rect
var _height = _bBox.height + _bBox.y //getting each rect's height
var _y = _bBox.y // getting each rect's y coordinate
var _heightAndY = _height + _y //total of Y+height of each rect
bgArray1.push(_height);
bgArray2.push(_heightAndY);
}
var _maxHeight = Math.max(...bgArray1); // use this if you want to position the rect at (y=0)
var _maxTotal = Math.max(...bgArray2); // use this if you want to position the rect at (y=0)
var _wrapperTop = _maxTotal + (wrapperY - _maxHeight); //use this if you want to postion the rect at the the
//top of the wrapper
var _wrapperBottom = _wrapperTop + wrapperHeight //use this if you wantto position the rects at the
//bottom of the wrapper
bgArray1.forEach((x, i) => getRect[i].setAttribute("transform", `translate(0,${_wrapperBottom}) scale(1,-1)`));
bgArray1.forEach((x, i) => getRect[i].style.setProperty("--del", (i + 1) + 's'))
}
[class^="r"] {
visibility: hidden;
animation: moveHeight 2s ease-out var(--del) 1 forwards;
}
#keyframes moveHeight {
0% {
visibility: visible;
height: 0
}
100% {
visibility: visible;
height: 100;
}
}
<!DOCTYPE html>
<html>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="wrapper1" id="wrapper1" x="10" y="345" width="120" height="180" stroke="teal" fill="none"></rect>
<line class="upper clone" x1="10" y1="80" x2="220" y2="80" style="stroke:rgb(110, 31, 194);stroke-width:1" />
<g>
<line class="upper" x1="10" y1="80" x2="220" y2="80" style="stroke:rgb(87, 202, 91);stroke-width:1"/>
<rect class="r0" id="r0" x="10" y="80" width="83" height="180" stroke="brown" fill="none"></rect>
<rect class="r1" id="r1" x="10" y="80" width="20" height="60" stroke="none" fill="orange"></rect>
<rect class="r2" id="r2" x="31" y="80" width="20" height="10" stroke="none" fill="green"></rect>
<rect class="r3" id="r3" x="52" y="80" width="20" height="100" stroke="none" fill="blue"></rect>
<rect class="r4" id="r4" x="73" y="80" width="20" height="140" stroke="none" fill="magenta"></rect>
<line class="lower" x1="10" y1="260" x2="220" y2="260" style="stroke:rgb(87, 202, 91);stroke-width:1"/>
</g>
<line class="lower clone" x1="10" y1="260" x2="220" y2="260" style="stroke:rgb(218, 149, 22);stroke-width:1" />
<g class="wrapper2" id="wrapper2">
<rect x="140" y="0" width="50" height="700" stroke="red" fill="none"></rect>
</g>
</svg>
<!--<script src="index.js"></script>-->
<script src="index2.js"></script>
</body>
</html>
Pure svg solution
The idea is to first hide the rectangles behind a masking strip.
Then raise them to the top by animating the y attribute of the rectangle
<animate id="anR1" xlink:href="#r1" attributeName="y" begin="Layer_1.click"
dur="1s" from="140" to="80" repeatCount="1" fill="freeze" />
<!DOCTYPE html>
<html>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g class="wrapper1" id="wrapper1" >
<rect x="10" y="20" width="120" height="120" stroke="black" fill="none"></rect>
<rect class="r1" id="r1" x="10" y="140" width="20" height="60" stroke="none" fill="orange"></rect>
<rect class="r2" id="r2" x="31" y="140" width="20" height="40" stroke="none" fill="green"></rect>
<rect class="r3" id="r3" x="52" y="140" width="20" height="80" stroke="none" fill="dodgerblue"></rect>
<!-- masking strip -->
<rect x="10" y="140" width="120" height="120" fill="white"></rect>
</g>
<animate id="anR1" xlink:href="#r1" attributeName="y" begin="Layer_1.click" dur="0.5s" from="140" to="80" repeatCount="1" fill="freeze" />
<animate id="anR2" xlink:href="#r2" attributeName="y" begin="anR1.end+0.25s" dur="0.5s" from="140" to="100" repeatCount="1" fill="freeze" />
<animate id="anR3" xlink:href="#r3" attributeName="y" begin="anR2.end+0.25s" dur="0.5s" from="140" to="60" repeatCount="1" fill="freeze" />
</svg>
<script src="index.js"></script>
</body>
</html>

CSS animate while dynamically changing translation

I made an SVG bee that needs to fly. I'm successfully using JavaScript to dynamically change the variables --tranX and --tranY in the CSS #bee1 (for changing its location).
Those variables are passed to the 100% {} keyframe in CSS. However, the animation is not working.
Note: I've already successfully got the bee to move by just applying the transform, but then the bee would just hop from location to location without animation.
CSS for the bee:
#bee1 {
-webkit-animation: beeMove 500ms ease-in-out infinite alternate-reverse both;
animation: beeMove 500ms ease-in-out infinite alternate-reverse both;
--tranX: 0;
--tranY: 0;
}
#-webkit-keyframes beeMove {
0% {
-webkit-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
}
100% {
-webkit-transform: translateX(var(--tranX)) translateY(var(--tranY));
transform: translateX(var(--tranX)) translateY(var(--tranY));
}
}
JavaScript for moving the bee (called every second):
for
(let bee of bees) {
bee.style.setProperty('--tranX', Math.random() * 340 + "px");
bee.style.setProperty('--tranY', Math.random() * 257 + "px");
}
https://jsfiddle.net/facechomp/3dbv15u6/26/
As per my comment, the CSS variables tranX and tranY are scoped to the #bee1 selector, and therefore the values are actually not accessible to the animation definition. If you simply want the bee to fly all over the place randomly without going back to its original position, you can update your code to this:
const _locationsInterval = 500; // ms
And for the CSS:
#bee1 {
transform: translateX(var(--tranX)) translateY(var(--tranY));
--tranX: 0;
--tranY: 0;
background: red;
transition: all 500ms ease-in-out;
}
const _wingsInterval = 500; // ms
const _locationsInterval = 500; // ms
var frontWings = document.getElementsByClassName('front-wing');
var backWings = document.getElementsByClassName('back-wing');
var bees = document.getElementsByClassName('bee');
///////////////////////////////////////////////////////////////////
// update all bees' wings every _wingsInterval ms
///////////////////////////////////////////////////////////////////
setInterval(function() {
var rotFront = -Math.round(Math.random() * 10 + 5);
for (let wing of frontWings) {
wing.style.setProperty('--rotFront', rotFront + "deg");
}
var rotBack = -Math.round(Math.random() * 20 + 2);
for (let wing of backWings) {
wing.style.setProperty('--rotBack', rotBack + "deg");
}
}, _wingsInterval);
///////////////////////////////////////////////////////////////////
// update all bees' locations every _locationsInterval ms
///////////////////////////////////////////////////////////////////
setInterval(function() {
for (let bee of bees) {
bee.style.setProperty('--tranX', Math.random() * 340 + "px");
bee.style.setProperty('--tranY', Math.random() * 257 + "px");
}
}, _locationsInterval);
body {
background-color: black;
}
.image-contain {
display: block;
margin: auto;
width: 800px;
}
.front-wing {
-webkit-animation: flapWingFront 60ms ease-in-out infinite alternate-reverse both;
animation: flapWingFront 60ms ease-in-out infinite alternate-reverse both;
--tranX: -52%;
--tranY: -26%;
--rotFront: 0;
position: absolute;
}
#-webkit-keyframes flapWingFront {
0% {
-webkit-transform: rotate(0) translateX(var(--tranX)) translateY(var(--tranY));
transform: rotate(0) translateX(var(--tranX)) translateY(var(--tranY));
}
100% {
-webkit-transform: rotate(var(--rotFront)) translateX(var(--tranX)) translateY(var(--tranY));
transform: rotate(var(--rotFront)) translateX(var(--tranX)) translateY(var(--tranY));
}
}
.back-wing {
-webkit-animation: flapWingBack 40ms ease-in-out infinite alternate-reverse both;
animation: flapWingBack 40ms ease-in-out infinite alternate-reverse both;
--btranX: -54%;
--btranY: -15%;
--rotBack: 0;
position: absolute;
}
#-webkit-keyframes flapWingBack {
0% {
-webkit-transform: rotate(0) translateX(var(--btranX)) translateY(var(--btranY));
transform: rotate(0) translateX(var(--btranX)) translateY(var(--btranY));
}
100% {
-webkit-transform: rotate(var(--rotBack)) translateX(var(--btranX)) translateY(var(--btranY));
transform: rotate(var(--rotBack)) translateX(--var(--btranX)) translateY(var(--btranY));
}
}
#bee1 {
transform: translateX(var(--tranX)) translateY(var(--tranY));
--tranX: 0;
--tranY: 0;
background: red;
transition: all 500ms ease-in-out;
}
<div class="image-contain">
<svg id="bee1" class="bee" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 340 275" width="75" height="50">
<defs>
<linearGradient id="a">
<stop offset="0" stop-color="#c5c5c7"/>
<stop offset="1" stop-color="#c5c5c7" stop-opacity="0"/>
</linearGradient>
<path d="M453.56 309.74c-11.86-45.92-22.57-71.57-55.36-100.67-21.86-19.41-40.14-15.15-54.82 12.76.16 1.03.93 6.18 2.32 15.46" id="d"/>
<path d="M453.52 309.46c-78.71-25.57-114.71-49.86-107.99-72.87" id="b"/>
<path d="M329.87 244.41c10.67.51 18.19-1.54 20.5-13.36 9.08-46.7-15.06-50.63-24.91-52.94-9.86-2.31-32.31-8.05-41.92-1.55-6.41 4.34-9.41 9.32-8.99 14.94 1.11 4.69 1.8 7.61 2.08 8.78.38 1.62 1.01 3.16 1.87 4.56.33.54-.81-1.33-.69-1.12 1.55 2.53 2.63 5.33 3.17 8.26 1.64 8.8 3.98 14.55 7.02 17.25 19.13 16.95 35.93 14.91 41.87 15.18z" id="e"/>
<path d="M236.72 232.73l5.12 4.79-6.97 15.88 13.4-14.87-12.88-11.34-7.85 17.15z" id="f"/>
<path d="M262.3 156.27c-.45 1.33-1.37 4.11-1.83 5.45a1.22 1.22 0 0 1-1.61.76c-3.15-1.2-11.39-4.37-14.53-5.58a1.358 1.358 0 0 1-.8-1.7c.44-1.33 1.37-4.11 1.81-5.44.22-.67.96-1.02 1.62-.77l14.53 5.58c.68.26 1.04 1.01.81 1.7z" id="g"/>
<path d="M259.43 179.58c-.91.41-2.58 1.16-3.5 1.55a1 1 0 0 1-1.37-.62c-.91-2.8-3.25-10.14-4.16-12.95-.19-.62.1-1.28.69-1.54.92-.41 2.59-1.15 3.5-1.56.56-.24 1.2.04 1.38.62.91 2.81 3.25 10.16 4.16 12.96.19.61-.11 1.28-.7 1.54z" id="h"/>
<path d="M254.44 164.19c-.36 1.07-1.09 3.28-1.45 4.35-.18.53-.77.81-1.29.6-2.51-.96-9.08-3.48-11.58-4.44-.55-.21-.83-.8-.64-1.35.35-1.07 1.09-3.29 1.44-4.34.18-.54.77-.82 1.3-.62 2.5.97 9.07 3.48 11.58 4.46.54.19.82.79.64 1.34z" id="i"/>
<path d="M237.5 238.35c-10.09-8.2-9.08-28.86 2.26-46.12 11.32-17.26 28.73-24.61 38.81-16.42 10.09 8.2 9.08 28.87-2.25 46.12-11.34 17.26-28.73 24.61-38.82 16.42z" id="j"/>
<path d="M268.55 175.57c-1.13.51-3.24 1.44-4.38 1.95-.69.3-1.5-.05-1.73-.78-1.13-3.52-4.08-12.72-5.2-16.26-.25-.76.12-1.6.87-1.92 1.13-.51 3.24-1.45 4.38-1.95.69-.31 1.5.05 1.73.78 1.13 3.52 4.08 12.73 5.2 16.25.25.77-.13 1.6-.87 1.93z" id="k"/>
<path d="M247.35 234.76c-5.23-4-2.62-18.27 5.81-31.88 8.44-13.59 19.53-21.4 24.75-17.4 5.24 3.98 2.63 18.26-5.81 31.86-8.43 13.61-19.52 21.4-24.75 17.42z" id="l"/>
<path d="M248.97 218.74c-1.11-.9 2.26-8.12 7.51-16.1 5.25-7.98 10.41-13.73 11.51-12.83 1.12.9-2.25 8.11-7.5 16.09s-10.41 13.74-11.52 12.84z" id="m"/>
<linearGradient xlink:href="#a" id="n" x1="308.975" y1="187.42" x2="498.657" y2="182.332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.09084 0 0 1 -28.066 14)"/>
<linearGradient xlink:href="#a" id="c" x1="308.975" y1="187.42" x2="498.657" y2="182.332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.72767 -.38085 .34914 .66708 10.105 193.084)"/>
</defs>
<g transform="translate(-177.91 -74.04)">
<use xlink:href="#b" width="100%" height="100%" fill="#eaad22"/>
<use xlink:href="#b" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<path class="back-wing" d="M300.374 200.434s116.837-96.705 117.927-71.09c1.09 25.615-6.342 42.957-111.889 75.617z" fill="url(#c)" transform="translate(-177.91 -88.04)"/>
<g transform="translate(-177.91 -88.04)">
<g transform="translate(0 14)">
<use xlink:href="#d" width="100%" height="100%" fill="#eaad22"/>
<use xlink:href="#d" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#e" width="100%" height="100%" fill="#ead822"/>
<use xlink:href="#e" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#f" width="100%" height="100%" fill="#ead822"/>
<use xlink:href="#f" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#g" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#g" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#h" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#h" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#i" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#i" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#j" width="100%" height="100%" fill="#ead822"/>
<use xlink:href="#j" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#k" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#k" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#l" width="100%" height="100%" fill="#3e3904"/>
<use xlink:href="#l" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#m" width="100%" height="100%" fill="#fff"/>
<use xlink:href="#m" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<path d="M336.576 240.154c4.009-.5-.136 5 1.328 6.432 1.4 1.37 9.97.116 7.93 2.627-2.134 2.628-10.78 3.916-15.078 6.175-4.108 2.158-8.267 7.628-12.097 8.105-4.008.5.137-5-1.328-6.432-1.4-1.37-9.97-.115-7.93-2.626 2.134-2.628 10.78-3.917 15.079-6.175 4.107-2.159 8.266-7.628 12.096-8.106z" fill="#463207"/>
<path d="M343.13 288.255c-2.381 5.955-6.17-4.324-9.066-3.485-2.768.803-7.628 13.69-9.247 8.793-1.695-5.125 3.178-18.145 3.57-25.956.375-7.465-3.366-17.74-1.09-23.43 2.382-5.956 6.17 4.324 9.066 3.484 2.768-.802 7.628-13.69 9.247-8.793 1.695 5.125-3.177 18.145-3.57 25.957-.375 7.464 3.366 17.74 1.09 23.43z" fill="#463207"/>
<ellipse cx="332.615" cy="297.798" rx="7.196" ry="21.188" fill="#463207"/>
<path d="M341.673 329.106c.457 2.686-2.767-2.585-3.492-2.412-.693.166.387 6.002-1.092 3.506-1.548-2.612-2.65-8.512-4.092-12.255-1.377-3.576-4.586-8.84-5.023-11.408-.457-2.686 2.768 2.585 3.493 2.412.693-.166-.387-6.002 1.092-3.506 1.548 2.612 2.65 8.512 4.091 12.254 1.378 3.577 4.587 8.842 5.023 11.409z" fill="#463207"/>
<ellipse cx="351.115" cy="128.439" rx="8.237" ry="25.267" transform="matrix(.91978 .39243 -.35584 .93455 0 0)" fill="#463207"/>
<path d="M254.936 313.666c-1.91-.697 1.976-11.42 2.96-16.422.984-5 .702-12.594 3.596-16.898 2.893-4.304 4.709 1.01 6.618 1.707 1.91.697 7.09-2.064 6.107 2.937-.984 5.001-6.686 10.41-9.58 14.715-2.893 4.304-7.791 14.658-9.701 13.961z" fill="#463207"/>
<path d="M237.744 319.857c-2.685.462 2.58-2.772 2.405-3.497-.166-.693-6.001.398-3.508-1.086 2.61-1.553 8.507-2.665 12.248-4.114 3.574-1.384 8.832-4.603 11.398-5.044 2.686-.462-2.58 2.772-2.405 3.497.167.693 6.002-.398 3.508 1.086-2.609 1.552-8.506 2.665-12.247 4.114-3.574 1.384-8.833 4.602-11.399 5.044zM288.076 232.159c-4.008-.5.137 5-1.328 6.432-1.399 1.369-9.97.115-7.93 2.626 2.134 2.628 10.78 3.916 15.079 6.175 4.107 2.159 8.266 7.628 12.097 8.106 4.008.5-.137-5 1.327-6.433 1.4-1.369 9.97-.115 7.93-2.626-2.134-2.628-10.78-3.916-15.078-6.175-4.108-2.158-8.267-7.628-12.097-8.105zM363.99 244.882c3.917.986-1.938 4.61-1.092 6.477.809 1.783 9.252 3.717 6.442 5.32-2.941 1.676-11.467-.254-16.292.295-4.61.525-10.467 4.118-14.21 3.176-3.918-.986 1.937-4.61 1.09-6.477-.808-1.783-9.251-3.717-6.44-5.32 2.94-1.676 11.466.254 16.29-.295 4.611-.525 10.468-4.118 14.212-3.176z" fill="#463207"/>
<path d="M370.502 303.896c-2.736 7.294-7.087-5.296-10.415-4.268-3.18.983-8.761 16.767-10.622 10.77-1.947-6.277 3.65-22.224 4.101-31.792.43-9.143-3.866-21.727-1.252-28.697 2.736-7.294 7.087 5.296 10.415 4.268 3.18-.983 8.761-16.767 10.622-10.77 1.947 6.277-3.65 22.224-4.101 31.792-.43 9.143 3.866 21.727 1.252 28.697z" fill="#463207"/>
<ellipse cx="238.882" cy="419.961" rx="7.196" ry="21.188" transform="rotate(-19.343)" fill="#463207"/>
<path d="M383.416 343.67c1.321 2.383-3.467-1.522-4.094-1.119-.599.386 2.353 5.536.13 3.67-2.325-1.952-5.319-7.153-7.919-10.207-2.484-2.919-7.256-6.823-8.518-9.1-1.32-2.384 3.467 1.521 4.094 1.118.6-.386-2.353-5.535-.13-3.67 2.325 1.952 5.319 7.154 7.919 10.208 2.485 2.918 7.256 6.823 8.518 9.1z" fill="#463207"/>
<path d="M415.769 310.79l-13.793-6.396s7.362-1.287 18.773-11.637c11.41-10.35 9.612-31.539 9.612-31.539s5.235 7.62 6.815 11.805c1.58 4.187-2.141 18.253-6.19 23.1-5.438 5.887-8.08 10.368-15.217 14.668zM388.927 298.598l-16.93-9.215s10.423-1.573 26.58-14.218c16.155-12.646 13.608-38.533 13.608-38.533s7.813 8.509 9.85 12.224c2.236 5.115-3.232 24.5-8.964 30.422-7.7 7.193-14.04 14.066-24.144 19.32z" fill="#2d2d2d"/>
</g>
<path class="front-wing" d="M308.975 201.42s197.045-41.837 182.552-11.024c-14.493 30.812-33.92 46.643-178.235 20.07z" fill="url(#n)" transform="translate(-177.91 -88.04)"/>
</svg>
</div>
However, if you want your bee to fly to a random position and back to its starting position, you might need a little more JS wizardry. What you need is basically to set 2 timers, one that transitions the bee to a randomly generated position and another back to coordinates of 0,0:
let iteration = 0;
setInterval(function() {
for (let bee of bees) {
const tranX = iteration % 2 ? 0 : Math.random() * 340;
const tranY = iteration % 2 ? 0 : Math.random() * 257;
bee.style.setProperty('--tranX', tranX + "px");
bee.style.setProperty('--tranY', tranY + "px");
iteration++;
}
}, _locationsInterval);
For this to work, your _locationsInterval must be the same duration as the transition-duration set on the bee.
The code above basically keeps track of the iteration used: if it is even-numbered, go back to original coordinates. If it is odd-numbered, go to a randomly-generated coordinates. This will create the effect of the bee going back and forth.
const _wingsInterval = 500; // ms
const _locationsInterval = 500; // ms
var frontWings = document.getElementsByClassName('front-wing');
var backWings = document.getElementsByClassName('back-wing');
var bees = document.getElementsByClassName('bee');
///////////////////////////////////////////////////////////////////
// update all bees' wings every _wingsInterval ms
///////////////////////////////////////////////////////////////////
setInterval(function() {
var rotFront = -Math.round(Math.random() * 10 + 5);
for (let wing of frontWings) {
wing.style.setProperty('--rotFront', rotFront + "deg");
}
var rotBack = -Math.round(Math.random() * 20 + 2);
for (let wing of backWings) {
wing.style.setProperty('--rotBack', rotBack + "deg");
}
}, _wingsInterval);
///////////////////////////////////////////////////////////////////
// update all bees' locations every _locationsInterval ms
///////////////////////////////////////////////////////////////////
let iteration = 0;
setInterval(function() {
for (let bee of bees) {
const tranX = iteration % 2 ? 0 : Math.random() * 340;
const tranY = iteration % 2 ? 0 : Math.random() * 257;
bee.style.setProperty('--tranX', tranX + "px");
bee.style.setProperty('--tranY', tranY + "px");
iteration++;
}
}, _locationsInterval);
body {
background-color: black;
}
.image-contain {
display: block;
margin: auto;
width: 800px;
}
.front-wing {
-webkit-animation: flapWingFront 60ms ease-in-out infinite alternate-reverse both;
animation: flapWingFront 60ms ease-in-out infinite alternate-reverse both;
--tranX: -52%;
--tranY: -26%;
--rotFront: 0;
position: absolute;
}
#-webkit-keyframes flapWingFront {
0% {
-webkit-transform: rotate(0) translateX(var(--tranX)) translateY(var(--tranY));
transform: rotate(0) translateX(var(--tranX)) translateY(var(--tranY));
}
100% {
-webkit-transform: rotate(var(--rotFront)) translateX(var(--tranX)) translateY(var(--tranY));
transform: rotate(var(--rotFront)) translateX(var(--tranX)) translateY(var(--tranY));
}
}
.back-wing {
-webkit-animation: flapWingBack 40ms ease-in-out infinite alternate-reverse both;
animation: flapWingBack 40ms ease-in-out infinite alternate-reverse both;
--btranX: -54%;
--btranY: -15%;
--rotBack: 0;
position: absolute;
}
#-webkit-keyframes flapWingBack {
0% {
-webkit-transform: rotate(0) translateX(var(--btranX)) translateY(var(--btranY));
transform: rotate(0) translateX(var(--btranX)) translateY(var(--btranY));
}
100% {
-webkit-transform: rotate(var(--rotBack)) translateX(var(--btranX)) translateY(var(--btranY));
transform: rotate(var(--rotBack)) translateX(--var(--btranX)) translateY(var(--btranY));
}
}
#bee1 {
transform: translateX(var(--tranX)) translateY(var(--tranY));
--tranX: 0;
--tranY: 0;
background: red;
transition: all 500ms ease-in-out;
}
<div class="image-contain">
<svg id="bee1" class="bee" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 340 275" width="75" height="50">
<defs>
<linearGradient id="a">
<stop offset="0" stop-color="#c5c5c7"/>
<stop offset="1" stop-color="#c5c5c7" stop-opacity="0"/>
</linearGradient>
<path d="M453.56 309.74c-11.86-45.92-22.57-71.57-55.36-100.67-21.86-19.41-40.14-15.15-54.82 12.76.16 1.03.93 6.18 2.32 15.46" id="d"/>
<path d="M453.52 309.46c-78.71-25.57-114.71-49.86-107.99-72.87" id="b"/>
<path d="M329.87 244.41c10.67.51 18.19-1.54 20.5-13.36 9.08-46.7-15.06-50.63-24.91-52.94-9.86-2.31-32.31-8.05-41.92-1.55-6.41 4.34-9.41 9.32-8.99 14.94 1.11 4.69 1.8 7.61 2.08 8.78.38 1.62 1.01 3.16 1.87 4.56.33.54-.81-1.33-.69-1.12 1.55 2.53 2.63 5.33 3.17 8.26 1.64 8.8 3.98 14.55 7.02 17.25 19.13 16.95 35.93 14.91 41.87 15.18z" id="e"/>
<path d="M236.72 232.73l5.12 4.79-6.97 15.88 13.4-14.87-12.88-11.34-7.85 17.15z" id="f"/>
<path d="M262.3 156.27c-.45 1.33-1.37 4.11-1.83 5.45a1.22 1.22 0 0 1-1.61.76c-3.15-1.2-11.39-4.37-14.53-5.58a1.358 1.358 0 0 1-.8-1.7c.44-1.33 1.37-4.11 1.81-5.44.22-.67.96-1.02 1.62-.77l14.53 5.58c.68.26 1.04 1.01.81 1.7z" id="g"/>
<path d="M259.43 179.58c-.91.41-2.58 1.16-3.5 1.55a1 1 0 0 1-1.37-.62c-.91-2.8-3.25-10.14-4.16-12.95-.19-.62.1-1.28.69-1.54.92-.41 2.59-1.15 3.5-1.56.56-.24 1.2.04 1.38.62.91 2.81 3.25 10.16 4.16 12.96.19.61-.11 1.28-.7 1.54z" id="h"/>
<path d="M254.44 164.19c-.36 1.07-1.09 3.28-1.45 4.35-.18.53-.77.81-1.29.6-2.51-.96-9.08-3.48-11.58-4.44-.55-.21-.83-.8-.64-1.35.35-1.07 1.09-3.29 1.44-4.34.18-.54.77-.82 1.3-.62 2.5.97 9.07 3.48 11.58 4.46.54.19.82.79.64 1.34z" id="i"/>
<path d="M237.5 238.35c-10.09-8.2-9.08-28.86 2.26-46.12 11.32-17.26 28.73-24.61 38.81-16.42 10.09 8.2 9.08 28.87-2.25 46.12-11.34 17.26-28.73 24.61-38.82 16.42z" id="j"/>
<path d="M268.55 175.57c-1.13.51-3.24 1.44-4.38 1.95-.69.3-1.5-.05-1.73-.78-1.13-3.52-4.08-12.72-5.2-16.26-.25-.76.12-1.6.87-1.92 1.13-.51 3.24-1.45 4.38-1.95.69-.31 1.5.05 1.73.78 1.13 3.52 4.08 12.73 5.2 16.25.25.77-.13 1.6-.87 1.93z" id="k"/>
<path d="M247.35 234.76c-5.23-4-2.62-18.27 5.81-31.88 8.44-13.59 19.53-21.4 24.75-17.4 5.24 3.98 2.63 18.26-5.81 31.86-8.43 13.61-19.52 21.4-24.75 17.42z" id="l"/>
<path d="M248.97 218.74c-1.11-.9 2.26-8.12 7.51-16.1 5.25-7.98 10.41-13.73 11.51-12.83 1.12.9-2.25 8.11-7.5 16.09s-10.41 13.74-11.52 12.84z" id="m"/>
<linearGradient xlink:href="#a" id="n" x1="308.975" y1="187.42" x2="498.657" y2="182.332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.09084 0 0 1 -28.066 14)"/>
<linearGradient xlink:href="#a" id="c" x1="308.975" y1="187.42" x2="498.657" y2="182.332" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.72767 -.38085 .34914 .66708 10.105 193.084)"/>
</defs>
<g transform="translate(-177.91 -74.04)">
<use xlink:href="#b" width="100%" height="100%" fill="#eaad22"/>
<use xlink:href="#b" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<path class="back-wing" d="M300.374 200.434s116.837-96.705 117.927-71.09c1.09 25.615-6.342 42.957-111.889 75.617z" fill="url(#c)" transform="translate(-177.91 -88.04)"/>
<g transform="translate(-177.91 -88.04)">
<g transform="translate(0 14)">
<use xlink:href="#d" width="100%" height="100%" fill="#eaad22"/>
<use xlink:href="#d" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#e" width="100%" height="100%" fill="#ead822"/>
<use xlink:href="#e" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#f" width="100%" height="100%" fill="#ead822"/>
<use xlink:href="#f" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#g" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#g" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#h" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#h" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#i" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#i" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#j" width="100%" height="100%" fill="#ead822"/>
<use xlink:href="#j" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#k" width="100%" height="100%" fill="#383729"/>
<use xlink:href="#k" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#l" width="100%" height="100%" fill="#3e3904"/>
<use xlink:href="#l" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<g transform="translate(0 14)">
<use xlink:href="#m" width="100%" height="100%" fill="#fff"/>
<use xlink:href="#m" width="100%" height="100%" fill-opacity="0" stroke="#000" stroke-opacity="0"/>
</g>
<path d="M336.576 240.154c4.009-.5-.136 5 1.328 6.432 1.4 1.37 9.97.116 7.93 2.627-2.134 2.628-10.78 3.916-15.078 6.175-4.108 2.158-8.267 7.628-12.097 8.105-4.008.5.137-5-1.328-6.432-1.4-1.37-9.97-.115-7.93-2.626 2.134-2.628 10.78-3.917 15.079-6.175 4.107-2.159 8.266-7.628 12.096-8.106z" fill="#463207"/>
<path d="M343.13 288.255c-2.381 5.955-6.17-4.324-9.066-3.485-2.768.803-7.628 13.69-9.247 8.793-1.695-5.125 3.178-18.145 3.57-25.956.375-7.465-3.366-17.74-1.09-23.43 2.382-5.956 6.17 4.324 9.066 3.484 2.768-.802 7.628-13.69 9.247-8.793 1.695 5.125-3.177 18.145-3.57 25.957-.375 7.464 3.366 17.74 1.09 23.43z" fill="#463207"/>
<ellipse cx="332.615" cy="297.798" rx="7.196" ry="21.188" fill="#463207"/>
<path d="M341.673 329.106c.457 2.686-2.767-2.585-3.492-2.412-.693.166.387 6.002-1.092 3.506-1.548-2.612-2.65-8.512-4.092-12.255-1.377-3.576-4.586-8.84-5.023-11.408-.457-2.686 2.768 2.585 3.493 2.412.693-.166-.387-6.002 1.092-3.506 1.548 2.612 2.65 8.512 4.091 12.254 1.378 3.577 4.587 8.842 5.023 11.409z" fill="#463207"/>
<ellipse cx="351.115" cy="128.439" rx="8.237" ry="25.267" transform="matrix(.91978 .39243 -.35584 .93455 0 0)" fill="#463207"/>
<path d="M254.936 313.666c-1.91-.697 1.976-11.42 2.96-16.422.984-5 .702-12.594 3.596-16.898 2.893-4.304 4.709 1.01 6.618 1.707 1.91.697 7.09-2.064 6.107 2.937-.984 5.001-6.686 10.41-9.58 14.715-2.893 4.304-7.791 14.658-9.701 13.961z" fill="#463207"/>
<path d="M237.744 319.857c-2.685.462 2.58-2.772 2.405-3.497-.166-.693-6.001.398-3.508-1.086 2.61-1.553 8.507-2.665 12.248-4.114 3.574-1.384 8.832-4.603 11.398-5.044 2.686-.462-2.58 2.772-2.405 3.497.167.693 6.002-.398 3.508 1.086-2.609 1.552-8.506 2.665-12.247 4.114-3.574 1.384-8.833 4.602-11.399 5.044zM288.076 232.159c-4.008-.5.137 5-1.328 6.432-1.399 1.369-9.97.115-7.93 2.626 2.134 2.628 10.78 3.916 15.079 6.175 4.107 2.159 8.266 7.628 12.097 8.106 4.008.5-.137-5 1.327-6.433 1.4-1.369 9.97-.115 7.93-2.626-2.134-2.628-10.78-3.916-15.078-6.175-4.108-2.158-8.267-7.628-12.097-8.105zM363.99 244.882c3.917.986-1.938 4.61-1.092 6.477.809 1.783 9.252 3.717 6.442 5.32-2.941 1.676-11.467-.254-16.292.295-4.61.525-10.467 4.118-14.21 3.176-3.918-.986 1.937-4.61 1.09-6.477-.808-1.783-9.251-3.717-6.44-5.32 2.94-1.676 11.466.254 16.29-.295 4.611-.525 10.468-4.118 14.212-3.176z" fill="#463207"/>
<path d="M370.502 303.896c-2.736 7.294-7.087-5.296-10.415-4.268-3.18.983-8.761 16.767-10.622 10.77-1.947-6.277 3.65-22.224 4.101-31.792.43-9.143-3.866-21.727-1.252-28.697 2.736-7.294 7.087 5.296 10.415 4.268 3.18-.983 8.761-16.767 10.622-10.77 1.947 6.277-3.65 22.224-4.101 31.792-.43 9.143 3.866 21.727 1.252 28.697z" fill="#463207"/>
<ellipse cx="238.882" cy="419.961" rx="7.196" ry="21.188" transform="rotate(-19.343)" fill="#463207"/>
<path d="M383.416 343.67c1.321 2.383-3.467-1.522-4.094-1.119-.599.386 2.353 5.536.13 3.67-2.325-1.952-5.319-7.153-7.919-10.207-2.484-2.919-7.256-6.823-8.518-9.1-1.32-2.384 3.467 1.521 4.094 1.118.6-.386-2.353-5.535-.13-3.67 2.325 1.952 5.319 7.154 7.919 10.208 2.485 2.918 7.256 6.823 8.518 9.1z" fill="#463207"/>
<path d="M415.769 310.79l-13.793-6.396s7.362-1.287 18.773-11.637c11.41-10.35 9.612-31.539 9.612-31.539s5.235 7.62 6.815 11.805c1.58 4.187-2.141 18.253-6.19 23.1-5.438 5.887-8.08 10.368-15.217 14.668zM388.927 298.598l-16.93-9.215s10.423-1.573 26.58-14.218c16.155-12.646 13.608-38.533 13.608-38.533s7.813 8.509 9.85 12.224c2.236 5.115-3.232 24.5-8.964 30.422-7.7 7.193-14.04 14.066-24.144 19.32z" fill="#2d2d2d"/>
</g>
<path class="front-wing" d="M308.975 201.42s197.045-41.837 182.552-11.024c-14.493 30.812-33.92 46.643-178.235 20.07z" fill="url(#n)" transform="translate(-177.91 -88.04)"/>
</svg>
</div>

How do you center a <g> within a <svg> in D3.js?

I am trying to center a group that has a d3 tree inside of it. The svg is currently positioned perfectly across the browser and I am just trying to get the dynamically loaded tree to stay in the center of that svg element. All tree elements are within one group and have a zoom listener and have the ability to pan.
<svg width="1535" height="685" overflow-y="hidden" class="overlay">
<g transform="translate(742.5,342.5)scale(1)">
<g class="node" transform="translate(0,25)">
<circle class="nodeCircle" r="4.5" style="fill: rgb(255, 255, 255)</circle>
<text x="10" dy=".35em" class="nodeText" text-anchor="start" style="fill-opacity: 1;"></text>
<text x="10" dy="1.5em" class="nodeText" text-anchor="start"></text>
</g>
</g>
</svg>
i hope you understand the concept
first you draw svg with width: 1535 and hight :685
you want to make g element on middle of it
middle of it means half of width(1535/2) and half of height (685/2)
w:767.5 h:342.5
you draw g and transform it. good point but you must set transform to right place, that means on middle of svg to 742.5 and 342.5
so that means you need transform x,y) it more (25,0)
why you set it wrong
<g class="node" transform="translate(0,25)">
it must be
<g class="node" transform="translate(25,0)">
this is little example
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg{
border-style: solid;
border-color: red;
}
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
<svg width="200" height="100" overflow-y="hidden" class="overlay">
<g transform="translate(70,20)scale(1)">
<g class="node" transform="translate(30,30)">
<circle class="nodeCircle" r="10" style="fill: black"</circle>
<text x="10" dy=".35em" class="nodeText" text-anchor="start" style="fill-opacity: 1;"></text>
<text x="10" dy="1.5em" class="nodeText" text-anchor="start"></text>
</g>
</g>
</svg>
<svg width="200" height="100" overflow-y="hidden" class="overlay">
<g transform="translate(100,50)scale(1)">
<g class="node" transform="translate(0,0)">
<circle class="nodeCircle" r="10" style="fill: black"</circle>
<text x="10" dy=".35em" class="nodeText" text-anchor="start" style="fill-opacity: 1;"></text>
<text x="10" dy="1.5em" class="nodeText" text-anchor="start"></text>
</g>
</g>
</svg>
<br/>
<svg width="200" height="100" overflow-y="hidden" class="overlay">
<g transform="translate(200,50)scale(1)">
<g class="node" transform="translate(0,0)">
<circle class="nodeCircle" r="10" style="fill: black"</circle>
<text x="10" dy=".35em" class="nodeText" text-anchor="start" style="fill-opacity: 1;"></text>
<text x="10" dy="1.5em" class="nodeText" text-anchor="start"></text>
</g>
</g>
</svg>
<svg width="200" height="100" overflow-y="hidden" class="overlay">
<g transform="translate(100,10)scale(1)">
<g class="node" transform="translate(100,40)">
<circle class="nodeCircle" r="10" style="fill: black"</circle>
<text x="10" dy=".35em" class="nodeText" text-anchor="start" style="fill-opacity: 1;"></text>
<text x="10" dy="1.5em" class="nodeText" text-anchor="start"></text>
</g>
</g>
</svg>
</body>

animate line of svg based on user provided value

How should i animate the line of my svg vertically? I have a svg of thermometer. I want to move the needle of thermometer based on the user provided value but i could only show the svg. The initial value is 1 and the needle should be in 1 but it is in about -19, -18. I have also created a webpackbin to show what i have done
Here is the link
https://www.webpackbin.com/bins/-KhGUeUlftWQUNDSxMrC
The code below i have pasted is not complete as i have to remove path code because of body limit by SO.
const normalize = (value, maxValue) => {
const capacity = parseFloat(maxValue);
// needle ranges from 0 to 50 degrees
// It should not overflow
const nValue = (parseFloat(value) / capacity) * 50;
return Math.max(Math.min(nValue, 50), 0);
};
class HelloSvg extends React.Component {
constructor() {
super();
this.state = {value: '1'};
}
componentDidMount() {
const {value} = this.state;
this.animation.setAttribute('from', this.animation.getAttribute('to'));
this.animation.setAttribute('to', 50 - value);
this.animation.beginElement();
}
handleChange(event) {
this.setState({ value: event.target.value });
}
//shouldComponentUpdate() {
//return false;
//}
render() {
const {value} = this.state;
console.log(this.state.value);
return (
<div>
Hello from React
<input type="range" min='1' max='50' onChange={this.handleChange.bind(this)} />
Value is {this.state.value}
<svg width="100%" height="auto" viewBox="50 50 60 800" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient x1="-103.596615%" y1="53.6675027%" x2="174.725349%" y2="53.6675027%" id="linearGradient-1">
<stop stopColor="#000000" offset="0%"></stop>
<stop stopColor="#B6B6B6" offset="50%"></stop>
<stop stopColor="#FFFFFF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
<g id="thermometer">
<g id="callibrations" transform="translate(-3.099210, -1.008722)">
<rect id="rect4197" fill="#1ab394" x="0.46429" y="0.99612" width="227.30853" height="817.64752"></rect>
<path d="M113.15625,43.46875 C98.74432,43.49155 89.08034,59.50943 92.09455,72.90625 C92.30532,282.95724 91.65711,451.01733 92.46875,661.0625 C94.96609,678.28747 121.07484,684.93864 131.09375,670.5625 C140.06366,658.7571 134.72639,643.12281 136.1538,629.53125 C135.90071,426.03222 136.67745,264.52501 135.71875,61.03125 C133.78141,50.75755 123.6736,42.80162 113.15625,43.46875 Z" id="path4415" fill="url(#linearGradient-1)"></path>
<rect id="rect3857" fill="white" x="0.46429" y="0.99612" width="227.30853" height="817.64752"></rect>
<path d="M114.1186,51.45093 C121.88695,51.45093 128.14089,57.70487 128.14089,65.47322 L128.14089,698.52196 C128.14089,706.29031 121.88695,712.54425 114.1186,712.54425 C106.35025,712.54425 100.09631,706.29031 100.09631,698.52196 L100.09631,65.47322 C100.09631,57.70487 106.35025,51.45093 114.1186,51.45093 L114.1186,51.45093 Z" id="rect3048" fill="grey"></path>
<rect id="level" fill="blue" opacity="0.79" x="100.089208" y="500" width="28.0599995" height="200">
<animateTransform
attributeName="height"
to="30"
dur="300ms"
repeatCount="0"
fill="freeze"
ref={(animation) => { this.animation = animation; }}
/>
</rect>
<path d="M128.14089,65.47322 L128.14089,698.52196 C128.14089,706.29031 121.88695,712.54425 114.1186,712.54425 C106.35025,712.54425 100.09631,706.29031 100.09631,698.52196 L100.09631,65.47322 C100.09631,57.70487 106.35025,51.45093 114.1186,51.45093 C121.88695,51.45093 128.14089,57.70487 128.14089,65.47322 Z" id="path3887" fill="grey" opacity="0.454616855"></path>
<path d="M162.16938,727.645267 C162.16938,754.183009 140.65635,775.696112 114.118545,775.696112 C87.580845,775.696112 66.06771,754.183009 66.06771,727.645267 C66.06771,701.107514 87.580845,679.594421 114.118545,679.594421 C140.65635,679.594421 162.16938,701.107514 162.16938,727.645267 Z" id="path3046" fill="#056AAE"></path>
<path d="M162.16938,727.645267 C162.16938,754.183009 140.65635,775.696112 114.118545,775.696112 C87.580845,775.696112 66.06771,754.183009 66.06771,727.645267 C66.06771,701.107514 87.580845,679.594421 114.118545,679.594421 C140.65635,679.594421 162.16938,701.107514 162.16938,727.645267 Z" id="path3051" fill="red" opacity="0.47163122"></path>
</g>
<text id="Unit" fontFamily="ArialMT, Arial" fontSize="32" fontWeight="normal" fill="#0E0E0E">
<tspan x="94" y="32">°F</tspan>
</text>
<g id="callibtext" transform="translate(21.000000, 94.000000)" fontSize="24" fontFamily="ArialMT, Arial" fill="#0E0E0E" fontWeight="normal">
<text id="-30">
<tspan x="0" y="581">-30</tspan>
</text>
<text id="50">
<tspan x="8" y="22">50</tspan>
</text>
<text id="0">
<tspan x="21" y="371">0</tspan>
</text>
</g>
</g>
</g>
</svg>
</div>
);
}
}
export default HelloSvg;
The needle that i want to move is the rect in the code so i have tried to apply animation over there but i see no any effect.
Does the following working example help you at all?
var slider = document.getElementById("slider");
var anim = document.getElementById("anim");
slider.addEventListener("change", function(evt) {
var sliderValue = evt.target.value;
var currentTo = anim.getAttribute("to");
anim.setAttribute("from", currentTo);
anim.setAttribute("to", 400 - sliderValue);
anim.beginElement();
});
<svg width="100" height="400">
<line x1="50" y1="400" x2="50" y2="0" stroke="lightgrey" stroke-width="20"/>
<line x1="50" y1="400" x2="50" y2="400" stroke="red" stroke-width="20">
<animate id="anim"
attributeName="y2"
to="400"
dur="1s"
fill="freeze"/>
</line>
</svg>
<input id="slider" type="range" min="0" max="400" step="1" value="0"/>

paper-tooltip not showing up

I have the following code which seems like it should display a <paper-tooltip> when the chart is hovered over, but it does not. Hovering causes the <paper-tooltip> node in the DOM to update, but it doesn't show up. What am I doing wrong?
<svg id="svg_fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89" width="600" height="450">
<g>
<line opacity="1" x1="167.0000000000005" y1="225.00001160643953" x2="121.49166679382381" y2="220.40001302639112" style="stroke: #A9A9A9; stroke-width: 1"></line>
<g>
<defs>
<radialGradient id="radialGradient_0_fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89" cx="50%" cy="50%" fx="50%" fy="50%" r="50%" gradientUnits="userSpaceOnUse">
<stop offset="40%" stop-color="#DBDBDB"></stop>
<stop offset="100%" stop-color="#777777"></stop>
</radialGradient>
</defs>
<path id="pieWedge_0_fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89" class="pie-chart-wedge" fill="url(#radialGradient_0_fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89)" d="M300,225 L435,225 A135,135 0 1 1 434.99999999999795,224.99997643805509z"></path>
<paper-tooltip position="right" animation-delay="0.5" fittovisiblebounds="true" role="tooltip" tabindex="-1" class="x-scope paper-tooltip-0" style="left: 279.15px; top: 1841.22px;">
<div id="tooltip" class="style-scope paper-tooltip" hidden="">
Austin Office: 100.0
</div>
</paper-tooltip>
<rect opacity="1" fill="white" style="stroke: #A9A9A9; stroke-width: 1" x="92.98333358764705" y="213.5000129310237" width="57.016666412353516" height="13.800000190734863"></rect>
<text class="pie-label-fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89" opacity="1" x="94.98333358764705" y="225.0000130899694" font-size="11" textLength="53.016666412353516" lengthAdjust="spacingAndGlyphs">Austin Office</text>
</g>
<circle cx="300" cy="225" r="54" fill="white"></circle>
</g>
</svg>
I'm adding the tooltip using:
var paperTT = document.createElement("paper-tooltip");
paperTT.setAttribute("position", "right");
paperTT.setAttribute("animation-delay", "0.5");
paperTT.setAttribute("fitToVisibleBounds", "true");
paperTT.textContent = this.name + ": " + (this.fraction * 100).toFixed(1);
group.appendChild(paperTT);
The <paper-tooltip> should be outside the <svg>, and set <paper-tooltip>.for to the element ID of the hover target (presumably the pie wedge).
<paper-tooltip for="pieWedge">
Austin Office: 100.0
</paper-tooltip>
<svg>
...
<path id="pieWedge">...</path>
</svg>
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo'
});
});
<head>
<base href="https://polygit.org/polymer+1.7.1/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-tooltip/paper-tooltip.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<paper-tooltip for="pieWedge"
position="right"
animation-delay="0.5"
fittovisiblebounds
tabindex="-1"
style="left: 279.15px; top: 1841.22px;">
Austin Office: 100.0
</paper-tooltip>
<svg id="svg" width="600" height="450">
<g>
<line opacity="1" x1="167.0000000000005" y1="225.00001160643953" x2="121.49166679382381" y2="220.40001302639112"
style="stroke: #A9A9A9; stroke-width: 1"></line>
<g>
<defs>
<radialGradient id="radialGradient_0_fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89" cx="50%" cy="50%" fx="50%"
fy="50%" r="50%" gradientUnits="userSpaceOnUse">
<stop offset="40%" stop-color="#DBDBDB"></stop>
<stop offset="100%" stop-color="#777777"></stop>
</radialGradient>
</defs>
<path id="pieWedge" class="pie-chart-wedge"
fill="url(#radialGradient_0_fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89)"
d="M300,225 L435,225 A135,135 0 1 1 434.99999999999795,224.99997643805509z"></path>
<rect opacity="1" fill="white" style="stroke: #A9A9A9; stroke-width: 1" x="92.98333358764705"
y="213.5000129310237" width="57.016666412353516" height="13.800000190734863"></rect>
<text class="pie-label-fbff5dd2-1724-4f3d-a0b2-2fbe41d75e89" opacity="1" x="94.98333358764705"
y="225.0000130899694" font-size="11" textLength="53.016666412353516" lengthAdjust="spacingAndGlyphs">
Austin Office
</text>
</g>
<circle cx="300" cy="225" r="54" fill="white"></circle>
</g>
</svg>
</template>
</dom-module>
</body>
codepen

Categories