我创建了一个网站,通过添加/删除css类来动画图像网格。每个css类都应用了transition duration
(简写),并且以这样的方式添加类,以便为图像提供起始位置,然后(在假setTimeout
)结束位置之后,这样他们就可以激活这个位置了。
Here is the hosted page (www.willynolan.com/test)
奇怪的是,这适用于除firefox之外的所有浏览器,即使firefox应该在所有其他浏览器之前支持css transition
和transform
属性。实际上,autoprefixer甚至不会建议为这些属性添加前缀。更好的是,即使在较旧版本的firefox上进行测试时,转换在firefox中的工作时间约为1/2。
由于代码有点复杂,我没有张贴小提琴,而是托管了整个页面。你可以通过在Firefox和其他浏览器中看到差异来看。我测试了jsfiddle中的transform
和transition
属性,它们确实在firefox中工作,所以我不知道它是什么。我将在这里发布HTML / CSS / JS代码。 Chrome或Firefox的开发人员工具中均未显示任何错误。
请注意,因为我测试了相同代码的前缀版本并查看了浏览器支持,我知道添加-moz-
前缀不起作用。我已经试过了。
CSS
/********************************************** Base Styles *****************************************************/
html, body {
margin: 0 auto;
padding: 0;
width: 100%;
height: 100%;
}
body {
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
margin: 0;
}
header {
line-height: 1.5em;
text-transform: uppercase;
margin-top: 1.5em;
}
h1 {
width: 100%;
display: inline-block;
font-size: 1.2em;
font-weight: 100;
padding-left: .25em;
}
h1 span {
color: #999;
}
#menuIcon {
display: inline-block;
position: absolute;
z-index: 16;
top: 0;
left: 0;
width: 2.5em;
height: 2.5em;
margin: .2em .2em 0 .4em;
background: black url('../media/media/nav.png') center;
}
nav ul {
display: none;
width: 0;
}
nav:hover ul {
display: block;
position: absolute;
background-color: black;
left: 0;
margin: .2em;
top: 2.5em;
width: 10em;
z-index: 15;
}
nav ul.clicked {
display: block;
position: absolute;
background-color: black;
left: 0;
margin: .2em;
top: 2.5em;
width: 10em;
z-index: 15;
}
nav ul.none {
display: none;
width: 0;
}
nav li {
width: 100%;
padding: .6em 0;
margin: 0;
}
a {
text-decoration: none;
}
a:link, a:visited {
color: white;
}
nav li a:hover, nav li a:focus {
color: #777;
-webkit-transition: color 500ms ease-out;
transition: color 500ms ease-out;
}
nav li a:active {
color: #444;
}
#mainContainer {
display: block;
width: 85%;
margin: 0 auto;
}
div.imageHolder {
position: relative;
width: 100%;
padding-bottom: 56%;
margin-bottom: .1em;
overflow: hidden;
}
img {
width: 100%;
position: absolute;
left: 0;
}
img.loaded {
display: none;
}
/********************************************** Next Size Up Styles ****************************************************************/
@media (min-width: 31.25em) {
html {
max-width: 1400px;
}
h1 {
font-size: 2.5em;
}
}
@media (min-width: 35em) {
[data-icon]:before {
display: none;
}
footer {
font-size: .8em;
}
footer ul li small, footer ul li small, .footerItem {
display: inline;
}
}
@media (min-width: 38.5em) {
div.imageHolder {
max-width: 512px;
padding-bottom: 288px;
}
div.imageHolder {
margin: 0 auto .1em auto;
}
img {
max-width: 512px;
padding-bottom: 288px;
}
}
@media (min-width: 48em) {
footer {
font-size: 1.2em;
}
}
@media (min-width: 60em){
header {
position: relative;
height: 5.5em;
width: 85%;
margin: 0 auto;
border-bottom: 2px solid black;
}
h1 {
position: relative;
top: 1.3em;
text-align: left;
}
#menuIcon {
display: none;
}
nav:hover ul, nav ul {
width: 100%;
display: inline;
position: absolute;
top: 3em;
left: 0;
margin: 0;
text-align: right;
background: transparent;
list-style: none;
}
nav ul li {
display: inline;
padding: 0 .6em;
font-size: 1.2em;
line-height: 3em;
}
a:link, a:visited {
color: black;
}
#mainContainer {
margin: 2.5em auto 0 auto;
padding-left: 1%;
}
div.imageHolder {
float: left;
position: relative;
width: 33%;
padding-bottom: 18.7%;
margin-bottom: .1em;
margin-right: .1em;
}
div.imageContent {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
overflow: hidden;
}
div img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-transform: translateZ(0);
-moz-backface-visibility: hidden;
margin: 0;
}
footer {
font-size: 1.2em;
}
}
#overlay {
position:fixed;
top:0;
left:0;
height:100%;
width:100%;
background: rgba(0, 0, 0, .65);
}
#largeImage {
max-width: 75%;
height: auto;
-webkit-perspective: 1000;
perspective: 1000;
-webkit-backface-visibility:hidden;
backface-visibility:hidden;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-animation: goBig 700ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
animation: goBig 700ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
}
/********************************** Transitions *******************************************/
.opacityStart {
visibility: hidden;
opacity: 0;
}
.opacityEnd {
opacity: 1;
-webkit-transition: opacity 1s;
transition: opacity 1s;
}
.scaleXStart {
visibility: hidden;
-webkit-transform:scaleX(0);
-ms-transform:scaleX(0);
transform:scaleX(0);
}
.scaleXEnd {
-webkit-transform: scaleX(1);
-ms-transform: scaleX(1);
transform: scaleX(1);
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
}
.scaleYStart {
visibility: hidden;
-webkit-transform:scaleY(0);
-ms-transform:scaleY(0);
transform:scaleY(0);
}
.scaleYEnd {
-webkit-transform: scaleY(1);
-ms-transform: scaleY(1);
transform: scaleY(1);
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
}
.translateRightStart {
visibility: hidden;
-webkit-transform: translateX(100%);
-ms-transform: translateX(100%);
transform: translateX(100%);
}
.translateRightEnd {
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
}
.translateLeftStart {
visibility: hidden;
-webkit-transform: translateX(-100%);
-ms-transform: translateX(-100%);
transform: translateX(-100%);
}
.translateLeftEnd {
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
}
.translateYUpStart {
visibility: hidden;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%)
}
.translateYUpEnd {
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-webkit-transition: -webkit-transform 1s;
transition: transform 1s
}
.translateYDownStart {
visibility: hidden;
-webkit-transform: translateY(100%);
-ms-transform: translateY(100%);
transform: translateY(100%)
}
.translateYDownEnd {
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-webkit-transition: -webkit-transform 1s;
transition: transform 1s
}
/********************************** Animations *******************************************/
@-webkit-keyframes goBig {
0% {
opacity: 0;
-webkit-transform: scale3d(0, 0, 0);
}
100% {
opacity: 1;
-webkit-transform: scale3d(1, 1, 1);
}
}
@keyframes goBig {
0% {
opacity: 0;
-webkit-transform: scale3d(0, 0, 0);
transform: scale3d(0, 0, 0);
}
100% {
opacity: 1;
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
}
的Javascript
function shuffle(array) {
var currentIndex = array.length,
temporaryValue,
randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
var turnObjToArray = function(obj) {
return [].map.call(obj, function(element) {
return element;
});
};
/* Images */
var imageArray = [
{
source: 'media/media/test.jpg'
},
{
source: 'media/media/test.jpg'
},
{
source: 'media/media/test.jpg'
},
{
source: 'media/media/test.jpg'
}
];
shuffle(imageArray);
var imageElements = [];
/* Turn animating divs into random array for later manipulation */
var startHolders = shuffle(turnObjToArray(document.querySelectorAll('.imageContent')));
/* Load first images */
function startLoader(index) {
var image = new Image();
image.onload = function() {
startHolders[index].appendChild(this);
imageElements.push(this);
};
image.src = imageArray[index]['source'];
}
(function(){
for(var i = 0, j = startHolders.length; i < j; i += 1) {
startLoader(i);
}
})();
function imageLoader(i) {
var image = new Image();
image.onload = function() {
imageElements.push(this);
};
image.src = imageArray[i]['source'];
}
window.addEventListener('load', function () {
/* Preload images */
(function preload(){
for(var i = startHolders.length; i < imageArray.length; i += 1) {
imageLoader(i);
}
})();
/* Start animations */
var animation = (function () {
var a = {};
a.divIndex = 0;
a.imgIndex = startHolders.length;
a.animIndex = 0;
a.run = function() {
if(!document.querySelector('#overlay')){
imageElements[a.imgIndex].className = animations[a.animIndex]['start'];
startHolders[a.divIndex].appendChild(imageElements[a.imgIndex]);
setTimeout(function(){
imageElements[a.imgIndex].className = animations[a.animIndex]['end'];
if(++a.divIndex === startHolders.length) a.divIndex = 0;
if(++a.imgIndex === imageElements.length) a.imgIndex = 0;
if(++a.animIndex === animations.length) a.animIndex = 0;
}, 0);
}
};
return a;
})();
setInterval(animation.run, 1500);
/* Create Overlay */
document.addEventListener('click', function(e) {
if(e.target.tagName == 'IMG' && e.target.id != 'largeImage') {
var overlay = document.createElement('div');
overlay.id = 'overlay';
document.body.appendChild(overlay);
overlay.addEventListener('click', function(){
this.remove();
},false);
var overImage = new Image();
overImage.addEventListener('load', function(){
this.id = 'largeImage';
if(this.height > window.innerHeight) {
this.ratio = window.innerHeight / this.height;
this.height = this.height * this.ratio;
this.width = this.width * this.ratio;
}
if(this.width > window.innerWidth) {
this.ratio = window.innerWidth / this.width;
this.height = this.height * this.ratio;
this.width = this.width * this.ratio;
}
setTimeout(function(){
var a = document.getElementById('largeImage');
centerImage(a);
}, 30);
centerImage(this);
overlay.appendChild(this);
}, false);
if(window.innerWidth > 513){
overImage.src = e.target.src.substr(0, e.target.src.length - 7) + '1024.jpg';
} else {
overImage.src = e.target.src;
}
}
function centerImage(theImage) {
var myDifX = (window.innerWidth - theImage.width) / 2;
var myDifY = (window.innerHeight - theImage.height) / 2;
theImage.style.top = myDifY + 'px';
theImage.style.left = myDifX + 'px';
return theImage;
}
window.addEventListener('resize', function(){
if(document.querySelector('#largeImage')){
centerImage(document.querySelector('#largeImage'));
}
},false);
},false);
var menuIcon = document.querySelector('#menuIcon');
var clicked = false;
menuIcon.addEventListener('touchstart', function(){
clicked = !clicked;
if(clicked) {
document.querySelector('nav ul').className = 'clicked';
} else {
document.querySelector('nav ul').className = 'none';
}
}, false);
});
/* Animations */
var opacity = {
start: 'opacityStart',
end: 'opacityEnd'
};
var scaleX = {
start: 'scaleXStart',
end: 'scaleXEnd'
};
var scaleY = {
start: 'scaleYStart',
end: 'scaleYEnd'
};
var translateRight = {
start: 'translateRightStart',
end: 'translateRightEnd'
};
var translateLeft = {
start: 'translateLeftStart',
end: 'translateLeftEnd'
};
var translateUp = {
start: 'translateYUpStart',
end: 'translateYUpEnd'
};
var translateDown = {
start: 'translateYDownStart',
end: 'translateYDownEnd'
};
var animations = [
opacity,
scaleX,
scaleY,
translateRight,
translateLeft,
translateUp,
translateDown
];
shuffle(animations);
HTML
<!doctype html>
<html>
<head lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width initial-scale=1 maximum-scale=1">
<link rel="stylesheet" href="css/style.css">
<!--[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<article id="mainContainer">
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
<div class="imageHolder"><div class="imageContent"></div></div>
</article>
<script src="scripts/main.js" type="text/javascript"></script>
</body>
</html>