Skip to content

Commit 3f3876f

Browse files
committed
add
0 parents  commit 3f3876f

14 files changed

+4145
-0
lines changed

Diff for: README.md

Whitespace-only changes.

Diff for: animate.js

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* Scroller
3+
* http://github.com/zynga/scroller
4+
*
5+
* Copyright 2011, Zynga Inc.
6+
* Licensed under the MIT License.
7+
* https://raw.github.com/zynga/scroller/master/MIT-LICENSE.txt
8+
*
9+
* Based on the work of: Unify Project (unify-project.org)
10+
* http://unify-project.org
11+
* Copyright 2011, Deutsche Telekom AG
12+
* License: MIT + Apache (V2)
13+
*/
14+
15+
/**
16+
* Generic animation class with support for dropped frames both optional easing and duration.
17+
*
18+
* Optional duration is useful when the lifetime is defined by another condition than time
19+
* e.g. speed of an animating object, etc.
20+
*
21+
* Dropped frame logic allows to keep using the same updater logic independent from the actual
22+
* rendering. This eases a lot of cases where it might be pretty complex to break down a state
23+
* based on the pure time difference.
24+
*/
25+
(function(global) {
26+
var time = Date.now || function() {
27+
return +new Date();
28+
};
29+
var desiredFrames = 60;
30+
var millisecondsPerSecond = 1000;
31+
var running = {};
32+
var counter = 1;
33+
34+
// Create namespaces
35+
if (!global.core) {
36+
global.core = { effect : {} };
37+
38+
} else if (!core.effect) {
39+
core.effect = {};
40+
}
41+
42+
core.effect.Animate = {
43+
44+
/**
45+
* A requestAnimationFrame wrapper / polyfill.
46+
*
47+
* @param callback {Function} The callback to be invoked before the next repaint.
48+
* @param root {HTMLElement} The root element for the repaint
49+
*/
50+
requestAnimationFrame: (function() {
51+
52+
// Check for request animation Frame support
53+
var requestFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame;
54+
var isNative = !!requestFrame;
55+
56+
if (requestFrame && !/requestAnimationFrame\(\)\s*\{\s*\[native code\]\s*\}/i.test(requestFrame.toString())) {
57+
isNative = false;
58+
}
59+
60+
if (isNative) {
61+
return function(callback, root) {
62+
requestFrame(callback, root)
63+
};
64+
}
65+
66+
var TARGET_FPS = 60;
67+
var requests = {};
68+
var requestCount = 0;
69+
var rafHandle = 1;
70+
var intervalHandle = null;
71+
var lastActive = +new Date();
72+
73+
return function(callback, root) {
74+
var callbackHandle = rafHandle++;
75+
76+
// Store callback
77+
requests[callbackHandle] = callback;
78+
requestCount++;
79+
80+
// Create timeout at first request
81+
if (intervalHandle === null) {
82+
83+
intervalHandle = setInterval(function() {
84+
85+
var time = +new Date();
86+
var currentRequests = requests;
87+
88+
// Reset data structure before executing callbacks
89+
requests = {};
90+
requestCount = 0;
91+
92+
for(var key in currentRequests) {
93+
if (currentRequests.hasOwnProperty(key)) {
94+
currentRequests[key](time);
95+
lastActive = time;
96+
}
97+
}
98+
99+
// Disable the timeout when nothing happens for a certain
100+
// period of time
101+
if (time - lastActive > 2500) {
102+
clearInterval(intervalHandle);
103+
intervalHandle = null;
104+
}
105+
106+
}, 1000 / TARGET_FPS);
107+
}
108+
109+
return callbackHandle;
110+
};
111+
112+
})(),
113+
114+
115+
/**
116+
* Stops the given animation.
117+
*
118+
* @param id {Integer} Unique animation ID
119+
* @return {Boolean} Whether the animation was stopped (aka, was running before)
120+
*/
121+
stop: function(id) {
122+
var cleared = running[id] != null;
123+
if (cleared) {
124+
running[id] = null;
125+
}
126+
127+
return cleared;
128+
},
129+
130+
131+
/**
132+
* Whether the given animation is still running.
133+
*
134+
* @param id {Integer} Unique animation ID
135+
* @return {Boolean} Whether the animation is still running
136+
*/
137+
isRunning: function(id) {
138+
return running[id] != null;
139+
},
140+
141+
142+
/**
143+
* Start the animation.
144+
*
145+
* @param stepCallback {Function} Pointer to function which is executed on every step.
146+
* Signature of the method should be `function(percent, now, virtual) { return continueWithAnimation; }`
147+
* @param verifyCallback {Function} Executed before every animation step.
148+
* Signature of the method should be `function() { return continueWithAnimation; }`
149+
* @param completedCallback {Function}
150+
* Signature of the method should be `function(droppedFrames, finishedAnimation) {}`
151+
* @param duration {Integer} Milliseconds to run the animation
152+
* @param easingMethod {Function} Pointer to easing function
153+
* Signature of the method should be `function(percent) { return modifiedValue; }`
154+
* @param root {Element ? document.body} Render root, when available. Used for internal
155+
* usage of requestAnimationFrame.
156+
* @return {Integer} Identifier of animation. Can be used to stop it any time.
157+
*/
158+
start: function(stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) {
159+
160+
var start = time();
161+
var lastFrame = start;
162+
var percent = 0;
163+
var dropCounter = 0;
164+
var id = counter++;
165+
166+
if (!root) {
167+
root = document.body;
168+
}
169+
170+
// Compacting running db automatically every few new animations
171+
if (id % 20 === 0) {
172+
var newRunning = {};
173+
for (var usedId in running) {
174+
newRunning[usedId] = true;
175+
}
176+
running = newRunning;
177+
}
178+
179+
// This is the internal step method which is called every few milliseconds
180+
var step = function(virtual) {
181+
182+
// Normalize virtual value
183+
var render = virtual !== true;
184+
185+
// Get current time
186+
var now = time();
187+
188+
// Verification is executed before next animation step
189+
if (!running[id] || (verifyCallback && !verifyCallback(id))) {
190+
191+
running[id] = null;
192+
completedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, false);
193+
return;
194+
195+
}
196+
197+
// For the current rendering to apply let's update omitted steps in memory.
198+
// This is important to bring internal state variables up-to-date with progress in time.
199+
if (render) {
200+
201+
var droppedFrames = Math.round((now - lastFrame) / (millisecondsPerSecond / desiredFrames)) - 1;
202+
for (var j = 0; j < Math.min(droppedFrames, 4); j++) {
203+
step(true);
204+
dropCounter++;
205+
}
206+
207+
}
208+
209+
// Compute percent value
210+
if (duration) {
211+
percent = (now - start) / duration;
212+
if (percent > 1) {
213+
percent = 1;
214+
}
215+
}
216+
217+
// Execute step callback, then...
218+
var value = easingMethod ? easingMethod(percent) : percent;
219+
if ((stepCallback(value, now, render) === false || percent === 1) && render) {
220+
running[id] = null;
221+
completedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, percent === 1 || duration == null);
222+
} else if (render) {
223+
lastFrame = now;
224+
core.effect.Animate.requestAnimationFrame(step, root);
225+
}
226+
};
227+
228+
// Mark as running
229+
running[id] = true;
230+
231+
// Init first step
232+
core.effect.Animate.requestAnimationFrame(step, root);
233+
234+
// Return unique animation ID
235+
return id;
236+
}
237+
};
238+
})(this);
239+

Diff for: cache_canvas_pool.js

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
(function(CL){
2+
var devicPixelRatio = window.devicPixelRatio;
3+
//缓存的canvas池
4+
var CacheCanvasPool = {
5+
init:function(opt){
6+
opt = opt || {};
7+
this.poolSize = opt.poolSize || 30;
8+
this.cacheCanvasList = [];
9+
},
10+
get:function(layer){
11+
var targetCache;
12+
var id = layer.id;
13+
14+
$.each(this.cacheCanvasList,function(i,cache){
15+
if(cache.id == id){
16+
targetCache = cache;
17+
return false;
18+
}
19+
});
20+
21+
22+
return targetCache;
23+
24+
},
25+
add:function(layer,isScrollingDown){
26+
27+
var cacheCanvasList = this.cacheCanvasList;
28+
var newCanvas;
29+
var newCache;
30+
31+
//如果超出了池子大小,拿最旧的来复用
32+
if(cacheCanvasList.length && (cacheCanvasList.length + 1 > this.poolSize)){
33+
console.log('reuse!');
34+
if(window.reused == null){
35+
window.reused = 0;
36+
}
37+
else{
38+
window.reused++;
39+
$('.reused-count').html(window.reused);
40+
}
41+
42+
var oldCache;
43+
//根据滚动方向,使用不同的复用缓存方案,避免导致缓存canvas循环使用不当导致的卡顿
44+
if(isScrollingDown){
45+
oldCache = cacheCanvasList.shift();
46+
}
47+
else{
48+
oldCache = cacheCanvasList.pop();
49+
}
50+
console.log(isScrollingDown);
51+
52+
newCanvas = oldCache.canvas;
53+
newCtx = oldCache.context;
54+
//清空原来内容后再用
55+
newCtx.clearRect(0,0,newCanvas[0].width,newCanvas[0].height);
56+
}
57+
else{
58+
newCanvas = $('<canvas></canvas>');
59+
newCtx = newCanvas[0].getContext('2d');
60+
}
61+
//缓存canvas和层的大小一致
62+
newCanvas.prop('width',layer.drawWidth * 2);
63+
newCanvas.prop('height',layer.drawHeight * 2);
64+
65+
newCache = {
66+
id:layer.id,
67+
canvas:newCanvas,
68+
context:newCtx
69+
};
70+
71+
if(isScrollingDown){
72+
//增加到列表并返回
73+
cacheCanvasList.push(newCache);
74+
}
75+
else{
76+
//增加到列表并返回
77+
cacheCanvasList.unshift(newCache);
78+
}
79+
80+
81+
82+
//test
83+
//$('body').append(newCanvas);
84+
85+
return newCache;
86+
87+
},
88+
remove:function(id){
89+
90+
this.cacheCanvasList = this.cacheCanvasList.filter(function(cache){
91+
//test
92+
// if(id == cache.id){
93+
// cache.canvas.remove();
94+
// }
95+
96+
return cache.id != id;
97+
});
98+
99+
100+
101+
}
102+
};
103+
104+
CL.CacheCanvasPool = CacheCanvasPool;
105+
106+
107+
})(window.CanvasList = window.CanvasList || {});

0 commit comments

Comments
 (0)