كيف يمكنني الحصول على مسج تنفيذ الرسوم المتحركة في الدقيقة متوازيان ؟

StackOverflow https://stackoverflow.com/questions/811750

  •  03-07-2019
  •  | 
  •  

سؤال

أحاول إنشاء القطعة الأكورديون في مسج مماثلة مسج الأكورديون هو البرنامج المساعد, مع الفرق التي أريد مقابض تظهر أسفل كل منهما المحتوى بدلا من أعلاه.الأكورديون يعمل عن طريق تقليل ارتفاع فتح قسم المحتوى في الوقت نفسه زيادة ارتفاع النقر قسم المحتوى.لقد نشرت مثال هنا.مشكلتي هي أن الرسوم المتحركة ليست بدأت في نفس الوقت ، وهناك ملحوظة "القفز" بسبب تأخير طفيف قبل الثانية المتحركة بدأت.

Scriptaculous له وظيفة تسمى تأثير.موازية هذا يسمح لك لخلق مجموعة من الرسوم المتحركة والمؤثرات تنفيذها بالتوازي.للأسف, أنا لا يمكن أن يبدو للعثور على شيء مماثل مع مسج.

هل هناك طريقة يمكنني تشغيل دقة الموازي الرسوم المتحركة منفصلة divs في jquery ؟

تحرير:أنا مهتمة كثيرا في طرق بديلة الترميز هذه القطعة الأكورديون.لذلك إذا كان هناك أي طريقة أخرى من الناس يعتقدون أن العمل أنا مستعد لذلك.

هل كانت مفيدة؟

المحلول

واحد أكثر إجابة، ونأمل بلدي واحد آخر ...

ولسوء الحظ، طريقة syncAnimate جون ريسيغ ليست تماما حتى مات لالأكورديون من نوع الرسوم المتحركة أريد القيام به. بينما يعمل كبيرة على فايرفوكس، لم أتمكن من الحصول على عمل بسلاسة على IE أو سفاري.

وقال مع ذلك، قررت لدغة الرصاص ويكتب لي محرك الرسوم المتحركة الخاصة التي لا الرسوم المتحركة موازية بسيطة. يستخدم رمز الطبقة ظائف مسج ولكن ليس المساعد مسج. أيضا، لقد حدد ذلك فقط ما يصل الى القيام الرسوم المتحركة حجم / الموقف، الذي هو كل ما تحتاج.

ParallelAnimations = function(animations, opts){
    this.init(animations, opts);
};

$.extend(ParallelAnimations.prototype, {
    options: {
        duration: 250
    },
    rules: {},

    init: function(animations, opts){
        // Overwrite the default options
        $.extend(this.options, opts);

        // Create a set of rules to follow in our animation
        for(var i in animations){
            this.rules[i] = {
                element: animations[i].element,
                changes: new Array()
            };

            for(var style in animations[i].styles){

                // Calculate the start and end point values for the given style change
                var from = this.parse_style_value(animations[i].element, style, "");
                var to = this.parse_style_value(animations[i].element, style, animations[i].styles[style]);

                this.rules[i].changes.push({
                    from: from,
                    to: to,
                    style: style
                });
            }
        }

        this.start()
    },

    /*
     * Does some parsing of the given and real style values
     * Allows for pixel and percentage-based animations
     */
    parse_style_value: function(element, style, given_value){
        var real_value = element.css(style);

        if(given_value.indexOf("px") != -1){
            return {
                amount: given_value.substring(0, (given_value.length - 2)),
                unit: "px"
            };
        }

        if(real_value == "auto"){
            return {
                amount: 0,
                unit: "px"
            };
        }

        if(given_value.indexOf("%") != -1){
            var fraction = given_value.substring(0, given_value.length - 1) / 100;

            return {
                amount: (real_value.substring(0, real_value.length - 2) * fraction),
                unit: "px"
            };
        }

        if(!given_value){
            return {
                amount: real_value.substring(0, real_value.length - 2),
                unit: "px"
            };
        }
    },

    /*
     * Start the animation
     */
    start: function(){
        var self = this;
        var start_time = new Date().getTime();
        var freq = (1 / this.options.duration);

        var interval = setInterval(function(){
            var elapsed_time = new Date().getTime() - start_time;

            if(elapsed_time < self.options.duration){
                var f = elapsed_time * freq;

                for(var i in self.rules){
                    for(var j in self.rules[i].changes){
                        self.step(self.rules[i].element, self.rules[i].changes[j], f);
                    }
                }
            }
            else{
                clearInterval(interval);

                for(var i in self.rules){
                    for(var j in self.rules[i].changes)
                        self.step(self.rules[i].element, self.rules[i].changes[j], 1);
                }
            }
        }, 10);
    },

    /*
     * Perform an animation step
     * Only works with position-based animations
     */ 
    step: function(element, change, fraction){

        var new_value;
        switch(change.style){
            case 'height':
            case 'width':
            case 'top':
            case 'bottom':
            case 'left':
            case 'right':
            case 'marginTop':
            case 'marginBottom':
            case 'marginLeft':
            case 'marginRight':
                new_value = Math.round(change.from.amount - (fraction * (change.from.amount - change.to.amount))) + change.to.unit;
                break;
        }

        if(new_value)
            element.css(change.style, new_value);
    }
});

وبعد ذلك يحتاج الطبقة الأكورديون الأصلية فقط إلى تعديل في طريقة تحريك للاستفادة من الدعوة الجديدة.

Accordion = function(container_id, options){
    this.init(container_id, options);
}

$.extend(Accordion.prototype, {
    container_id: '',
    options: {},
    active_tab: 0,    
    animating: false,
    button_position: 'below',
    duration: 250,
    height: 100,

    handle_class: ".handle",
    section_class: ".section",

    init: function(container_id, options){
        var self = this;
        this.container_id = container_id;
        this.button_position = this.get_button_position();

        // The height of each section, use the height specified in the stylesheet if possible
        this.height = $(this.container_id + " " + this.section_class).css("height");

        if(options && options.duration)    this.duration = options.duration;
        if(options && options.active_tab)  this.active_tab = options.active_tab;

        // Set the first section to have a height and be "open"
        // All the rest of the sections should have 0px height
        $(this.container_id).children(this.section_class).eq(this.active_tab)
            .addClass("open")
            .css("height", this.height)
            .siblings(this.section_class)
            .css("height", "0px");

        // figure out the state of the handles
        this.do_handle_logic($(this.container_id).children(this.handle_class).eq(this.active_tab));

        // Set up an event handler to animate each section
        $(this.container_id + " " + this.handle_class).mouseover(function(){

            if(self.animating)
                return;

            self.animate($(this));
        });
    },

    /*
     * Determines whether handles are above or below their associated section
     */     
    get_button_position: function(){
        return ($(this.container_id).children(":first").hasClass(this.handle_class) ? 'above' : 'below');
    },

    /*
     * Animate the accordion from one node to another
     */ 
    animate: function(handle){
        var active_section = (this.button_position == 'below' ? handle.prev() : handle.next());    
        var open_section = handle.siblings().andSelf().filter(".open");

        if(active_section.hasClass("open"))
            return;

        this.animating = true;

        // figure out the state of the handles
        this.do_handle_logic(handle);

        // Close the open section
        var arr = new Array();
        arr.push({
            element: open_section,
            styles: {
                "height": "0px"
            }
        });
        arr.push({
            element: active_section,
            styles: {
                "height": this.height
            }
        });
        new ParallelAnimations(arr, {duration: this.duration});

        var self = this;
        window.setTimeout(function(){
            open_section.removeClass("open");
            active_section.addClass("open");
            self.animating = false;
        }, this.duration);
    },

    /*
     * Update the current class or "state" of each handle
     */ 
    do_handle_logic: function(handle){
        var all_handles = handle.siblings(".handle").andSelf();
        var above_handles = handle.prevAll(this.handle_class);
        var below_handles = handle.nextAll(this.handle_class);

        // Remove all obsolete handles
        all_handles
            .removeClass("handle_on_above")
            .removeClass("handle_on_below")
            .removeClass("handle_off_below")
            .removeClass("handle_off_above");

        // Apply the "on" state to the current handle
        if(this.button_position == 'below'){
            handle
                .addClass("handle_on_below");
        }
        else{
            handle
                .addClass("handle_on_above");
        }

        // Apply the off above/below state to the rest of the handles
        above_handles
            .addClass("handle_off_above");

        below_handles
            .addClass("handle_off_below");
    }
});

ووHTML لا يزال يسمى بنفس الطريقة:

<html>
<head>
    <title>Parallel Accordion Animation</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="ui.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
        new Accordion("#accordion");
    });
    </script>
    <style type="text/css">
    #accordion{
        position: relative;
    }
    #accordion .handle{
        width: 260px;
        height: 30px;
        background-color: orange;
    }
    #accordion .section{
        width: 260px;
        height: 445px;
        background-color: #a9a9a9;
        overflow: hidden;
        position: relative;
    }
    </style>
</head>
<body>

<div id="accordion">
    <div class="section"><!-- --></div>
    <div class="handle">handle 1</div>
    <div class="section"><!-- --></div>
    <div class="handle">handle 2</div>
    <div class="section"><!-- --></div>
    <div class="handle">handle 3</div>
    <div class="section"><!-- --></div>
    <div class="handle">handle 4</div>
    <div class="section"><!-- --></div>
    <div class="handle">handle 5</div>
</div>

</body>
</html>

وهناك عدد قليل من الأشياء أود أن أضيف في المستقبل:  - قائمة الانتظار متحركة  - صور متحركة لأنواع أخرى من الأساليب (ألوان، الخ)

نصائح أخرى

وجون ريسيغ سجلت متزامنة الرسوم المتحركة نموذجا (أي تعليمات، انقر فوق مربع ملون). قد يستغرق بعض العمل لمعرفة كيفية تطبيقه على التحكم الخاصة بك، ولكن يمكن أن يكون مكانا جيدا للبدء.

وهذا لا يحل تشغيل الرسوم المتحركة بالتوازي مع ذلك أنها تستنسخ السلوك المتوقع من دون غضب. أنا وضعت الباب داخل المقبض للحد من عدد من الرسوم المتحركة. هل يمكن استخدام andSelf () لجعل رمز أصغر ولكن سيكون من الصعب قراءتها. سوف تحتاج إلى إجراء بعض بتعديل النمط.

<html>
<head>
    <title>Accordion Test</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">

    $(document).ready(function(){
        $("#accordion .handle").click(function(){
            var open = $(this).parent().children(".section, .open");
            var active = $(this);

            if (!active.hasClass("open"))
            {
                if (active.hasClass("up"))
                {
                  console.log("up");
                  active.animate({top:"+=100"}).removeClass("up");
                  active.nextAll(".handle").andSelf().filter(".up").animate({top:"+=100"}).removeClass("up");
                  $(".section", active).slideUp();
                  $(".section", active.nextAll()).slideUp();
                  $(".section", active.prev()).slideDown();
                }
                else
                {
                  active.prevAll(".handle").not(".up").animate({top:"-=100"}).addClass("up");
                  $(".section", active.prev()).slideDown();
                }

                open.removeClass("open");
                active.addClass("open");
            }
        });
    });

    </script>
    <style type="text/css">
        #accordion{
            width: 200px;
            position:relative;
        }
        #accordion .section{
            width: 196px;
            margin-left: 2px;
            height: 100px;
            background-color: #b9b9b9;
            display:none;
        }
        #accordion .handle{
            width: 200px;
            height: 30px;
            background-color: #d9d9d9;
            border: 1px solid black;
            cursor: pointer;
            cursor: hand;
            position: absolute;
        }
        #accordion .handle .header {
            height: 30px;
        }
    </style>
</head>
<body>

<div id="accordion">
    <div id="s1" class="section open" style="display:block">This is section 1</div>

    <div class="handle open" style="top:100;">
      <div class="header">handle 1</div>
      <div class="section">This is section 2</div>
    </div>

    <div class="handle" style="top:130;">
      <div class="header">handle 2</div>
      <div class="section">This is section 3</div>
    </div>

    <div class="handle" style="top:160;">
      <div class="header">handle 3</div>
      <div class="section">This is section 4</div>
    </div>

    <div class="handle" style="top:190;">
      <div class="header">handle 4</div>
      <div class="section">This is section 5</div>
    </div>

    <div class="handle" style="top:220;">
      <div class="content">handle 5</div>
    </div>
</div>

</body>
</html>

وبفضل آدم الشاقول عن حل عظيم حقا موازية الرسوم المتحركة. كان لي مشكلة صغيرة مع ذلك وعلى الرغم من أن كان ذلك حفظه بطريقة أو بأخرى أدوار من الرسوم المتحركة في وقت سابق أنا ثابت ذلك من خلال وضع قواعد ل{} قبل إضافتها في وظيفة الحرف الأول. ومن المحتمل أنه يمكن القيام به بشكل أفضل على الرغم من. أود أيضا أن أضيف دالة رد أن يسمى عند الرسوم المتحركة الانتهاء.

ParallelAnimations = function(animations, opts){
    this.init(animations, opts);
};

$.extend(ParallelAnimations.prototype, {
    options: {
        duration: 250,
        callback: null
    },
    rules: {},

    init: function(animations, opts){
        // Overwrite the default options
        $.extend(this.options, opts);

        // Create a set of rules to follow in our animation
        this.rules = {}; // Empty the rules.
        for(var i in animations){
            this.rules[i] = {
                element: animations[i].element,
                changes: new Array()
            };

            for(var style in animations[i].styles){

                // Calculate the start and end point values for the given style change
                var from = this.parse_style_value(animations[i].element, style, "");
                var to = this.parse_style_value(animations[i].element, style, animations[i].styles[style]);

                this.rules[i].changes.push({
                    from: from,
                    to: to,
                    style: style
                });
            }
        }

        this.start()
    },

    /*
     * Does some parsing of the given and real style values
     * Allows for pixel and percentage-based animations
     */
    parse_style_value: function(element, style, given_value){
        var real_value = element.css(style);

        if(given_value.indexOf("px") != -1){
            return {
                amount: given_value.substring(0, (given_value.length - 2)),
                unit: "px"
            };
        }

        if(real_value == "auto"){
            return {
                amount: 0,
                unit: "px"
            };
        }

        if(given_value.indexOf("%") != -1){
            var fraction = given_value.substring(0, given_value.length - 1) / 100;

            return {
                amount: (real_value.substring(0, real_value.length - 2) * fraction),
                unit: "px"
            };
        }

        if(!given_value){
            return {
                amount: real_value.substring(0, real_value.length - 2),
                unit: "px"
            };
        }
    },

    /*
     * Start the animation
     */
    start: function(){
        var self = this;
        var start_time = new Date().getTime();
        var freq = (1 / this.options.duration);

        var interval = setInterval(function(){
            var elapsed_time = new Date().getTime() - start_time;

            if(elapsed_time < self.options.duration){
                var f = elapsed_time * freq;

                for(var i in self.rules){
                    for(var j in self.rules[i].changes){
                        self.step(self.rules[i].element, self.rules[i].changes[j], f);
                    }
                }
            }
            else{
                clearInterval(interval);

                for(var i in self.rules){
                    for(var j in self.rules[i].changes)
                        self.step(self.rules[i].element, self.rules[i].changes[j], 1);
                }
                if(self.options.callback != null) {
                    self.options.callback(); // Do Callback
                }
            }
        }, 10);
    },

    /*
     * Perform an animation step
     * Only works with position-based animations
     */ 
    step: function(element, change, fraction){

        var new_value;
        switch(change.style){
            case 'height':
            case 'width':
            case 'top':
            case 'bottom':
            case 'left':
            case 'right':
            case 'marginTop':
            case 'marginBottom':
            case 'marginLeft':
            case 'marginRight':
                new_value = Math.round(change.from.amount - (fraction * (change.from.amount - change.to.amount))) + change.to.unit;
                break;
        }

        if(new_value)
            element.css(change.style, new_value);
    }
});

وأعتقد أن مشكلتك ليست التوقيت ولكن تقسيم كسور من بكسل. إذا حاولت هذا الرمز يبدو سهل للمقبض 1 و 2 ولكن ليس غيرها في فايرفوكس 3 ولكن لا تزال تبدو ثاب في الكروم.

 active
    .animate({ height: "100px" })
    .siblings(".section")
    .animate({ height: "0px" });

هل فكرت في اتخاذ موقف من عناصر ثابتة أو مطلقة؟ إذا كان لديك فقط تحريك الموقف من عنصرين لم يكن لديك ما يدعو للقلق بعضها الآخر القفز. أعطني الثانية وسأحاول أن جعل على سبيل المثال.

تحديث:أنا لم تعد تستخدم John Resig هو syncAnimate المساعد.أرى بلدي في وقت لاحق الإجابة عن الحل النهائي

أردت فقط أن العرض النهائي العامل الحل الذي أنا توظيف على المشروع.ويستخدم syncAnimate المساعد أن John Resig كتب (منشورة من قبل كوربن آذار / مارس).

هذا الكود:

  • قراءة و استخدام قسم من ارتفاع CSS
  • تسمح لك لضبط مدة الرسوم المتحركة ، الافتراضية النشط القسم من خلال كائن الخيارات.
  • تلقائيا الكشف عن التعامل مع الموقف بالنسبة إلى القسم وضبط وفقا لذلك.إذا قمت بتحريك مقابض فوق أو تحت القسم في العلامات و لا تضطر إلى تغيير js التعليمات البرمجية.

HTML

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="ui.js"></script>

<script type="text/javascript">
$(document).ready(function(){
    new Accordion("#accordion", {active_tab: 0});
});
</script>
<style type="text/css">
#accordion .handle{
    width: 260px;
    height: 30px;
    background-color: orange;
}
#accordion .section{
    width: 260px;
    height: 445px;
    background-color: #a9a9a9;
    overflow: hidden;
    position: relative;
}

</style>

<div id="accordion">
    <div class="section">Section Code</div>
    <div class="handle">handle 1</div>

    <div class="section">Section Code</div>
    <div class="handle">handle 2</div>

    <div class="section">Section Code</div>
    <div class="handle">handle 3</div>

    <div class="section">Section Code</div>
    <div class="handle">handle 4</div>

    <div class="section">Section Code</div>
    <div class="handle">handle 5</div>
</div>

ui.js

Accordion = function(container_id, options){
    this.init(container_id, options);
}

$.extend(Accordion.prototype, {
    container_id: '',
    options: {},
    active_tab: 0,    
    animating: false,
    button_position: 'below',
    duration: 250,
    height: 100,

    handle_class: ".handle",
    section_class: ".section",

    init: function(container_id, options){
        var self = this;
        this.container_id = container_id;
        this.button_position = this.get_button_position();

        // The height of each section, use the height specified in the stylesheet if possible
        this.height = $(this.container_id + " " + this.section_class).css("height");

        if(options && options.duration)    this.duration = options.duration;
        if(options && options.active_tab)  this.active_tab = options.active_tab;

        // Set the first section to have a height and be "open"
        // All the rest of the sections should have 0px height
        $(this.container_id).children(this.section_class).eq(this.active_tab)
            .addClass("open")
            .css("height", this.height)
            .siblings(this.section_class)
            .css("height", "0px");

        // figure out the state of the handles
        this.do_handle_logic($(this.container_id).children(this.handle_class).eq(this.active_tab));

        // Set up an event handler to animate each section
        $(this.container_id + " " + this.handle_class).mouseover(function(){

            if(self.animating)
                return;

            self.animate($(this));
        });
    },

    /*
     * Determines whether handles are above or below their associated section
     */     
    get_button_position: function(){
        return ($(this.container_id).children(":first").hasClass(this.handle_class) ? 'above' : 'below');
    },

    /*
     * Animate the accordion from one node to another
     */ 
    animate: function(handle){
        var active_section = (this.button_position == 'below' ? handle.prev() : handle.next());    
        var open_section = handle.siblings().andSelf().filter(".open");

        if(active_section.hasClass("open"))
            return;

        this.animating = true;

        // figure out the state of the handles
        this.do_handle_logic(handle);

        // Close the open section
        open_section
            .syncAnimate(active_section, {"height": "0px"}, {queue:false, duration:this.duration}, '')
            .removeClass("open");

        // Open the new section
        active_section
            .syncAnimate(open_section, {"height": this.height}, {queue:false, duration:this.duration}, '')
            .addClass("open");

        var self = this;
        window.setTimeout(function(){
            self.animating = false;
        }, this.duration);
    },

    /*
     * Update the current class or "state" of each handle
     */ 
    do_handle_logic: function(handle){
        var all_handles = handle.siblings(".handle").andSelf();
        var above_handles = handle.prevAll(this.handle_class);
        var below_handles = handle.nextAll(this.handle_class);

        // Remove all obsolete handles
        all_handles
            .removeClass("handle_on_above")
            .removeClass("handle_on_below")
            .removeClass("handle_off_below")
            .removeClass("handle_off_above");

        // Apply the "on" state to the current handle
        if(this.button_position == 'below'){
            handle
                .addClass("handle_on_below");
        }
        else{
            handle
                .addClass("handle_on_above");
        }

        // Apply the off above/below state to the rest of the handles
        above_handles
            .addClass("handle_off_above");

        below_handles
            .addClass("handle_off_below");
    }
});

وأنت لا تستطيع أن تفعل له تأثير مواز في مسج مع طابور السليم ونطاقها. Scriptaculous انها حصلت على حق مع طابور ونطاق حيث من ناحية أخرى لديها مسج .queue و.animate التي هي عديمة الفائدة أساسا مجتمعة. الشيء الوحيد مسج هو جيد لمن خارج منطقة الجزاء ودفع بعض سمات النمط حولها على دوم في حين يغطي Scriptaculous مجموعة كاملة من ما هو ممكن مع الآثار.

وتحتاج إلى استخدام Scriptaculous وجون ريسيغ يجب إعادة النظر في jQuery.fx، وينبغي أن يكون النظر في scripty2.com في حين انه في ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top