我有一个非常简单的演示工作,它使用Webkit转换和过渡来在“面板”(div)之间进行平滑的水平滚动。
我想采用这种方式而不是使用Javascript驱动的系统的原因是,它用于iPad,Javascript性能相当差,但是CSS转换和过渡像丝绸一样平滑。不过,可悲的是,我的演示版在iPad上引起了很多闪烁。
您可以看到the demo here
您需要使用野生动物园或iPad才能观看它的运行。我从未在任何有关转换和过渡的演示中看到过这种情况,因此我希望这是可以修复的。
无论如何,这是为事物提供动力的代码。...
HTML看起来像这样。
<html>
<head>
<title>Swipe Demo</title>
<link href="test.css" rel="stylesheet" />
<link href="styles.css" rel="stylesheet" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="functions.js"></script>
<script type="text/javascript" src="swiping.js"></script>
</head>
<body>
<div id="wrapper">
<div class='panel one'>
<h1>This is panel 1</h1>
</div>
<div class='panel two'>
<h1>This is panel 2</h1>
</div>
<div class='panel three'>
<h1>This is panel 3</h1>
</div>
<div class='panel four'>
<h1>This is panel 4</h1>
</div>
</div>
</body>
</html>
CSS看起来像这样
body,
html
{
padding: 0;
margin: 0;
background: #000;
}
#wrapper
{
width: 10000px;
-webkit-transform: translateX(0px);
}
.panel
{
width: 1024px;
height: 300px;
background: #fff;
display: block;
float: left;
position: relative;
}
并且javascript看起来像这样
// Mouse / iPad Touch
var touchSupport = (typeof Touch == "object"),
touchstart = touchSupport ? 'touchstart' : 'mousedown',
touchmove = touchSupport ? 'touchmove' : 'mousemove',
touchend = touchSupport ? 'touchend' : 'mouseup';
$(document).ready(function(){
// set top and left to zero
$("#wrapper").css("top", 0);
$("#wrapper").css("left", 0);
// get total number of panels
var panelTotal;
$(".panel").each(function(){ panelTotal += 1 });
// Touch Start
// ------------------------------------------------------------------------------------------
var touchStartX;
var touchStartY;
var currentX;
var currentY;
var shouldMove = false;
document.addEventListener(touchstart, swipeStart, false);
function swipeStart(event){
touch = realEventType(event);
touchStartX = touch.pageX;
touchStartY = touch.pageY;
var pos = $("#wrapper").position();
currentX = parseInt(pos.left);
currentY = parseInt(pos.top);
shouldMove = true;
}
// Touch Move
// ------------------------------------------------------------------------------------------
var touchMoveX;
var touchMoveY;
var distanceX;
var distanceY;
document.addEventListener(touchmove, swipeMove, false);
function swipeMove(event){
if(shouldMove){
touch = realEventType(event);
event.preventDefault();
touchMoveX = touch.pageX;
touchMoveY = touch.pageY;
distanceX = touchMoveX - touchStartX;
distanceY = touchMoveY - touchStartY;
movePanels(distanceX);
}
}
function movePanels(distance){
newX = currentX + (distance/4);
$("#wrapper").css("left", newX);
}
// Touch End
// ------------------------------------------------------------------------------------------
var cutOff = 100;
var panelIndex = 0;
document.addEventListener(touchend, swipeEnd, false);
function swipeEnd(event){
touch = (touchSupport) ? event.changedTouches[0] : event;
var touchEndX = touch.pageX;
var touchEndY = touch.pageY;
updatePanelIndex(distanceX);
gotToPanel();
shouldMove = false;
}
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function updatePanelIndex(distance){
if(distanceX > cutOff)
panelIndex -= 1;
if(distanceX < (cutOff * -1)){
panelIndex += 1;
}
if(panelIndex < 0){
panelIndex = 0;
}
if(panelIndex >= panelTotal)
panelIndex = panelTotal -1;
console.log(panelIndex);
}
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function gotToPanel(){
var panelPos = getTotalWidthOfElement($(".panel")) * panelIndex * -1;
$("#wrapper").css("-webkit-transition-property", "translateX");
$("#wrapper").css("-webkit-transition-duration", "1s");
$("#wrapper").css("-webkit-transform", "translateX("+panelPos+"px)");
}
});
function realEventType(event){
e = (touchSupport) ? event.targetTouches[0] : event;
return e;
}
尝试使用translate3d而不是translateX。在iPad 3.2上似乎只有translate3d可以通过硬件加速。
@@ gargantaun是正确的,如果要设置动画的元素大于屏幕,则Webkit会闪烁。但是有一个简单的解决方法。只需添加:
-webkit-backface-visibility: hidden;
到元素,你很高兴!
如上所述,由于硬件加速可实现更平滑的过渡,因此最好使用Translate3d。
但是,当动画div大于屏幕时,会引起闪烁。因此,如果您希望增加一个水平宽度为3.5的屏幕宽度的区域,则应将其分成4个div,例如:
[1] [2] [3] [。5]
div均不应超过屏幕的高度或宽度。
抱歉发布此答案的时间太晚。我完全忘记了它,直到我收到一个“热门问题”通知。
我首先使视图处于“ 3D”状态,从而消除了闪烁。首先,我所有视图都保留了3D。然后我有此代码,
MyNamespace.flickerFixer = function(children) {
children.css({
"-webkitTransform": "translate3D(0px, 0px, 0px)",
"-webkit-transition": "1s ease-in-out"
});
}
然后我在进行Webkit动画之前将其初始化:
MyNamespace.flickerFixer($this.parent(".ui-content"));
[现在,在iOS8上,另一个好的解决方案是将overflow: hidden
应用于所包含的元素(或其容器)。
我发现,与对left:或right:类进行动画处理相比,translate3D是更好的解决方案。它在Safari上效果很好,并且更流畅。
这是幻灯片:
.cartout-enter-active {
-webkit-animation: cartout 0.2s;
animation: cartout 0.2s;
}
.cartout-leave-active {
-webkit-animation: cartout 0.2s reverse;
animation: cartout 0.15s reverse;
}
@-webkit-keyframes cartout {
from {
transform: translate3d(100%, 0, 0);
}
to {
transform: translate3d(0%, 0, 0);
}
}