I have a very simple demo working that uses Webkit transforms and transitions for smooth horizontal scrolling between 'panels' (divs).
我有一个非常简单的演示工作,它使用Webkit转换和过渡来平滑地滚动“面板”(div)。
The reason I want to go this route as opposed to a Javascript driven system is that it's for the iPad and Javascript performance is quite poor, but the css transforms and transitions are smooth as silk. Sadly though, I'm getting a lot of flicker on the iPad with my Demo.
与Javascript驱动系统不同,我之所以选择这条路,是因为它是针对iPad的,而且Javascript的性能很差,但是css的转换和转换就像丝绸一样平滑。遗憾的是,我的演示在iPad上有很多闪光点。
You can see the demo here
你可以在这里看到演示
You'll need safari or and iPad to see it in action. I've never seen this happening in any of the demos for transforms and transitions so I'm hopeful that this is fixable.
你需要safari或者iPad才能看到它的运行。我从来没有在任何一个转换和转换的演示中看到过这种情况,所以我希望这是可以修复的。
Anyway here's the code that powers the thing....
无论如何这是权力的代码的....
The HTML looks like this.
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>
The CSS looks like this
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;
}
and the javascript looks like this
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;
}
6 个解决方案
#1
8
Try using translate3d instead of translateX. It appears only translate3d is hardware accelerated on iPad 3.2.
尝试使用translate3d而不是translateX。它似乎只在iPad 3.2上加速了硬件加速。
#2
45
@gargantaun is right, Webkit flickers if the element you want to animate is bigger than the screen. But there is an easy fix. Just add:
@gargantaun是对的,如果你想要动画的元素比屏幕大,Webkit会闪烁。但有一个简单的解决办法。添加:
-webkit-backface-visibility: hidden;
to the element and you are good to go!
到元素和你是好的去!
#3
5
As mentioned above, it is better to use Translate3d due to the hardware acceleration which makes for smoother transitions.
如上所述,使用Translate3d比较好,因为硬件加速可以使转换更加流畅。
However, the flicker is caused when the div being animated is larger than the screen. So, if you have an area that adds up to 3.5 screen widths that you wish to transition horizontally, it should be broken up into 4 divs like this
但是,当正在动画的div比屏幕大时,会引起闪烁。所以,如果你有一个区域的屏幕宽度加起来是3。5,你想水平移动,它应该被分成4个div,像这样
[ 1 ][ 2 ][ 3 ][.5]
[2][3][.5]
None of the divs should exceed the screens height or width.
所有的divs都不应该超过屏幕的高度或宽度。
Sorry for the lateness in posting this answer. I'd completely forgotten about it until I just got a "popular question" notice.
很抱歉,迟交了这个答案。我完全忘了这件事,直到我收到一个“流行问题”通知。
#4
1
I got the flicker to go away by first getting the view to be in a "3D" state. First I have all my views have the preserve-3D on. Then I have this code,
我先让视图处于“3D”状态,让闪烁消失。首先我把所有的视图都打开了。然后我有了这个代码,
MyNamespace.flickerFixer = function(children) {
children.css({
"-webkitTransform": "translate3D(0px, 0px, 0px)",
"-webkit-transition": "1s ease-in-out"
});
}
And then I initialize it before doing webkit animations:
然后我在做webkit动画之前初始化它:
MyNamespace.flickerFixer($this.parent(".ui-content"));
#5
1
Nowadays, with iOS8, another good solution is to apply a overflow: hidden
to the incriminated elements (or their container).
现在,有了iOS8,另一个好的解决方案是应用溢出:隐藏已定罪的元素(或它们的容器)。
#6
0
Based on @tobiasahlin talk at WebExpo.
基于@tobiasahlin在WebExpo的谈话。
Safari flickering issue fix best solution is
Safari闪烁问题修复的最佳解决方案是
transform: translateZ(0);
#1
8
Try using translate3d instead of translateX. It appears only translate3d is hardware accelerated on iPad 3.2.
尝试使用translate3d而不是translateX。它似乎只在iPad 3.2上加速了硬件加速。
#2
45
@gargantaun is right, Webkit flickers if the element you want to animate is bigger than the screen. But there is an easy fix. Just add:
@gargantaun是对的,如果你想要动画的元素比屏幕大,Webkit会闪烁。但有一个简单的解决办法。添加:
-webkit-backface-visibility: hidden;
to the element and you are good to go!
到元素和你是好的去!
#3
5
As mentioned above, it is better to use Translate3d due to the hardware acceleration which makes for smoother transitions.
如上所述,使用Translate3d比较好,因为硬件加速可以使转换更加流畅。
However, the flicker is caused when the div being animated is larger than the screen. So, if you have an area that adds up to 3.5 screen widths that you wish to transition horizontally, it should be broken up into 4 divs like this
但是,当正在动画的div比屏幕大时,会引起闪烁。所以,如果你有一个区域的屏幕宽度加起来是3。5,你想水平移动,它应该被分成4个div,像这样
[ 1 ][ 2 ][ 3 ][.5]
[2][3][.5]
None of the divs should exceed the screens height or width.
所有的divs都不应该超过屏幕的高度或宽度。
Sorry for the lateness in posting this answer. I'd completely forgotten about it until I just got a "popular question" notice.
很抱歉,迟交了这个答案。我完全忘了这件事,直到我收到一个“流行问题”通知。
#4
1
I got the flicker to go away by first getting the view to be in a "3D" state. First I have all my views have the preserve-3D on. Then I have this code,
我先让视图处于“3D”状态,让闪烁消失。首先我把所有的视图都打开了。然后我有了这个代码,
MyNamespace.flickerFixer = function(children) {
children.css({
"-webkitTransform": "translate3D(0px, 0px, 0px)",
"-webkit-transition": "1s ease-in-out"
});
}
And then I initialize it before doing webkit animations:
然后我在做webkit动画之前初始化它:
MyNamespace.flickerFixer($this.parent(".ui-content"));
#5
1
Nowadays, with iOS8, another good solution is to apply a overflow: hidden
to the incriminated elements (or their container).
现在,有了iOS8,另一个好的解决方案是应用溢出:隐藏已定罪的元素(或它们的容器)。
#6
0
Based on @tobiasahlin talk at WebExpo.
基于@tobiasahlin在WebExpo的谈话。
Safari flickering issue fix best solution is
Safari闪烁问题修复的最佳解决方案是
transform: translateZ(0);