The realization of motion frame
Movement, in fact, in a period of time to change the left, right, width, height, opactiy value, to reach the destination after the stop.
now follow the steps below to carry out the package of our motion frame: uniform velocity. Buffer movement. Multi-Object movement. Any change in value. Chain type movement. Movement at the same time. (i) Motion speed animation basic
thinking: How to let the div move? as follows: Set element as absolute positioning, only after absolute positioning, left,top equivalent is effective. The use of the timer (dynamically changing the value), where the SetInterval () is used to execute the code at specified intervals. Timer setinterval (function, interaction time (milliseconds)): At execution time, code is executed at the specified time after the page is loaded. Cancels the timer clearinterval (function) method to cancel the interaction time set by SetInterval (). Get the current location, size, and so on. Offsetleft (the current element is relative to the parent element position). Velocity-the speed of the object movement the timer interval changes the size of the value according to the above information we can begin to encapsulate the motion frame to create a changed div.
- /**
- * Motion Frame--Move Up
- * @param {HtmlElement} element to move the node
- */
- var timer = null;
- function Startmove (Element) {
- Timer = setinterval (function () {//Timer
- Element.style.left = element.offsetleft + 5 + "px";
- }, 30);
- }
you are not wrong, it is so simple. But wait, what? Why won't you stop? WTF? That's because we don't have sports to terminate the condition. Well, it's still easier. Directly in the timer inside, judge to reach the target value, clear the timer on the line pull!
- /** 
- * Motion Frame-motion termination
- * @param {HTMLElement} element moving node
- * @param {number} iTarget movement termination conditions.
-  */ 
- var timer = null;
- function startmove (element, itarget) {
- timer = setinterval (function () {
- element.style.left = element.offsetLeft + 5 + "px";
- if (element.offsetleft === itarget) {//stop condition
- Clearinterval (timer);
- }
- },& NBSP;30);
- }
So is it done? It's OK now? No There are also some bugs to deal with.
the bug in the motion speed to some value can not stop the arrival of the position and then click on the motion repeated click speed can not be changed
resolution of the bug speed to some values will not stop ( This bug is resolved later, naturally resolved during evolution) to move and stop (If/else) when starting a motion, close an existing timer and save the speed with a variable
- /** 
- * Motion Framework-Solution bug
- */
- var timer = null;
- function Startmove (Element, itarget) {
- clearinterval (timer); Close existing timer
- timer = setinterval (function () {
- var ispeed = 5;//saves the speed with a variable
- //Move and Stop (If/else)
- if (Element.offsetleft === itarget) {//end motion
- clearinterval (timer);
-         } ELSE&NBsp {
- element.style.left = element.offsetLeft + iSpeed + "px";
- }
- }, 30);
- }
Such a simple frame of motion is done. But wait a second. Just go right? Don't worry, we're not defining speed as a variable? Just have to do some processing on it! var ispeed = 5;
- To determine the distance from the target position, to achieve automatic change speed or positive
- var ispeed = 0;
- if (Element.offsetleft < ITarget) {
- Ispeed = 5;
- } else {
- Ispeed =-5;
- }
Transparency Animation stores current transparency with variable alpha. Change the above element.offsetleft to variable alpha. The motion and stop conditions section are changed. As follows:
- Transparency Browser Compatibility implementation
- if (alpha = = ITarget) {
- Clearinterval (time);
- } else {
- Alpha + speed;
- Element.style.filter = ' alpha (opacity: ' + alpha + ') '; Compatible IE
- Element.style.opacity = alpha/100;//Standard
- }
(ii) Buffering animation
think: What is the buffer animation? Should have the following: Gradually slow, the last stop distance the greater the speed of the speed determined by the distance = (target-current value)/scaling factor Bug: Speed rounding (using the math method), otherwise it will flash upward rounding. Math.ceil (ispeed) is rounded down. Math.floor (ispeed) or the speed of the article:
- /**&NBSP;
- * Motion Frame-buffer animation
- */
- function startmove (element, itarget) {
-
- timer = SetInterval (function () {
- //must be placed in the timer because the speed is changing dynamically
- var iSpeed = (itarget - element.offsetleft) / 10; //(target-current value)/scaling factor = speed
- ispeed = ispeed > 0 ? math.ceil (ISpeed) : math.floor (ispeed); //speed rounding
- if (Element.offsetleft === itarget) {//End motion
- &nbsP; clearinterval (timer);
- } else {
- element.style.left = element.offsetLeft + ispeed + "px";
- }
- }, 30);
- }
Do this, (speed to some value will not be able to stop) the bug is automatically resolved! Example: Buffer menu follow page scrolling sidebar online Demo: Codepen potential problem target value is not an integer
(iii) Multi-object movement
thinking: How to achieve the movement of multiple objects? Single timer, there are problems. Each div a timer timer acts as an object's property directly using Element.timer to turn the timer into an attribute on the object. Transfer of parameters: Object/target value is simpler the above frame is changed as follows: Timer-->element.timer it's all right!
(iv) changes in arbitrary values
cough. Let's add a 1px border to the Div. boder:1px Solid #000 Then try the following code
- SetInterval (function () {
- ODiv.style.width = odiv.offsetwidth-1 + "px";
- }, 30)
Well, something magical has happened! What Do I not set the width in the minus? How the NI increased! No, Big Brother. What has gone wrong? Look for information together, see the document, the original offset this series of properties will exist, by other attributes interfere with the problem. Well, since it can't be used, then we'll just have to do the change of any value.
First step: Get the actual style Use offsetleft ... When you get a style, a bug occurs when you set a border, padding, and so on to change the properties of the element's width height. Find Element.currentstyle (attr) to get the properties after the calculation. But because of compatibility issues, you need to encapsulate the GetStyle function. (Evil IE) of course with CSS Box-sizing property set to Border-box can achieve the same effect? (self-considered, not validated).
- /**&NBSP;
- * get actual style function
- * @param {HTMLElement} element HTML node for the style to look for
- * @param {String]} attr style properties found in Objects
- * @returns {String} acquired property
- */
- function getstyle (element, attr) {
- //ie writing
- if (Element.currentstyle) {
- return element.currentstyle[attr];
- //Standard
- } else {
- return getcomputedstyle (Element, false) [attr];
- }
- }&NBSP;
Step Two: Transform the original function add parameters, attr represent the value of the property that needs to be changed. Change Element.offsetleft to GetStyle (element, attr). Note that getstyle (element, attr) cannot be used directly because it gets the string, example: 10px. Variable icurrent use parseint () to convert a style to a number. Element.style.left for Element.style[attr].
- /**
- * Arbitrary value change of motion frame
- * @param {HtmlElement} Element motion Object
- * @param {string} attr properties that need to be changed.
- * @param {Number} ITarget target value
- */
- function Startmove (element, attr, ITarget) {
- Clearinterval (Element.timer);
- Element.timer = setinterval (function () {
- Because the speed has to be changed dynamically, it must be placed in the timer.
- var icurrent=0;
- Icurrent = parseint (GetStyle (element, attr))//Actual style size
- var ispeed = (itarget-icurrent)/10; (target value-current value)/scaling factor = speed
- Ispeed = ispeed > 0? Math.ceil (ispeed): Math.floor (Ispeed); Speed rounding
- if (icurrent = = ITarget) {//End Motion
- Clearinterval (Element.timer);
- } else {
- ELEMENT.STYLE[ATTR] = icurrent + ispeed + "px";
- }
- }, 30);
- }
give it a try, is it OK? Do you remember the transparency changes we wrote above? Try again true or not, (nonsense, you have seen the transparency of "PX" unit?) --supercilious eyes)
Third step: transparency compatibility processingThinking: Do you need to modify those attributes? Determine if attr is a transparency property opacity. For speed processing. For transparency, you need * 100 because the transparency you get is decimal, and you need to round the decimal number to an integer because the computer stores floating point numbers. Use: Math.Round (parsefloat (GetStyle (element, attr)) * 100). Otherwise, continue using the default speed. Make changes to the result output section. Judgment is the transparency property, use the transparency method otherwise, use the default output format.
- /**
- * Motion Frame-compatible transparency
- * @param {HtmlElement} Element motion Object
- * @param {string} attr properties that need to be changed.
- * @param {Number} ITarget target value
- */
- function Startmove (element, attr, ITarget) {
- Clearinterval (Element.timer);
- Element.timer = setinterval (function () {
- Because the speed has to be changed dynamically, it must be placed in the timer.
- var icurrent = 0;
- if (attr = = "opacity") {//is executed for transparency.
- Icurrent = Math.Round (parsefloat (GetStyle (element, attr)) * 100);
- } else {//default
- Icurrent = parseint (GetStyle (element, attr)); Actual style size
- }
- var ispeed = (itarget-icurrent)/10; (target value-current value)/scaling factor = speed
- Ispeed = ispeed > 0? Math.ceil (ispeed): Math.floor (Ispeed); Speed rounding
- if (icurrent = = ITarget) {//End Motion
- Clearinterval (Element.timer);
- } else {
- if (attr = = "opacity") {//For transparency, perform
- Element.style.filter = "Alpha (opacity:" + (Icurrent + ispeed) + ")"; Ie
- Element.style.opacity = (icurrent + ispeed)/100; Standard
- } else {//default
- ELEMENT.STYLE[ATTR] = icurrent + ispeed + "px";
- }
- }
- }, 30);
- }
here, the movement framework is basically complete. But we're in pursuit of perfection, aren't we?
continue to evolve!
(v) Chain-type animation
chain Animation: As the name suggests, is to start the next movement when the movement stops. How to achieve it? Use the callback function: When the motion stops, the execution function adds the Func parameter (the callback function). Icurrent = = ITarget when the current attribute arrives at the destination, to determine if there is a callback function, and to execute it. if (icurrent = = ITarget) {//End movement Clearinterval (Element.timer); if (func) {func ();//callback function}} good, the chain animation completes! The perfect distance is still one step away!
(vi) Simultaneous movement
Thinking: How to achieve simultaneous movement? Use JSON to pass multiple values using a for in loop, traversing the property, and the value. Timer problem! (Motion stopped early) sets the variable outside the loop, suppose all the values have reached the destination value is true in the loop to detect whether to reach the target value, if no value is not yet, false at the end of the loop, detect whether all the target values are reached. Yes then clear Timer implementation: Delete attr and ITarget two parameter, change to JSON when the function starts, set a tag var flag = true; Let's say all the movements arrive at the end. In the timer, use for in, traverse the properties and targets, rewrite the original attr and ITarget, modify the motion termination condition for the properties and values of the JSON, and flag true only if the actual property value of each item is icurrent equal to the target value json[attr]. Clear the timer to determine if the callback. Otherwise, continue executing the code until all the property values are equal to the target value. Perfect Motion Frame
- /**
- * Get the actual style function
- * @param {htmlelement} element HTML node for the style to look for
- * @param {String]} attr The style properties found in the object
- * @returns the properties obtained by {String}
- */
- function GetStyle (element, attr) {
- IE notation
- if (Element.currentstyle) {
- return element.currentstyle[attr];
- Standard
- } else {
- return getComputedStyle (element, false) [attr];
- }
- }
- /**
- * Perfect Motion Frame
- * @param {HtmlElement} Element motion Object
- * @param {JSON} JSON attribute: Target value
- * @property {String} attr property value
- * @config {Number} target destination value
- * @param {function} func optional, callback function, chain animation.
- */
- function Startmove (element, JSON, func) {
- var flag = true; Let's say all the movements arrive at the end.
- Clearinterval (Element.timer);
- Element.timer = setinterval (function () {
- for (Var attr in JSON) {
- 1. Take the current property value.
- var icurrent = 0;
- if (attr = = "opacity") {//is executed for transparency.
- Icurrent = Math.Round (parsefloat (GetStyle (element, attr)) * 100);
- } else {//default
- Icurrent = parseint (GetStyle (element, attr)); Actual style size
- }
- 2. Calculate the movement speed, the animation buffering effect
- var ispeed = (json[attr]-icurrent)/10; (target value-current value)/scaling factor = speed
- Ispeed = ispeed > 0? Math.ceil (ispeed): Math.floor (Ispeed); Speed rounding
- 3. Execute code when the target value is not reached
- if (icurrent!= json[attr]) {
- Flag = false; Termination condition
- if (attr = = "opacity") {//For transparency, perform
- Element.style.filter = "Alpha (opacity:" + (Icurrent + ispeed) + ")"; Ie
- Element.style.opacity = (icurrent + ispeed)/100; Standard
- } else {//default
- ELEMENT.STYLE[ATTR] = icurrent + ispeed + "px";
- }
- } else {
- Flag = true;
- }
- 4. Motion terminated, whether callback
- if (flag) {
- Clearinterval (Element.timer);
- if (func) {
- Func ();
- }
- }
- }
- }, 30);
- }
Summary of
motion frameMotion frame Evolution Process Framework Change startmove (Element) movement Startmove (Element,itarg ET) uniform--> buffer--> Startmove (ELEMENT,ATTR,ITARGRT) arbitrary value startmove (Element,attr,itargrt,func) Chain Motion Startmove (ELEMENT,JSON,FUNC) multi-value (simultaneous)--> Perfect motion frame