感謝akinuri我設法他的答案適應上requestanimationframe運行的動態功能。再次感謝akinuri,不錯的代碼。 PS:currentColor和targetColor請求與RGB值的字符串( 'RGB(0,0,0)')
function startColorFade(fps, duration, element, currentColor, targetColor) {
var stop = false;
var fpsInterval = 1000/fps;
var now;
var then = Date.now();
var elapsed;
var startTime = then;
var currentColorArray = getElementBG(currentColor);
var targetColorArray = getElementBG(targetColor);
var distance = calculateDistance(currentColorArray, targetColorArray);
var increment = calculateIncrement(distance, fps, duration);
animateColor(duration, element, currentColorArray, targetColorArray, increment, stop, fpsInterval, now, then, elapsed, startTime);
}
function animateColor(duration, element, currentColorArray, targetColorArray, increment, stop, fpsInterval, now, then, elapsed, startTime) {
var step = function() {
if (stop) {
return;
}
// request another frame
requestAnimationFrame(function() //arguments can passed on the callback by an anonymous funtion
{
animateColor(duration, element, currentColorArray, targetColorArray, increment, stop, fpsInterval, now, then, elapsed, startTime);
colorTransition(element, currentColorArray, targetColorArray, increment);
});
// calc elapsed time since last loop
now = Date.now();
elapsed = now - then;
// if enough time has elapsed, draw the next frame
if (elapsed > fpsInterval) {
// Get ready for next frame by setting then=now, but...
// Also, adjust for fpsInterval not being multiple of 16.67
then = now - (elapsed % fpsInterval);
// draw stuff here
var sinceStart = now - startTime;
}
if (sinceStart/1000 * 100 >= duration * 100)
{
stop = true;
}
}
step();
}
function colorTransition(element, currentColorArray, targetColorArray, increment) {
// checking R
if (currentColorArray[0] > targetColorArray[0]) {
currentColorArray[0] -= increment[0];
if (currentColorArray[0] <= targetColorArray[0]) {
increment[0] = 0;
}
} else {
currentColorArray[0] += increment[0];
if (currentColorArray[0] >= targetColorArray[0]) {
increment[0] = 0;
}
}
// checking G
if (currentColorArray[1] > targetColorArray[1]) {
currentColorArray[1] -= increment[1];
if (currentColorArray[1] <= targetColorArray[1]) {
increment[1] = 0;
}
} else {
currentColorArray[1] += increment[1];
if (currentColorArray[1] >= targetColorArray[1]) {
increment[1] = 0;
}
}
// checking B
if (currentColorArray[2] > targetColorArray[2]) {
currentColorArray[2] -= increment[2];
if (currentColorArray[2] <= targetColorArray[2]) {
increment[2] = 0;
}
} else {
currentColorArray[2] += increment[2];
if (currentColorArray[2] >= targetColorArray[2]) {
increment[2] = 0;
}
}
// apply the new modified color
element.style.backgroundColor = rgb2hex(currentColorArray);
}
function getElementBG(elmBGColor) {
var bg = elmBGColor; // i.e: RGB(255, 0, 0)
bg = bg.match(/\((.*)\)/)[1];
bg = bg.split(",");
for (var i = 0; i < bg.length; i++) {
bg[i] = parseInt(bg[i], 10);
}
if (bg.length > 3) { bg.pop(); }
return bg; // return array
}
function calculateDistance(colorArray1, colorArray2) {
var distance = [];
for (var i = 0; i < colorArray1.length; i++) {
distance.push(Math.abs(colorArray1[i] - colorArray2[i]));
}
return distance;
}
function calculateIncrement(distanceArray, fps, duration) {
var increment = [];
for (var i = 0; i < distanceArray.length; i++) {
increment.push(Math.abs(Math.floor(distanceArray[i]/(fps * duration))));
if (increment[i] == 0) {
increment[i]++;
}
}
return increment;
}
function rgb2hex(colorArray) {
var hex = [];
for (var i = 0; i < colorArray.length; i++) {
hex.push(colorArray[i].toString(16));
if (hex[i].length < 2) { hex[i] = "0" + hex[i]; }
}
return "#" + hex.join("");
}
//random rgb values in array, very nice
function generateRGB(min, max) {
var min = min || 0;
var max = max || 255;
var color = [];
for (var i = 0; i < 3; i++) {
var num = Math.floor(Math.random() * max);
while (num < min) {
num = Math.floor(Math.random() * max);
}
color.push(num);
}
return color;
}
請說明您的具體問題或添加額外的細節,突顯正是你需要的。正如目前所寫,很難確切地說出你在問什麼。 – Marcin
試圖更具體。它應該做的。我猜。 – akinuri
注意 - 你有一個失控的'setInterval'循環,你在'switchColor'裏面啓動一個新的100ms定時器,並且永遠不會取消它 - 每個2s你再做一次... – Alnitak