Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate a HTML element after creating using Backbone.js

This code I have is given below. How can I resize an element with a JQuery like animation in this case? Details is written as a comment in the code.

Template:

<script id="content_template" type="text/template">
        <div
                class="content"
                style="position: absolute;
                    top:<%= top %>px;
                    left:<%= left %>px;
                    width:<%= width %>px;
                    height:<%= height %>px; "
        ></div>
</script>

Model:

var FrameObject = Backbone.Model.extend({
    defaults: {
        top: 0,
        left: 0,
        width: 1,
        height: 1
    }
});

Collection:

var FrameObjects = Backbone.Collection.extend({
    model: FrameObject
});

Object view:

var Object_view = Backbone.View.extend({
    template: _.template($("#content_template").html()),
    render:function(){
        return this.template(this.model.toJSON());
    }
});

Object container view:

var App_view = Backbone.View.extend({
    el: $(".container"),
    events: {
        "click .container": "create_object"
    },
    create_object: function(event){
        var frame_object = new FrameObject({
            top: event.pageX,
            left: event.pageY,
            width: 100,
            height: 100
        });
        frame_objects.add(frame_object);

        var object_view = new Object_view({model: frame_object});
        this.$(".container").append(object_view.render());

        /* here I want to change the 'top' & 'left' attributes of the object model
           and want my object_view to animate to that position. Same as it would do for -

           someElement.animate({top: newTop, left: newLeft});
        */
    }
});
like image 316
Tahin Rahman Avatar asked Feb 21 '23 02:02

Tahin Rahman


1 Answers

I wrote a simple example:

var FrameObject = Backbone.Model.extend({
    defaults: {
        top: 0,
        left: 0,
        width: 1,
        height: 1
    }
});

var FrameObjects = Backbone.Collection.extend({
    model: FrameObject
});

var ObjectView = Backbone.View.extend({
    className: 'frame',

    initialize: function() {
        this.model.on('change', this.animate, this);
    },

    render: function() {
        var params = _.extend(this.model.toJSON(),  { position: 'absolute' });
        this.$el.css(params);
        return this;
    },

    animate: function() {
        this.$el.animate(this.model.toJSON());
    }
});

var AppView = Backbone.View.extend({
    el: $("#container"),

    events: {
        "click": "createObject"
    },

    createObject: function(event) {
        var frameObject = new FrameObject({
            top: event.pageY,
            left: event.pageX,
            width: 100,
            height: 100
        });

        var frameObjects = new FrameObjects();

        frameObjects.add(frameObject);

        var objectView = new ObjectView({
            model: frameObject
        });
        this.$el.append(objectView.render().el);

        setTimeout(function() {
            frameObject.set({
                // 500 — width of #container
                top: Math.random() * 500,
                left: Math.random() * 500
            })
        }, 1000);
    }
});

var appView = new AppView();

http://jsfiddle.net/theotheo/4Y8gy/

Notice I've made a few changes to your code. Firstly, I changed events hash of AppView, or more precisely I omitted selector, because

Omitting the selector causes the event to be bound to the view's root element (this.el).

It seems like it's exactly what you want. Second, I removed the template of ObjectView. You can use it, of course, but at this case I think it's not necessary. Third, I renamed variables for the sake of consistency. Feel free to ask.

like image 188
theotheo Avatar answered Feb 22 '23 17:02

theotheo