Friday, December 18, 2009

CS 164 Final Project: JPix

Part 1

1. What problem are you addressing? Describe an instance; missing features, etc

We will be writing a plugin that allows composable animations to be made easily through Javascript/jQuery. The plugin will include features such as “move” (where we move an image a certain amount of pixels X and Y), and will allow objects to be composed of other objects that have their own animation. With these two basic functionalities and other functions that we will add, we can compose any type of animation and have them do a variety of things such as following a mouse and respond to triggered events. Moving animations around in jQuery is a commonly sought task. For example, to make an image of a bee follow a mouse and accelerate around using jQuery, there exists a plugin called "squidy" that allows doing so. But what if we want this animation to also occur on a fixed rotation rather than following the mouse? This will normally require copy/pasting another code or looking for another plugin that accomplishes this task, or else a lot of ugly Javascript writing. We want a to create a plugin you can just do something similar to this in jQuery:

moveBee = moveXY delay=1 accel=1 bee mousefollow = 1/0

bee = importBitmap "../Media/bee.bmp"

but laid out in a simple manner, and with other optional functionality that can be added in without much more effort. Our plugin will abstract away all the ugly code and allow for more general flexibility and composability.


2. Argue why this problem is hard.

Images and animations deal with a lot of 2D visualization and pixel details. Animations in general are hard to work with, because they deal with many different variables that occur at the same time. Since the general trend is towards more images/fancier UI’s, there should be more generalized and easier-to-use interfaces for animating graphics. Composing objects is also hard because objects cannot be referenced in compositions, but must instead be cloned so animations do not step over each other trying to animate the same object.

3. Argue why this problem is worth solving.

The existing solutions are not really customizable; we aimed to give people more control and allow them to do more with one plugin. For example, the squidy stuff is meant only for mouse following. You can’t do anything else. Since jQuery is a design language, it is expected that users will be want to be able make many different types of composable animations with it. Composable animations would also be a plus because it would allow abstraction of animations and make creating animations modular, which is a concept that CS majors would understand better than just pure artsy stuff.



Part 2

"squidy" is our sample language that solves a similar problem. However there are many limitations with squidy:

The image MUST follow the mouse.

All the trailing images have the same delay.

The images are evenly spaced with the same offsets.

Can’t have multiple images following the mouse.

The image cannot be turned into a link or anything else.

Trailing images could potentially blocks things you want to click on, unless you hardcode it into squidy. We want this as an option in our plugin.

Sample Squidy Code

$.squidy({head_img: '/__data/assets/image/0007/1795048/Bee2.gif', //Describes what image is the head

tail_img: '/__data/assets/image/0017/1800620/beetail.gif',//Describes what image is the tail

tail_length: 12,//Describe how many of the tail image make up the tail

tail_spacing_x: -2,//Describes how far apart images in the tail are spaced

tail_offset_x: 5, //Describes the horizontal offset of the tail from the head

tail_offset_y:-20});//Describes the vertical offset of the tail from the head

Squidy is implemented as a function in jQuery with code mixed in from Javascript. It allows the declaration of variables in a hash that is passed in as an argument. The above describes how many tails are used, how far apart each tail is spaced, how far away the tail is from the main image, and what images are the main and the tail images. It then creates the image at a location off the view of the page before allowing it to follow the mouse. The images are each created separately on the fly through jQuery, each with its own CSS that specifies its location.

Squidy uses a separate plugin called jquery-periodic that allows an animate function to be called repeatedly at timed intervals, and does this indefinitely. It tracks the position of the mouse with an event handler that records the mouse’s X and Y location every time the mouse moves. Inside squidy’s animate function, squidy does calculations based on the current X and Y and the mouse’s current X and Y to adjust for velocity and acceleration. When periodic calls this function, the image is made to move like typical jQuery image movements through changing CSS, and is targeted towards the mouse.


Squidy ({head_img, tail_img, tail_spacing, tail_offsets}) {

Mouse_location = find_Mouse_Location()

Animate = New Squidy_animation()

Periodic_repeat(animate)

Track(Mouse_location)

}

Squidy_animation() {

Calculate distance from mouse location

Set velocity and acceleration to move towards mouse

Move the object

}

Part 3

1. Sample programs we can make using our plugin:

a. An image moving across the screen

b. Two images on top of each other, moving around

c. Two images following the mouse

d. Moving clouds with a static sun background (composed animations)

e. Human shapes that do animations triggered by mouse clicks

f. A bee catching game: Bees are flying around the screen. A net follows your mouse; you must use the net to catch all the bees. Once a bee is caught by your net, the bee then switches to following the "net" (the mouse) as well.

2. The “objects” in our language are the images as well as divs that contain various things like text. We will use method chaining to describe what we want each animation object to do. Operations on these images include:

a. Animations

i. In set paths

ii. In relation to other objects, like mouse following

iii. Fading

iv. Rotation, scaling, appearing, and more

v. Changing movement style

b. controls/event triggered actions

i. mouse movement

ii. timer

iii. clicks

iv. and more

c. Most of the smaller animations will be placed inside larger animations for basic operations. Combining a set of animations within another animation (through a list of actions to be taken) may be a possible option for consolidation effects into higher levels of abstraction.

3. Write an example program in your language.

Milestone: Three Example Programs to be Demoed at Poster Session

These examples should better illustrate how we plan to implement the language. They are 3 different animations: 1.) clouds moving in front of the sun, 2.) 3 people who, when clicked on, do certain animations, and 3.) the bee-catching game mentioned above.

Note that due to time restraints, movements here are shown as absolute. It would be possible to extend the language to allow relative movement as well, but may not be added due to time limitations. If we have time to add it in for the demo, know that we will.

# Clouds moving in Front of Sun Animation

new JPixAction("slowcircle","move").path([[30,30],[20,40],[10,30]]).speed(10)

.clone("fastcircle").path([[60,60],[70,50],[40,60]]).speed(40)

new JPixAction("sunrotate","rotate").angle(360).speed(1000)

new JPixObject("slowCloud").addImg("cloud1.bmp").position(20,20).addAction("slowmove").properties({})

new JPixObject("fastCloud").addImg("cloud2.bmp").position(50,50).addAction("fastmove").properties({})

new JPixObject("sun").addImg("sun.bmp").startPos(90,30).addAction("sunrotate").properties({})

new JPixObject("sky").addObject("slowCloud").addObject("fastCloud").addObject("sun").properties({width:'500',height:'500',backgroundColor:'blue'}).run()


# Click on 3 people animation; When clicked, each person does an action

# path(), rotate(), disappear() to be abstracted away under an Action class; they are each Actions


new JPixAction("jump","move")

new JPixAction("backflip","rotate")

new JPixAction("disappear", "fade")

new JPixObject("jumper").addImage("person.bmp").position(100,200).addOnClick("jump").properties({}).run()

new JPixObject("gymnast").addImage("./person.bmp").position(200,200).addOnMouseOver("backflip").properties({}).run()

new JPixObject("ninja").addImage("person.bmp").position(300,200).addOnDblClick("disappear").properties({}).run()


# Bee game - Bees flying around. Net follows mouse, and you use the net to catch bees. When net touches

# bee, the captured bee follows mouse as well.

# There's only 2 bees for simplicity


new JPixAction("bee1path", "move").path([[20,20], [500,300], [500,20], [20,300], [20,20]]).speed(20).properties({loop:forever})

new JPixAction("bee2path", "move").path([[400,100], [400,200], [20,20], [400,100]]).speed(10).properties({loop:forever})

new JPixAction("followMouse", "follow").target("@mouse")

.clone("follow1").offset(20,0)

.clone("follow2").offset(40,0)

.clone("follow3").offset(60,0)

new JPixAction("changeMouse", "change").target("follow2")


new JPixObject("bee1").addImage("bee.bmp")).position(20,20).addAction("bee1path").addOnClick("changeMouse").properties({}).run()


new JPixObject("bee2").addImage("bee.bmp")).position(400,100).addAction("bee2path").addOnClick("changeMouse")properties({})

new JPixObject("net1").addImage("net1.bmp").addAction("follow1").properties({})

new JPixObject("net2").addImage("net2.bmp").addAction("follow2").properties({})

new JPixObject("net3").addImage("net3.bmp").addAction("follow3").properties({})


new JPixObject("net").addObject("net1").addObject("net2").addObject("net3").properties({}).run()



Part 4

Front End: Our plugin is implemented in Javascript/jQuery as a library for Javascript. It will be implemented directly into web pages as a .js file. We will have objects that will be created and modified with method chaining to describe the variables. Users will be using syntactic sugar to specify the variables they want, and to access existing animation styles.

The core language: The core language will essentially be sugared functions in Javascript that set variables for a given object. Objects are created via new JPixObject(name) and can be referenced via JPixObects[name]. Actions are created via new JPixAction(name, type[optional]) where type is to specify existing JPix Action library actions. Both have a properties({}) tag used to specify any fields not accessible otherwise. JPixObject uses addAction, addOnMouseClick, etc. to add events, and these may be directly implemented as Javascript/JQuery functions instead of using premade library functions.

Internal Representation: The internal representation is separated in JPixObjects and JPixActions. Objects can have an action, and can contain other objects, and are composable. Actions are actions that will be generated, either run through event handlers or added to a global periodic worklist that continues() those functions to provide parallelism of running actions. Objects are items contained inside their own div, which makes action binding through JQuery easier. Objects, when animated, will first render themselves and their children before calling the actions specified with each item.

Interpreter/Compiler: The interpreter/compiler is the construct() method for Actions and the run() method for Objects. run() will first call render() on the object, and render() calls down its children. render() will display the object with the correct properties. Then, run() will call the animate() function, which will call construct() on the action unless it's an existing object. The action object's construct() will then change the action object into a working function, mostly through an existing actions library, and return the function to the object, which will then put it onto the periodic worklist. This will go down into the children as well. Event handler actions are different in that they are constructed when the event handler is run rather than when run() is called.

Debugging: The implementation is debugged mainly by viewing the result on web pages and through the use of Javascript consoles in Developer Tools on Google Chrome and IE8 that point out where lines of Javascript break down.

Friday, November 20, 2009

Part 1

1. What problem are you addressing? Describe an instance; missing features, etc

We will be writing a plugin that allows composable animations to be made easily through Javascript/jQuery. The plugin will include features such as “move” (where we move an image a certain amount of pixels X and Y), “over” (where we combine multiple animations on top of each other, such as two moving images). With these two basic functions and other functions that we will add, we can compose any type of animation and have them do a variety of things such as following a mouse and triggered events. The problem is that moving animations around in jQuery is a commonly sought task. For example, to make an image of a bee follow a mouse and accelerate around using jQuery, there exists a plugin called "squidy" that allows doing so. But what if we want this animation to also occur on a fixed rotation rather than following the mouse? This will normally require copy/pasting another code or looking for another plugin that accomplishes this task. We want a to create a plugin you can just do something similar to this in jQuery:

moveBee = moveXY delay=1 accel=1 bee mousefollow = 1/0

bee = importBitmap "../Media/bee.bmp"

Our plugin will abstract away all the ugly code and allow for more general flexibility.


2. Argue why this problem is hard.

Images and animations deal with a lot of 2D visualization and pixel details. Animations in general are hard to work with, because they deal with many different variables that occur at the same time. Since the general trend is towards more images/fancier UI’s, there should be a more generalized and easier-to-use interface for animating graphics.

3. Argue why this problem is worth solving.

The existing solutions are not really customizable; we aimed to give people more control and allow them to do more with one plugin. For example, the squidy stuff is meant only for mouse following. You can’t do anything else. Since jQuery is a design language, it is expected that users will be want to be able make many different types of composable animations with it.



Part 2

"squidy" is our sample language that solves a similar problem. However there are many limitations with squidy:

The image MUST follow the mouse.

All the trailing images have the same delay.

The images are evenly spaced with the same offsets.

Can’t have multiple images following the mouse.

The image cannot be turned into a link or anything else.

Trailing images could potentially blocks things you want to click on, unless you hardcode it into squidy. We want this as an option in our plugin.

Sample Squidy Code

$.squidy({head_img: '/__data/assets/image/0007/1795048/Bee2.gif', //Describes what image is the head

tail_img: '/__data/assets/image/0017/1800620/beetail.gif',//Describes what image is the tail

tail_length: 12,//Describe how many of the tail image make up the tail

tail_spacing_x: -2,//Describes how far apart images in the tail are spaced

tail_offset_x: 5, //Describes the horizontal offset of the tail from the head

tail_offset_y:-20});//Describes the vertical offset of the tail from the head

Squidy is implemented as a function in jQuery with code mixed in from Javascript. It allows the declaration of variables in a hash that is passed in as an argument. The above describes how many tails are used, how far apart each tail is spaced, how far away the tail is from the main image, and what images are the main and the tail images. It then creates the image at a location off the view of the page before allowing it to follow the mouse. The images are each created separately on the fly through jQuery, each with its own CSS that specifies its location.

Squidy uses a separate plugin called jquery-periodic that allows an animate function to be called repeatedly at timed intervals, and does this indefinitely. It tracks the position of the mouse with an event handler that records the mouse’s X and Y location every time the mouse moves. Inside squidy’s animate function, squidy does calculations based on the current X and Y and the mouse’s current X and Y to adjust for velocity and acceleration. When periodic calls this function, the image is made to move like typical jQuery image movements through changing CSS, and is targeted towards the mouse.


Squidy ({head_img, tail_img, tail_spacing, tail_offsets}) {

Mouse_location = find_Mouse_Location()

Animate = New Squidy_animation()

Periodic_repeat(animate)

Track(Mouse_location)

}

Squidy_animation() {

Calculate distance from mouse location

Set velocity and acceleration to move towards mouse

Move the object

}

Part 3

1. Sample programs we can make using our plugin:

a. An image moving across the screen

b. Two images on top of each other, moving around

c. A string of text following with different time delays for each word

d. Two images following the mouse

e. Moving clouds with a static sun background (composed animations)

f. Human shapes that do animations triggered by mouse clicks

g. A bee catching game: Bees are flying around the screen. A net follows your mouse; you must use the net to catch all the bees. Once a bee is caught by your net, the bee then switches to following the net (and thus, the mouse) as well.

2. The “objects” in our language are the images as well as divs that contain various things like text. We will use method chaining to describe what we want each animation object to do. Operations on these images include:

a. Movement

i. Vertical/horizontal

ii. In circles, lines or other set paths

iii. In relation to other objects

iv. Fading and other animations during movements

v. And more

b. controls/event triggered actions

i. mouse movement

ii. timer

iii. clicks

iv. and more

c. Most of the smaller animations will be placed inside larger animations for basic operations. Combining a set of animations within another animation (through a list of actions to be taken) may be a possible option for consolidation effects into higher levels of abstraction.

3. Write an example program in your language.

(added in as the milestone below, where we wrote 3 programs in our language)

Milestone: Three Example Programs to be Demoed at Poster Session

These examples should better illustrate how we plan to implement the language. They are 3 different animations: 1.) clouds moving in front of the sun, 2.) 3 people who, when clicked on, do certain animations, and 3.) the bee-catching game mentioned above.

# Clouds moving in Front of Sun Animation


new Animation.Panel().width(200).height(200)

.createObject("slowCloud").shape(importImg("./cloud1.bmp")).startPos(0,100).properties({})

.createObject("fastCloud").shape(importImg("./cloud2.bmp")).startPos(0,100).properties({})

.createObject("sun").shape(Object("circle").properties({color:yellow})).startPos(10,10).properties({})

.createObject("cloudPair").startPos(0,100)

.includeAction("fastMove").actionProperties({})

.includeAction("slowMove").actionProperties({})

.createAction("slowMove").target(Object("slowCloud"))

.path([[0,100], [200,100]]) # start, end points

.speed(7) # time in seconds it takes to do action

.actionProperties({}) # default delay is 0, else can define here?

.createAction("fastMove").target(Object("fastCloud"))

.path([[0,100], [200,100]])

.speed(4)

.actionProperties({})

.createAction("staticSun").target(Object("sun"))

.actionProperties({})

.runAllActions();


# Click on 3 people animation; When clicked, each person does an action

# path(), rotate(), disappear() to be abstracted away under an Action class; they are each Actions


new Animation.Panel().width(400).height(400)

.createObject("jumper").shape(importImg("./person.bmp")).startPos(100,0).properties({})

.createObject("rotator").shape(importImg("./person.bmp")).startPos(200,0).properties({})

.createObject("disappearer").shape(importImg("./person.bmp")).startPos(300,0).properties({})

.createAction("jump").target("jumper")

.path([[100,0], [100,100], [100,0]]) # more points would define more complex paths, ie A to B, then B to C

.speed(2)

.actionProperties({onClick:True}) # if onClick == True, perform Action when target Object is clicked

.createAction("rotate").target("rotator")

.rotate(360)

.speed(2)

.actionProperties({onClick:True})

.createAction("disappear").target("disappearer")

.disappear()

.speed(2)

.actionProperties({onClick:True})

.runAllActions();


# Bee game - Bees flying around. Net follows mouse, and you use the net to catch bees. When net touches

# bee, the captured bee follows mouse as well.

# There's only 2 bees for simplicity


# onCollision(x, y): on collision with x, set targets Action to argument Action


new Animation.Panel().width(500).height(500)

.createObject("bee1").shape(importImg("./bee.bmp")).startPos(20,20).properties({})

.createObject("bee2").shape(importImg("./bee.bmp")).startPos(400,100).properties({})

.createObject("net").shape(importImg("./net.bmp")).startPos(0,0).properties({})

.createAction("bee1path").target("bee1")

.path([[20,20], [500,300], [500,20], [20,300]. [20,20]]) # bee1 moves in pseudo figure 8 path

.speed(7)

.onCollision("net", setAction("self",follow("net")).actionProperties({}))

.actionProperties({loop:forever})

.createAction("bee2path").target("bee2")

.path([[400,100], [400,200], [20,20], [400,100]]) # bee2 moves in triangular path

.speed(5)

.onCollision("net", setAction("self",follow("net")).actionProperties({}))

.actionProperties({loop:forever})

.createAction("netAction").target("net")

.followMouse()

.actionProperties({})

.runAllActions();



Part 4

Front End: Our plugin will be implemented in jQuery/javascript as an addon for jQuery. It will be implemented directly into web pages as a .js file. We will have objects that will be called with method chaining to describe the variables. Another alternative is to create a parser that will read a special syntax and generate an AST to be passed into an “interpreter”. The first will be easier to implement and will allow us to work directly with objects, but also be messier to deal with. The latter will take more effort, but will allow us to generalize many things, create an easy to use interface, and consolidate them into one place. We will be using protovis-style chain calling to create on the front end.

The core language: The core language will essentially be sugared functions in jQuery that call jQuery and javascript code. We can either have it animate straight away, but instead we will want to have it return an object with the ability to be called with animate().

Internal Representation: The internal representation can either be commands for actions that can be taken, and then have those actions parsed into an AST that will then be passed into an “interpreter”, or we can have animation objects that declare the variables, which are then also passed into some sort of interpreter to run. The objects will be easier to interpret than an AST, but the AST will be easier to inspect.

Interpreter/Compiler: Both will be run directly by jQuery/Javascript. This will be slow, but it will be easy to do, and accessible to any internet user. The calls will be interpreted within the functions that are used to generate the object, and the animation() call will also act as an interpreter, compiling the information stored inside the animation actions and objects, and making sure that all the calls to the actions will work accordingly. The actions will be placed inside a list of actions, which will be periodically called to refresh the actions on the page and calculate new positions for each object.

Debugging: The implementation will be debugged mainly by viewing the result on web pages.


Answers to questions from email:

- Can you describe what kind of animations can be composed?

There will be classes of objects, and actions that target said objects. Furthermore, objects can be composed of
other actions, which allows the composition of animation to occur.

- Can you give two examples of code in your language on how animations will be composed?

(Examples were given above in part 3)

- How will you implement the composition of animations?

The composition of the animation will be done through functions. Each action will be a function that does an action and will be added to the action list, but will also add any actions within the object it targets, thus allowing those actions to be carried out as well.


- How will animation be implemented? Will there be a list of active objects (those that are being animated) and every x msec (ie every frame) you will update each of these elements? Will you implement this list yourselves or will you delegate this to an existing jQuery functionality?

We will be mainly using jQuery functions to specify which actions are to be done. It will mainly be through a list of actions to be called every few milliseconds to update each element

- What implementation strategy will you use to update the elements in each frame, eg how will you compute the new positions of these elements?

This will be specified in the objects properties. If it is not, it will be done relative to the window's X:0 Y:0. Otherwise, it may be specified relative to another object or at a fixed window position.