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.