2010-06-04 10 views
19

मेरे पास एक बहुत ही सरल डेमो काम है जो 'पैनल' (divs) के बीच चिकनी क्षैतिज स्क्रॉलिंग के लिए वेबकिट ट्रांसफॉर्म और संक्रमण का उपयोग करता है।वेबकिट ट्रांसफॉर्म और संक्रमण का उपयोग करते समय फ़्लिकर को कैसे ठीक करें

कारण यह है कि मैं जावास्क्रिप्ट संचालित प्रणाली के विपरीत इस मार्ग पर जाना चाहता हूं कि यह आईपैड और जावास्क्रिप्ट प्रदर्शन के लिए काफी खराब है, लेकिन सीएसएस ट्रांसफॉर्म और संक्रमण रेशम के रूप में चिकनी हैं। अफसोस की बात है, हालांकि, मुझे अपने डेमो के साथ आईपैड पर बहुत झटका लग रहा है।

आप देख सकते हैं the demo here

आप कार्रवाई में यह देखने के लिए सफारी या और iPad की आवश्यकता होगी। मैंने कभी भी परिवर्तन और संक्रमण के लिए किसी भी जनसंख्या में ऐसा नहीं देखा है, इसलिए मुझे आशा है कि यह ठीक हो जाएगा।

वैसे भी यहाँ कोड है कि शक्तियों बात है ....

एचटीएमएल इस तरह दिखता है।

<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> 

सीएसएस इस

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; 
} 

उत्तर

8

की तरह लग रहा translateX के बजाय translate3d का उपयोग करें। ऐसा लगता है कि केवल अनुवाद 3 डी आईपैड 3.2 पर हार्डवेयर तेज है।

5

ऊपर वर्णित अनुसार, हार्डवेयर त्वरण के कारण अनुवाद 3 डी का उपयोग करना बेहतर है जो चिकनी संक्रमण के लिए बनाता है।

हालांकि, जब फ्लिकर एनिमेटेड स्क्रीन से बड़ा होता है तो झिलमिलाहट होती है। इसलिए, यदि आप एक क्षेत्र है कि 3.5 स्क्रीन चौड़ाई है कि आप क्षैतिज संक्रमण के लिए इच्छा के लिए कहते हैं, इसे 4 divs में इस

[1] [2] [3] [। 5]

तरह टूट जाना चाहिए

किसी भी divs स्क्रीन ऊंचाई या चौड़ाई से अधिक नहीं होना चाहिए।

इस उत्तर को पोस्ट करने में लापरवाही के लिए खेद है। जब तक मुझे अभी "लोकप्रिय प्रश्न" नोटिस नहीं मिला, तब तक मैं पूरी तरह से इसके बारे में भूल गया था।

+0

विशाल है - मैं एक ही समस्या में चल रहा हूँ, लेकिन मुझे यकीन है कि मैं इस सवाल का जवाब समझ में नहीं हूँ। मेरे पास एक समान लेआउट है - एक विस्तृत देखने वाला क्षेत्र जो व्यूपोर्ट/स्क्रीन के रूप में 300% चौड़ा है, और मैं उस क्षेत्र को बाएं और दाएं एनिमेट कर रहा हूं। यदि मैं इसे 3 divs में विभाजित करता हूं, प्रत्येक स्क्रीन के रूप में चौड़ा होता है - तो क्या आप सुझाव दे रहे हैं कि मैं प्रत्येक व्यक्ति को व्यक्तिगत रूप से एनिमेट करता हूं? – mattstuehler

1

मुझे पहली बार "3 डी" स्थिति में देखने के लिए फ्लिकर मिल गया। सबसे पहले मेरे सभी विचारों में संरक्षित-3 डी है। तब मैं इस कोड,

MyNamespace.flickerFixer = function(children) { 
children.css({ 
    "-webkitTransform": "translate3D(0px, 0px, 0px)", 
    "-webkit-transition": "1s ease-in-out" 
}); 
} 

है और फिर मैं यह वेबकिट एनिमेशन करने से पहले प्रारंभ:

MyNamespace.flickerFixer($this.parent(".ui-content")); 
45

@gargantaun सही है, वेबकिट flickers अगर तत्व आप एनिमेट करना चाहते स्क्रीन से भी बड़ा है। लेकिन एक आसान फिक्स है। बस जोड़ें:

-webkit-backface-visibility: hidden; 

तत्व के लिए और आप जाने के लिए अच्छे हैं!

+0

मैं उत्सुक हूँ, आपने इसे कैसे समझ लिया? – gargantuan

+0

इसे मिला [यहां] (http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform), इसकी हमारी [कंपनियों की वेबसाइट] के लिए आवश्यक है (http: // www .beenetwork.eu) (एनीमेशन के लिए बस कुछ सेकंड प्रतीक्षा करें)। –

+9

अपने जोखिम पर प्रयोग करें! जब आईओएस 7 बाहर आया, तो हमारी ऐप मेमोरी त्रुटियों के कारण दुर्घटनाग्रस्त हो गई। यह आमतौर पर 10-15 एमबी का उपयोग करता है, लेकिन आईओएस क्रैश लॉग ~ 600 एमबी के उपयोग की सूचना दी। कुछ खोदने के बाद, यह पता चला कि यह बैकफ़ेस-दृश्यता हैक (जिसे हम सचमुच हमारे स्रोत कोड से इस SO थ्रेड के लिए एक लिंक है) कारण था, या कम से कम, इसे हटाने से दुर्घटनाग्रस्त हो गया। यकीन नहीं क्यों, और यह केवल आईओएस 7 था। मुझे लगता है कि वेबकिट के ऐप्पल के कांटा में कुछ मेमोरी रिसाव बग या कुछ होना चाहिए। देवताओं के बहुत सारे आजकल आईओएस 7 सफारी दुर्घटनाग्रस्त होने के बारे में शिकायत कर रहे हैं। – greim

1

आजकल, आईओएस 8 के साथ, एक और अच्छा समाधान overflow: hidden को संक्रमित तत्वों (या उनके कंटेनर) पर लागू करना है।

0

WebExpo पर @tobiasahlin पर आधारित।

सफारी झिलमिलाते मुद्दा सबसे अच्छा समाधान ठीक

transform: translateZ(0); 
संबंधित मुद्दे