Synchronize button on two different html pages using javascript - javascript
I just want to know if there's a way that I can synchronize the map zoom button on two different html pages?
https://i.stack.imgur.com/nrFf9.png
I want to sync all the buttons in left and right map.
Here's the code for my Left and Right Map
LEFT
var scale = 1,
panning = false,
pointX = 0,
pointY = 0,
start = { x: 0, y: 0 },
zoom1 = document.getElementById("zoom1");
zoom2 = document.getElementById("zoom2");
function setTransform() {
zoom1.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
zoom2.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
}
function reset(){
event.preventDefault();
scale = 1;
pointX = 0;
pointY = 0;
start = { x: 0, y: 0 };
setTransform();
}
function zoomOut(){
document.getElementById("zoomout").click();
event.preventDefault();
var xs = (event.clientX - pointX) / scale,
ys = (event.clientY - pointY) / scale,
delta = (event.wheelDelta ? event.wheelDelta : -event.deltaY);
(delta > 0) ? (scale *= 1.04) : (scale /= 1.04);
setTransform();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LEFT</title>
<style>
#vatican g path {
-moz-transition-property: opacity;
-o-transition-property: opacity;
-webkit-transition-property: opacity;
transition-property: opacity;
-moz-transition-duration: 0.5s;
-o-transition-duration: 0.5s;
-webkit-transition-duration: 0.5s;
transition-duration: 0.5s;
-moz-transition-timing-function: ease;
-o-transition-timing-function: ease;
-webkit-transition-timing-function: ease;
transition-timing-function: ease;
stroke: gray;
stroke-width: 0.5px;
}
</style>
</head>
<body>
<div class="btn-zoom">
<div>
<button id="zoomout" onclick="zoomOut()">-</button>
</div>
<div>
<button onclick="reset()">R</button>
</div>
</div>
<div class="zoom_outer">
<div id="zoom1">
<svg id="vatican"
xmlns:mapsvg="http://mapsvg.com"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
height="100%"
width="100%"
viewBox="0 300 2000 2100"
preserveAspectRatio="none"
mapsvg:geoViewBox="116.927573 20.834769 126.606549 4.640292">
<g>
<path id="VA" title="Vatican City (Holy See)" class="land" d="M473.758,317.509L486.073,391.484L578.644,421.415L578.099,480.789L575.735,515.828L573.327,572.038L573.872,588.098L583.461,593.693L591.868,602.697L601.457,614.133L605.684,621.92L610.455,639.683L612,659.392L611.728,665.231L611.546,670.827L609.592,681.777L602.32,697.106L587.551,713.652L573.872,721.195L566.237,723.871L553.922,724.602L539.471,721.195L527.064,715.599L521.384,709.759L515.612,704.649L500.025,709.272L480.983,716.572L448.536,728.981L417.452,736.037L406.092,740.417L402.683,745.526L403.047,752.583L403.683,767.182L409.908,773.508L410.408,781.294L407.455,788.837L402.683,792L393.186,785.674L347.014,767.912L346.56,778.618L340.379,778.131L266.94,767.182L241.219,762.802L235.993,752.583L223.541,747.474L200.683,744.797L191.685,740.417L179.733,737.983L165.963,736.037L150.194,736.523L150.785,748.203L126.335,753.313L109.249,755.016L104.931,750.637L98.75,743.094L103.931,737.983L109.703,732.874L94.479,718.762L78.21,705.379L66.803,697.106L48.625,681.777L40.582,692.727L17.224,679.101L0,672.287L55.351,638.952L75.574,625.326L79.709,622.406L86.344,610.97L91.525,593.693L95.433,584.204L102.522,575.201L112.521,566.928L124.018,554.762L134.47,546.488L140.741,536.998L144.877,524.102L149.648,494.902L154.011,471.299L161.146,466.188L171.598,461.809L184.095,455.969L199.274,441.368L212.089,422.875L221.224,398.541L227.858,380.047L273.575,374.208L298.343,375.667L305.932,374.208L339.788,361.554L353.694,357.173L360.783,369.097L390.322,360.337L388.913,345.493L409,339.166z"/>
</g>
</svg>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
RIGHT
var scale = 1,
panning = false,
pointX = 0,
pointY = 0,
start = { x: 0, y: 0 },
zoom1 = document.getElementById("zoom1");
zoom2 = document.getElementById("zoom2");
function setTransform() {
zoom1.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
zoom2.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
}
function reset(){
event.preventDefault();
scale = 1;
pointX = 0;
pointY = 0;
start = { x: 0, y: 0 };
setTransform();
}
function zoomOut(){
document.getElementById("zoomout").click();
event.preventDefault();
var xs = (event.clientX - pointX) / scale,
ys = (event.clientY - pointY) / scale,
delta = (event.wheelDelta ? event.wheelDelta : -event.deltaY);
(delta > 0) ? (scale *= 1.04) : (scale /= 1.04);
setTransform();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RIGHT</title>
<style>
#vatican g path {
-moz-transition-property: opacity;
-o-transition-property: opacity;
-webkit-transition-property: opacity;
transition-property: opacity;
-moz-transition-duration: 0.5s;
-o-transition-duration: 0.5s;
-webkit-transition-duration: 0.5s;
transition-duration: 0.5s;
-moz-transition-timing-function: ease;
-o-transition-timing-function: ease;
-webkit-transition-timing-function: ease;
transition-timing-function: ease;
stroke: gray;
stroke-width: 0.5px;
}
</style>
</head>
<body>
<div class="btn-zoom">
<div>
<button id="zoomout" onclick="zoomOut()">-</button>
</div>
<div>
<button onclick="reset()">R</button>
</div>
</div>
<div class="zoom_outer">
<div id="zoom2">
<svg id="vatican"
xmlns:mapsvg="http://mapsvg.com"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
height="100%"
width="100%"
viewBox="0 300 2000 2100"
preserveAspectRatio="none"
mapsvg:geoViewBox="116.927573 20.834769 126.606549 4.640292">
<g>
<path id="VA" title="Vatican City (Holy See)" class="land" d="M473.758,317.509L486.073,391.484L578.644,421.415L578.099,480.789L575.735,515.828L573.327,572.038L573.872,588.098L583.461,593.693L591.868,602.697L601.457,614.133L605.684,621.92L610.455,639.683L612,659.392L611.728,665.231L611.546,670.827L609.592,681.777L602.32,697.106L587.551,713.652L573.872,721.195L566.237,723.871L553.922,724.602L539.471,721.195L527.064,715.599L521.384,709.759L515.612,704.649L500.025,709.272L480.983,716.572L448.536,728.981L417.452,736.037L406.092,740.417L402.683,745.526L403.047,752.583L403.683,767.182L409.908,773.508L410.408,781.294L407.455,788.837L402.683,792L393.186,785.674L347.014,767.912L346.56,778.618L340.379,778.131L266.94,767.182L241.219,762.802L235.993,752.583L223.541,747.474L200.683,744.797L191.685,740.417L179.733,737.983L165.963,736.037L150.194,736.523L150.785,748.203L126.335,753.313L109.249,755.016L104.931,750.637L98.75,743.094L103.931,737.983L109.703,732.874L94.479,718.762L78.21,705.379L66.803,697.106L48.625,681.777L40.582,692.727L17.224,679.101L0,672.287L55.351,638.952L75.574,625.326L79.709,622.406L86.344,610.97L91.525,593.693L95.433,584.204L102.522,575.201L112.521,566.928L124.018,554.762L134.47,546.488L140.741,536.998L144.877,524.102L149.648,494.902L154.011,471.299L161.146,466.188L171.598,461.809L184.095,455.969L199.274,441.368L212.089,422.875L221.224,398.541L227.858,380.047L273.575,374.208L298.343,375.667L305.932,374.208L339.788,361.554L353.694,357.173L360.783,369.097L390.322,360.337L388.913,345.493L409,339.166z"/>
</g>
</svg>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
I am calling the same JS file for the 2 pages.
This will help me alot if you guys can help me with this. Thank you!
Irrespective you use the same JS file for the two different page, both pages will load the JS as a new version for their own. so, even if you do some script change on one page, it wont reflect on the other until you refresh it.
Instead you can use Database to handle this as one of the solution.
Lets say on default both zoom was set at 8, and zoom button has a class "zoom_btn", and data-zoom='8'
Create a DB table called zoom_change with a column zoom_value with default one row with value of '8'.
Create a page in PHP or any other backend you use to update zoom_value in zoom_change table
Create another page in PHP or any other backend you use to fetch zootem_value in zoom_change table
using JQuery :
on the common JS page :
Script #1 to Record zoom changes into DB:
$(".zoom_btn").on("click", function() {
var zoom_value = parseInt($(this).attr("data-zoom"))+1;
$.post('zoom_value_update.php',
{
value : zoom_value
}, function () {
// $(this).attr("data-zoom",zoom_value);
// Do something with the zoom value ----
});
});
Script #2 to update zoom_value from DB to data attribute :
function() {
setInterval(() => {
$.post('zoom_value_fetch.php',
{ }, function (result) {
$(".zoom_btn").attr("data-zoom",result);
// Do something with the zoom value ----
});
}, 5000);
}();
Please note that this one of the method i know of. Not the only one. Please consider other answers as well.
Related
Need help scaling and rotating an image in a viewport
I have the code in this JSFidle - https://jsfiddle.net/pmi2018/smewua0k/211/ Javascript $('#rotate').click(function(e) { updateImage(90, 0) console.log("rotation"); }); $('#zoom-in').click(function() { updateImage(0, 0.1); console.log("Zoomed in"); }); $('#zoom-out').click(function() { updateImage(0, -0.1); console.log("Zoomed out"); }); var zoomLevel = 1; var rotation = 0; var updateImage = function(angle, zoom) { zoomLevel += zoom; var img_scale = ' scale(' + zoomLevel + ') '; rotation += angle; if (rotation == 360) { rotation = 0; } var str_rotation = ' rotate(' + rotation + 'deg) '; console.log("rotation=" + str_rotation + " scale=" + img_scale); var img = document.getElementById('sam'); img.style.transform = img_scale + str_rotation //if (angle == 0) { // img.style.transformOrigin = '0 0'; // img.style.transform = img_scale; // } // else { // img.style.transformOrigin = 'center center'; // img.style.transform = str_rotation; // } } HTML <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button> <div id=imageblock> <img id="sam" src="http://placekitten.com/g/250/250" /> </div> <div> <a id="rotate" href="#">Rotate 90 degrees</a> </div> CSS #imageblock { width: 300px; height: 300px; border: 1px solid #000000; overflow: auto; display: block; } #sam { transform-origin: center, center; } The problem is I need the have the origin be upper left corner when I scale the image to keep the scaled image in the box; but the origin has to be center, center when I rotate the image to keep the image in the box. However the CSS articles I have read say when rotating and scaling an image, they have to be done together. I tried applying the rotation and scale separately so I could set the origin correctly (the commented out code), but only the first transform fires, and not the second. How can I rotate and scale the image in the #imagebox? Thanks! Mark
The reason why it "goes together" is because the transform property can only have one origin. So if you apply multiple transformations on a single object, they will all use the same origin. An easy solution would be to put the image in a div. Then, use the zoom on the div, and the rotate on the image for exemple so that both can have different origins. $('#rotate').click(function(e) { updateImage(90, 0) }); $('#zoom-in').click(function() { updateImage(0, 0.1); }); $('#zoom-out').click(function() { updateImage(0, -0.1); }); var zoomLevel = 1; var rotation = 0; var updateImage = function(angle, zoom) { zoomLevel += zoom; var img_scale = ' scale(' + zoomLevel + ') '; rotation += angle; if (rotation == 360) { rotation = 0; } var str_rotation = ' rotate(' + rotation + 'deg) '; // Here I modified the syntax just a bit, to use JQuery methods instead of pur Javascript. I hope you are ok with it // I modify the image rotate property, and then the div scale property $('#sam').css('transform',str_rotation) $('#zoom').css('transform', img_scale); } #imageblock { width: 300px; height: 300px; border: 1px solid #000000; overflow: auto; display: block; overflow: hidden; /* To hide the scrollbar when you zoom in */ } #zoom { transform:scale(1); transform-origin:top left; } #sam { transform: rotate(0deg) transform-origin: center center; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button> <div id=imageblock> <div id="zoom"> <!-- I added this div --> <img id="sam" src="http://placekitten.com/g/250/250" /> </div> </div> <div> <a id="rotate" href="#">Rotate 90 degrees</a> </div> Also, please note that there is no coma in transform-origin: center center;. Ask them if you have any questions. I hope it helped !
Transitions on javascript
I'm using this code to make zoom to a container, but if I use transition CSS on the container but doesn't work. Can anybody help me plz? var zoom = 1; document.getElementById('mas').addEventListener('click', function(e) { zoom += 0.1; resize(); }); document.getElementById('menos').addEventListener('click', function(e) { if (zoom > 0.2) { zoom -= 0.1; resize(); } }); function resize() { document.getElementById('contenedor').style.zoom = zoom; document.getElementById('value').innerHTML = zoom.toFixed(2) + '%'; } #contenedor { width: 300px; height: 200px; background: red; transition: 1s ease } <!DOCTYPE html> <html lang="en"> <body> <div id="contenedor"></div> <input type="button" value="Aumentar" id="mas" /> <input type="button" value="Disminuir" id="menos" /> <span id="value">x1</span> </body> </html>
To be honest I have never used the property zoom before, but it is showing a rare behavior with transition. So, I changed your code a little bit. Take a look. var zoom = 1; var container = document.getElementById("contenedor"); var containerHeight = container.offsetHeight; var containerWidth = container.offsetWidth; document.getElementById("mas").addEventListener("click", function(e) { zoom += .10; resize(); }); document.getElementById("menos").addEventListener("click", function(e) { if (zoom > 0.2) { zoom -= .10; resize(); } }); function resize() { container.style.height = String(containerHeight * zoom + "px"); container.style.width = String(containerWidth * zoom + "px"); document.getElementById("value").innerHTML = zoom.toFixed(2) + "%"; } #contenedor { width: 300px; height: 200px; background: red; transition: 1s ease; transform-origin: 0 0; transform: scale(1.0); } <!DOCTYPE html> <html lang="en"> <body> <div id="contenedor"></div> <input type="button" value="Aumentar" id="mas"> <input type="button" value="Disminuir" id="menos"> <span id="value">x1</span> </body> </html>
TweenMax reuse function for all element ID's
I'm using a Tweenmax script I found to create a ripple effect on some buttons. I have HTML as follows: <label for="slider_1" id="js-ripple-btn" class="button styl-material"> Home <svg class="ripple-obj" id="js-ripple"><use height="100" width="100" xlink:href="#ripply-scott" class="js-ripple"></use></svg> </label> <label for="slider_2" id="js-ripple-btn2" class="button styl-material"> Catalogue <svg class="ripple-obj" id="js-ripple2"><use height="100" width="100" xlink:href="#ripply-scott" class="js-ripple2"></use></svg> </label> ... I'm a bit lost on how to have the script listen for any of the ID's that have the js-ripple class rather than specify just one. The following code only targets the first element ID but I need it to target whichever element ID is clicked. var ripplyScott = (function() { var circle = document.getElementById('js-ripple'), ripple = document.querySelectorAll('.js-ripple'); function rippleAnimation(event, timing) { var tl = new TimelineMax(); x = event.offsetX, y = event.offsetY, w = event.target.offsetWidth, h = event.target.offsetHeight, offsetX = Math.abs( (w / 2) - x ), offsetY = Math.abs( (h / 2) - y ), deltaX = (w / 2) + offsetX, deltaY = (h / 2) + offsetY, scale_ratio = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); console.log('x is:' + x); console.log('y is:' + y); console.log('offsetX is:' + offsetX); console.log('offsetY is:' + offsetY); console.log('deltaX is:' + deltaX); console.log('deltaY is:' + deltaY); console.log('width is:' + w); console.log('height is:' + h); console.log('scale ratio is:' + scale_ratio); tl.fromTo(ripple, timing, { x: x, y: y, transformOrigin: '50% 50%', scale: 0, opacity: 1, ease: Linear.easeIn },{ scale: scale_ratio, opacity: 0 }); return tl; } return { init: function(target, timing) { var button = document.getElementById(target); button.addEventListener('click', function(event) { rippleAnimation.call(this, event, timing); }); } }; })(); ripplyScott.init('js-ripple-btn', 0.75); I can obviously duplicate the script changing the element ID to each button but that means, I'm sure, ridiculous repeating of code when there must be a way of targeting all with a slight modification. Help/guidance is appreciated thanks! ** Update ** Here is a fiddle so you can sort of see my issue. Thanks.
I have made an attempt on solving your problem based on my understanding. Take a look at this jsFiddle. Here is the explanation: IDs should always be unique to elements. Your js-ripple-btn ID has been changed to class. We needed a way to get a reference to the button that has been clicked so that we can play respective animation. We solved that by using an index variable from buttons passing them all the way down to your animations. Snippet: var ripplyScott = (function() { var circle = document.getElementById('js-ripple'); var ripple = document.querySelectorAll('.js-ripple'); function rippleAnimation(event, timing, index) { var tl = new TimelineMax(); var x = event.offsetX; var y = event.offsetY; var w = event.target.offsetWidth; var h = event.target.offsetHeight; var offsetX = Math.abs((w / 2) - x); var offsetY = Math.abs((h / 2) - y); var deltaX = (w / 2) + offsetX; var deltaY = (h / 2) + offsetY; var scale_ratio = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); tl.fromTo(ripple[index], timing, { x: x, y: y, transformOrigin: '50% 50%', scale: 0, opacity: 1, ease: Linear.easeIn }, { scale: scale_ratio, opacity: 0 }); return tl; } return { init: function(target, timing) { var buttons = document.getElementsByClassName(target); var numButtons = buttons.length; for (var i = 0; i < numButtons; i += 1) { (function(index) { buttons[index].addEventListener('click', function(event) { rippleAnimation.call(this, event, timing, index); }); }(i)); } } }; })(); ripplyScott.init('js-ripple-btn', 0.75); label { border-radius: 0; display: block; background: #ccc; margin: 5px 0; cursor: pointer; color: #333; width: 200px; padding: 0; font-size: 15px; border: 1px solid #333; text-align: center; height: 70px; line-height: 70px; overflow: hidden; } .button { padding: 1.5em 3em; margin: 0; position: relative; display: inline-block; overflow: hidden; } .button.styl-material { transition: 200ms background cubic-bezier(0.4, 0, 0.2, 1); } .button.styl-material:hover, .button.styl-material:focus { outline: none; } .ripple-obj, .ripple-obj2 { height: 100%; pointer-events: none; position: absolute; top: 0; left: 0; z-index: 0; width: 100%; fill: #AD1457; } .ripple-obj use, .ripple-obj2 use { opacity: 0; } <script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/TweenMax.min.js"></script> <label class="button styl-material js-ripple-btn" for="slider_1">Home <svg class="ripple-obj" id="js-ripple"> <use class="js-ripple" height="100" width="100" xlink:href="#ripply-scott"> </use> </svg> </label> <label class="button styl-material js-ripple-btn" for="slider_2">Catalogue <svg class="ripple-obj" id="js-ripple2"> <use class="js-ripple" height="100" width="100" xlink:href="#ripply-scott"> </use> </svg> </label> <!-- Firefox Button Fix --> <div aria-hidden="true" style="height: 0; width: 0; position: absolute; visibility: hidden;"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> <radialgradient id="gradient"> <stop offset="0" stop-color="#0868BB"></stop> <stop offset="0.25" stop-color="#0075D8"></stop> <stop offset="0.35" stop-color="#0868BB"></stop> <stop offset="0.5" stop-color="#0075D8"></stop> <stop offset="0.6" stop-color="#0868BB"></stop> <stop offset="0.85" stop-color="#0075D8"></stop> <stop offset="1" stop-color="#0868BB"></stop> </radialgradient> </defs> <symbol id="ripply-scott" viewbox="0 0 100 100"> <circle cx="1" cy="1" fill="url(#gradient)" id="ripple-shape" r="1"></circle> </symbol> </svg> </div> <!-- / FF button fix --> Hope this helps.
You can add an onClick to your buttons to grab the id of them and then run ripplyScott.init passing in the id of the clicked button to target. <label class="button styl-material" for="slider_1" id="js-ripple-btn" onClick="myClick(this.id)"> var elementId; function myClick(id) { elementId = id; ripplyScott.init(id, 0.75); } return { init: function(target, timing) { rippleAnimation.call(target, event, timing); } }; And declare your ripple var as so: var ripple = document.getElementById(elementId).childNodes[1].childNodes[1]; Here's a working fiddle
style conflict between javascript and css
I have built a little element 3d rotator for infinite rotating in either direction on the X or Y axis. However I am running into what I think is a css style conflict. #face2 has a css property that rotates it -180deg . however its not being implemented by the browser. is this a css conflict perhaps? you can see the code and the effect in this code pen : //declaring global variables window.RotXFrontVal = 0; // by how much to rotate the X value of the front face window.RotXBackVal = -180; // by how much to rotate the X value of the back face window.RotYFrontVal = 0; // by how much to rotate the Y value of the front face window.RotYBackVal = 180; // by how much to rotate the Y value of the back face $(document).ready(function() { //$('#face2').css({'transform': 'rotateX(-180deg)'}, 0); //$('#face2').animate({'transform', 'rotateX(-180deg)'}, 0); //$('#face2').animate({'transform': 'rotateX(-180deg)'}, 0); var MyDivSlider = function() { // Here will come the Div Slider by Scroll var scl = $.now(); // Take a time stamp to prevent function from triggering too often $(document).on('DOMMouseScroll mousewheel', function MyScroll(event) { if (($.now() - scl) > 500) { if (event.originalEvent.detail > 0 || event.originalEvent.wheelDelta < 0) { //Scroll Down window.RotXFrontVal = window.RotXFrontVal - 180; window.RotXBackVal = window.RotXBackVal - 180; console.log("Down. Front: " + RotXFrontVal + "and" + RotXBackVal + " is Back"); } //Up Scroll else { window.RotXFrontVal = window.RotXFrontVal + 180; window.RotXBackVal = window.RotXBackVal + 180; console.log("Up. Front: " + RotXFrontVal + "and" + RotXBackVal + " is Back"); } $('#face2').css('transform', 'rotateX(' + RotXBackVal + 'deg)'); $('#face1').css('transform', 'rotateX(' + RotXFrontVal + 'deg)'); console.log('rotateX(' + RotXFrontVal + ')') console.log('rotateX(' + RotXBackVal + ')') scl = $.now(); } }); }(); }); body { height:100%; overflow:hidden;} #card { height:300px; width: 300px; display: block; position: relative; transform-style: preserve-3d; transition: all 1.5s linear; perspective: 1000px; } #face1 { display: block; position: absolute; width: 100%; height: 100%; background: red; backface-visibility: hidden; transition: transform 1.5s; z-index: 2; } #face2 { display: block; position: absolute; width: 100%; height: 100%; background: blue; backface-visibility: hidden; transition: transform 1.5s; z-index: 1; transform: rotateX ( -180deg ); } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <body> <div id="card"> <div id = "face1">Use the mouse scroll button to rotate me</div> <div id = "face2">Use the mouse scroll button to rotate me</div> </div> </body>
It's because of the whitespace inbetween rotateX and ( try: transform: rotateX( -180deg );
Using CSS transitions to animate dynamic SVG Attributes
I'm trying to animate the attributes of various SVG shapes using JavaScript and CSS transitions. For example: HTML: <svg width="400" height="400"> <circle id="circle" cx="200" cy="200" r="15" stroke="none" fill="blue" /> <rect id="rect" x="100" y="100" height="30" width="30" stroke="none" fill="red" /> </svg> <button id="button">Animate</button> JavaScript: document.getElementById("button").addEventListener("click", function () { var circle = document.getElementById("circle"); var cx = 50 + Math.round(Math.random() * 300); var cy = 50 + Math.round(Math.random() * 300); // using 'setAttribute' circle.setAttribute("cx", cx); circle.setAttribute("cy", cy); var rect = document.getElementById("rect"); var x = 50 + Math.round(Math.random() * 300); var y = 50 + Math.round(Math.random() * 300); // using 'setAttributeNS' rect.setAttributeNS(null, "x", x); rect.setAttributeNS(null, "y", y); }, false); CSS: circle, rect { -webkit-transition: all 0.7s ease-in-out; -moz-transition: all 0.7s ease-in-out; transition: all 0.7s ease-in-out; } Here's a complete JSFiddle: http://jsfiddle.net/kkhvzyjq/ In Chrome, this works beautifully. However, in Safari and Firefox, while the new attributes are applied (the shapes move), there's no transition/animation. Is there a way to do this that works in these browsers?
Safari and Firefox do not transition changes in the position attributes. The CSS property transform works better for that: http://jsfiddle.net/kkhvzyjq/7/ document.getElementById("button").addEventListener("click", function() { var circle = document.getElementById("circle"); var cx = 50 + Math.round(Math.random() * 300); var cy = 50 + Math.round(Math.random() * 300); circle.style.transform = "translate(" + cx + "px," + cy + "px)"; var rect = document.getElementById("rect"); var x = 50 + Math.round(Math.random() * 300); var y = 50 + Math.round(Math.random() * 300); rect.style.transform = "translate(" + x + "px," + y + "px)"; }, false); circle, rect { -webkit-transition: all 0.7s ease-in-out; -moz-transition: all 0.7s ease-in-out; transition: all 0.7s ease-in-out; } <svg width="400" height="400"> <circle id="circle" r="10" stroke="none" fill="blue" style="transform:translate(200px,200px);" /> <rect id="rect" height="10" width="10" stroke="none" fill="red" style="transform:translate(100px,100px);" /> </svg> <button id="button">Animate</button>