/**
* tiltfx.js
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2015, Codrops
* http://www.codrops.com
*/
;
(function(window) {
'use strict';
/**
* **************************************************************************
* utils
* **************************************************************************
*/
// from https://gist.github.com/desandro/1866474
var lastTime = 0;
var prefixes = 'webkit moz ms o'.split(' ');
// get unprefixed rAF and cAF, if present
var requestAnimationFrame = window.requestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame;
// loop through vendor prefixes and get prefixed rAF and cAF
var prefix;
for (var i = 0; i < prefixes.length; i++) {
if (requestAnimationFrame && cancelAnimationFrame) {
break;
}
prefix = prefixes[i];
requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame'];
cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] ||
window[prefix + 'CancelRequestAnimationFrame'];
}
// fallback to setTimeout and clearTimeout if either request/cancel is not supported
if (!requestAnimationFrame || !cancelAnimationFrame) {
requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
cancelAnimationFrame = function(id) {
window.clearTimeout(id);
};
}
function extend(a, b) {
for (var key in b) {
if (b.hasOwnProperty(key)) {
a[key] = b[key];
}
}
return a;
}
// from http://www.quirksmode.org/js/events_properties.html#position
function getMousePos(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return {
x: posx,
y: posy
}
}
// from http://www.sberry.me/articles/javascript-event-throttling-debouncing
function throttle(fn, delay) {
var allowSample = true;
return function(e) {
if (allowSample) {
allowSample = false;
setTimeout(function() {
allowSample = true;
}, delay);
fn(e);
}
};
}
/***************************************************************************/
/**
* TiltFx fn
*/
function TiltFx(el, options) {
this.el = el;
this.options = extend({}, this.options);
extend(this.options, options);
this._init();
this._initEvents();
}
/**
* TiltFx options.
*/
TiltFx.prototype.options = {
// number of extra image elements (div with background-image) to add to the DOM - min:1, max:5 (for a higher number, it's recommended to remove the transitions of .tilt__front in the stylesheet.
extraImgs: 2,
// the opacity value for all the image elements.
opacity: 0.7,
// by default the first layer does not move.
bgfixed: true,
// image element's movement configuration
movement: {
perspective: 1000, // perspective value
translateX: -10, // a relative movement of -10px to 10px on the x-axis (setting a negative value reverses the direction)
translateY: -10, // a relative movement of -10px to 10px on the y-axis
translateZ: 20, // a relative movement of -20px to 20px on the z-axis (perspective value must be set). Also, this specific translation is done when the mouse moves vertically.
rotateX: 2, // a relative rotation of -2deg to 2deg on the x-axis (perspective value must be set)
rotateY: 2, // a relative rotation of -2deg to 2deg on the y-axis (perspective value must be set)
rotateZ: 0 // z-axis rotation; by default there's no rotation on the z-axis (perspective value must be set)
}
}
/**
* Initialize: build the necessary structure for the image elements and replace it with the HTML img element.
*/
TiltFx.prototype._init = function() {
this.tiltWrapper = document.createElement('div');
this.tiltWrapper.className = 'tilt';
// main image element.
this.tiltImgBack = document.createElement('div');
this.tiltImgBack.className = 'tilt__back';
this.tiltImgBack.style.backgroundImage = 'url(' + this.el.src + ')';
this.tiltWrapper.appendChild(this.tiltImgBack);
// image elements limit.
if (this.options.extraImgs < 1) {
this.options.extraImgs = 1;
} else if (this.options.extraImgs > 5) {
this.options.extraImgs = 5;
}
if (!this.options.movement.perspective) {
this.options.movement.perspective = 0;
}
// add the extra image elements.
this.imgElems = [];
for (var i = 0; i < this.options.extraImgs; ++i) {
var el = document.createElement('div');
el.className = 'tilt__front';
el.style.backgroundImage = 'url(' + this.el.src + ')';
el.style.opacity = this.options.opacity;
this.tiltWrapper.appendChild(el);
this.imgElems.push(el);
}
if (!this.options.bgfixed) {
this.imgElems.push(this.tiltImgBack);
++this.options.extraImgs;
}
// add it to the DOM and remove original img element.
this.el.parentNode.insertBefore(this.tiltWrapper, this.el);
this.el.parentNode.removeChild(this.el);
// tiltWrapper properties: width/height/left/top
this.view = {
width: this.tiltWrapper.offsetWidth,
height: this.tiltWrapper.offsetHeight
};
};
/**
* Initialize the events on the main wrapper.
*/
TiltFx.prototype._initEvents = function() {
var self = this,
moveOpts = self.options.movement;
// mousemove event..
this.tiltWrapper.addEventListener('mousemove', function(ev) {
requestAnimationFrame(function() {
// mouse position relative to the document.
var mousepos = getMousePos(ev),
// document scrolls.
docScrolls = {
left: document.body.scrollLeft + document.documentElement.scrollLeft,
top: document.body.scrollTop + document.documentElement.scrollTop
},
bounds = self.tiltWrapper.getBoundingClientRect(),
// mouse position relative to the main element (tiltWrapper).
relmousepos = {
x: mousepos.x - bounds.left - docScrolls.left,
y: mousepos.y - bounds.top - docScrolls.top
};
// configure the movement for each image element.
for (var i = 0, len = self.imgElems.length; i < len; ++i) {
var el = self.imgElems[i],
rotX = moveOpts.rotateX ? 2 * ((i + 1) * moveOpts.rotateX / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.rotateX / self.options.extraImgs) : 0,
rotY = moveOpts.rotateY ? 2 * ((i + 1) * moveOpts.rotateY / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.rotateY / self.options.extraImgs) : 0,
rotZ = moveOpts.rotateZ ? 2 * ((i + 1) * moveOpts.rotateZ / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.rotateZ / self.options.extraImgs) : 0,
transX = moveOpts.translateX ? 2 * ((i + 1) * moveOpts.translateX / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.translateX / self.options.extraImgs) : 0,
transY = moveOpts.translateY ? 2 * ((i + 1) * moveOpts.translateY / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.translateY / self.options.extraImgs) : 0,
transZ = moveOpts.translateZ ? 2 * ((i + 1) * moveOpts.translateZ / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.translateZ / self.options.extraImgs) : 0;
el.style.WebkitTransform = 'perspective(' + moveOpts.perspective + 'px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(1,0,0,' + rotX + 'deg) rotate3d(0,1,0,' + rotY + 'deg) rotate3d(0,0,1,' + rotZ + 'deg)';
el.style.transform = 'perspective(' + moveOpts.perspective + 'px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(1,0,0,' + rotX + 'deg) rotate3d(0,1,0,' + rotY + 'deg) rotate3d(0,0,1,' + rotZ + 'deg)';
}
});
});
// reset all when mouse leaves the main wrapper.
this.tiltWrapper.addEventListener('mouseleave', function(ev) {
setTimeout(function() {
for (var i = 0, len = self.imgElems.length; i < len; ++i) {
var el = self.imgElems[i];
el.style.WebkitTransform = 'perspective(' + moveOpts.perspective + 'px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
el.style.transform = 'perspective(' + moveOpts.perspective + 'px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
}
}, 60);
});
// window resize
window.addEventListener('resize', throttle(function(ev) {
// recalculate tiltWrapper properties: width/height/left/top
self.view = {
width: self.tiltWrapper.offsetWidth,
height: self.tiltWrapper.offsetHeight
};
}, 50));
};
function init() {
// search for imgs with the class "tilt-effect"
[].slice.call(document.querySelectorAll('img.tilt-effect')).forEach(function(img) {
new TiltFx(img, JSON.parse(img.getAttribute('data-tilt-options')));
});
}
init();
window.TiltFx = TiltFx;
})(window);
.tilt {
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
margin: 0 auto;
}
.tilt__back {
position: relative;
}
.tilt__front {
position: absolute;
top: 0;
left: 0;
}
.tilt__back,
.tilt__front {
width: 100%;
height: 100%;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: cover;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
<div class="megawrapper">
<div class="w-section home-page" style="transform: translateX(0px) translateY(0px);">
<div class="home_logo" style="pointer-events:none;"></div>
<div class="home_centralarea" data-ix="home-darkfield" style="opacity: 1; transition: opacity 500ms;">
<div class="home_parallaxpic_wrapper">
<div class="home_parallaxpic" data-ix="home-parallaxpic" style="opacity: 0.4; transition: opacity 1000ms;">
<img class="hero__img tilt-effect" data-tilt-options='{ "extraImgs":3, "bgfixed":false, "opacity" : 0.5, "movement": { "perspective" : 1200, "translateX" : -5, "translateY" : -5, "rotateX" : -5, "rotateY" : -5 } }' src="<?php echo get_template_directory_uri(); ?>/images/road.jpeg"
/>
</div>
</div>
</div>
</div>
</div>
我想复制本网站的HTML结构(www.danielspatzek.com/)。但我不能让我的div正确地居中。该网站有两个主要的div,.home-page包含完全拉伸的背景图像和.tilt,它在背景图像上注入tiltfx效果。 div .tilt有一个按比例缩小的高度/宽度,因为它的父div已经在其上施加了60px的填充.home-page
我复制了HTML结构但是当我在.home-page中应用60px填充时,所有div都被向右/向下推,并且不再居中。
原始网站html是:
<div class="megawrapper">
<div class="w-section home-page" style="transform: translateX(0px) translateY(0px);">
<div class="home_logo" style="pointer-events:none;"></div>
<div class="home_centralarea" data-ix="home-darkfield" style="opacity: 1; transition: opacity 500ms;">
<div class="home_parallaxpic_wrapper">
<div class="home_parallaxpic" data-ix="home-parallaxpic" style="opacity: 0.4; transition: opacity 1000ms;">
<img class="hero__img tilt-effect" data-tilt-options='{ "extraImgs":3, "bgfixed":false, "opacity" : 0.5, "movement": { "perspective" : 1200, "translateX" : -5, "translateY" : -5, "rotateX" : -5, "rotateY" : -5 } }' src="<?php echo get_template_directory_uri(); ?>/images/road.jpeg" />
</div>
</div>
</div>
</div>
</div>
javascript文件tiltfx.js删除.tilt-effect并将其替换为.tilt,因此HTML为:
<div class="megawrapper">
<div class="w-section home-page" style="transform: translateX(0px) translateY(0px);">
<div class="home_logo" style="pointer-events:none;"></div>
<div class="home_centralarea" data-ix="home-darkfield" style="opacity: 1; transition: opacity 0ms;">
<div class="home_parallaxpic_wrapper">
<div class="home_parallaxpic" data-ix="home-parallaxpic" style="opacity: 0.4; transition: opacity 0ms;">
<div class="tilt"><div class="tilt__back" style="background-image: url("http://www.danielspatzek.com/themes/Theme/images/bg_home_street.jpg"); transform: perspective(1200px) translate3d(0.787151px, -0.0129973px, 0px) rotate3d(1, 0, 0, -0.0129973deg) rotate3d(0, 1, 0, 0.787151deg) rotate3d(0, 0, 1, 0deg);"></div>
</div>
</div>
</div>
</div>
我的娱乐HTML和CSS看起来像这样:
<div class="megawrapper">
<div class="home-page" style="transform: translateX(0px) translateY(0px);">
<img class="tilt-effect" data-tilt-options='{ "extraImgs":3, "bgfixed":false, "opacity" : 0.5, "movement": { "perspective" : 1200, "translateX" : -5, "translateY" : -5, "rotateX" : -5, "rotateY" : -5 } }' src="<?php echo get_template_directory_uri(); ?>/images/road.jpeg" />
</div>
.megawrapper {
position: absolute;
overflow-x: hidden;
overflow-y: hidden;
width: 100%;
height: 100%;
}
.home-page {
position: absolute;
z-index: 0;
width: 100%;
height: 100%;
background-color: #3c3c3e;
background-image: url(images/road.jpeg);
background-position: 50% 50%;
background-size: cover;
background-repeat: no-repeat;
}
.tilt {
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
margin: 0 auto;
}
.tilt__back {
position: relative;
}
.tilt__front {
position: absolute;
top: 0;
left: 0;
}
.tilt__back, .tilt__front {
width: 100%;
height: 100%;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: cover;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
我似乎无法获得与网站相同的布局。我不知道为什么。我在.home-page上应用60 px的填充时不会正确居中。我不想使用flexbox来实现相同的结果
答案 0 :(得分:2)
在 .home_page 上使用 box-sizing:border-box; ,它会正常工作。我添加了下面的代码段。
html,body{
width:100%;
height:100%;
}
.home_page{
width:100%;
height:100%;
background-color:#3c3c3e;
background-image: url(https://i.stack.imgur.com/wwy2w.jpg);
background-position: 50% 50%;
background-size: cover;
background-repeat: no-repeat;
padding:60px;
box-sizing:border-box;
}
.tilt {
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
margin: 0 auto;
background-color:yellow;
}
<div class="home_page">
<div class="tilt"></div>
</div>
答案 1 :(得分:0)
这是一个好方法。
<div class="divToCenterStuffIn">
<div class="vertCenter">
Vertical Center
</div>
</div>
<div class="divToCenterStuffIn">
<div class="horzCenter">
Horizontal Center
</div>
</div>
<div class="divToCenterStuffIn">
<div class="trueCenter">
True Center
</div>
</div>
.divToCenterStuffIn {
position: relative;
display: block;
width: 10rem;
height: 10rem;
}
.vertCenter
{
position: absolute;
display: block;
top:50%;
-ms-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.horzCenter
{
position: absolute;
display: block;
left: 50%;
-ms-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
.trueCenter {
position: absolute;
display: block;
left: 50%;
top: 50%;
-ms-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}