Html 如何修复使用Webkit变换时的闪烁&;过渡
我有一个非常简单的演示,它使用Webkit变换和转换在“面板”(div)之间平滑地水平滚动 我之所以要走这条路,而不是Javascript驱动的系统,是因为它适用于iPad,Javascript性能相当差,但css转换和转换非常平滑。遗憾的是,我的演示在iPad上出现了很多闪烁 你可以看到 你需要safari或iPad才能看到它的运行。我从未在任何变换和转换的演示中看到过这种情况,所以我希望这是可以解决的 不管怎么说,这是为这件事提供动力的代码 HTML如下所示Html 如何修复使用Webkit变换时的闪烁&;过渡,html,css,safari,webkit,Html,Css,Safari,Webkit,我有一个非常简单的演示,它使用Webkit变换和转换在“面板”(div)之间平滑地水平滚动 我之所以要走这条路,而不是Javascript驱动的系统,是因为它适用于iPad,Javascript性能相当差,但css转换和转换非常平滑。遗憾的是,我的演示在iPad上出现了很多闪烁 你可以看到 你需要safari或iPad才能看到它的运行。我从未在任何变换和转换的演示中看到过这种情况,所以我希望这是可以解决的 不管怎么说,这是为这件事提供动力的代码 HTML如下所示 <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>
javascript看起来是这样的
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;
}
// 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;
}
//鼠标/iPad触摸屏
var touchSupport=(触摸类型=“对象”),
touchstart=touchSupport?“touchstart':'mousedown',
touchmove=touchSupport?“touchmove':'mousemove',
touchend=touchSupport?“touchend':'mouseup';
$(文档).ready(函数(){
//将顶部和左侧设置为零
$(“#包装器”).css(“顶部”,0);
$(“#包装器”).css(“左”,0);
//获取面板的总数
总风险价值;
$(“.panel”).each(函数(){panelTotal+=1});
//触式起动
// ------------------------------------------------------------------------------------------
var-touchtartx;
var触摸屏;
无功电流x;
无功电流;
var shouldMove=false;
文档。addEventListener(touchstart、swipeStart、false);
功能启动(事件){
触摸=realEventType(事件);
touchStartX=touch.pageX;
touchStartY=touch.pageY;
var pos=$(“#包装器”).position();
currentX=parseInt(位置左侧);
currentY y=parseInt(位置顶部);
shouldMove=true;
}
//触动
// ------------------------------------------------------------------------------------------
var-touchMoveX;
var touchMoveY;
var距离;
var距离;
文件。添加的文件列表(touchmove、swipeMove、false);
功能开关移动(事件){
如果(应该移动){
触摸=realEventType(事件);
event.preventDefault();
touchMoveX=touch.pageX;
touchMoveY=touch.pageY;
距离X=触摸移动X-触摸开始X;
distanceY=touchMoveY-touchStartY;
移动面板(距离X);
}
}
功能面板(距离){
newX=电流x+(距离/4);
$(“#包装器”).css(“左”,newX);
}
//接触端
// ------------------------------------------------------------------------------------------
var截止=100;
var指数=0;
文件。添加的监听器(触摸端、开关、假);
功能切换(事件){
触摸=(触摸支持)?事件。更改触摸[0]:事件;
var touchEndX=touch.pageX;
var touchEndY=touch.pageY;
updatePanelIndex(距离X);
gotToPanel();
shouldMove=false;
}
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
函数updatePanelIndex(距离){
如果(距离X>截止)
panelIndex-=1;
如果(距离X<(截止*-1)){
指数+=1;
}
如果(面板索引<0){
panelIndex=0;
}
如果(panelIndex>=panelTotal)
panelIndex=panelTotal-1;
console.log(panelIndex);
}
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
函数gotToPanel(){
var panelPos=getTotalWidthOfElement($(“.panel”)*panelIndex*-1;
$(“#包装器”).css(“-webkit转换属性”,“translateX”);
$(“#包装器”).css(“-webkit转换持续时间”,“1s”);
$(“#包装器”).css(“-webkit-transform”,“translateX”(+panelPos+“px”);
}
});
函数realEventType(事件){
e=(touchSupport)?事件。targetTouches[0]:事件;
返回e;
}
尝试使用translate3d而不是translateX。似乎只有translate3d在iPad 3.2上是硬件加速的。如上所述,最好使用translate3d,因为硬件加速有助于更平滑的过渡
但是,当正在设置动画的div大于屏幕时,会导致闪烁。所以,如果你有一个区域,加起来有3.5个屏幕宽度,你希望水平过渡,它应该被分成4个像这样的分区
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;
}
// 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;
}
[1][2][3][.5]
所有div均不得超过屏幕高度或宽度
很抱歉延迟发布此答案。我完全忘记了这一点,直到我刚刚收到一个“热门问题”通知。我首先将视图设置为“3D”状态,从而消除了闪烁。首先,我的所有视图都打开了preserve-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"));
@gargantaun是对的,如果要设置动画的元素比屏幕大,Webkit会闪烁。但有一个简单的解决办法。只需添加:
-webkit-backface-visibility: hidden;
到元素和你是好去 如今,使用iOS8,另一个好的解决方案是将
溢出:隐藏
应用于被指控的元素(或其容器)。基于WebExpo上的讨论
Safari闪烁问题修复的最佳解决方案是
transform: translateZ(0);
我发现translate3D是比设置左:或右:类动画更好的解决方案。它在safari上运行良好,并且更平滑。即使在iOS13上,我也有一些重大的问题 这是一张幻灯片:
.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);
}
}
庞大-我遇到了同样的问题,但我不确定我是否理解这个答案。我有一个类似的布局-一个宽的可视区域,它的宽度是视口/屏幕的300%,我正在左右设置该区域的动画。如果我把它分成3个分区,每个分区都和屏幕一样宽,那么你是在建议我