1

C4D搭配椭圆动态及闪动控制动画效果

 1 year ago
source link: https://blog.51cto.com/u_15345191/5701987
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、椭圆运动函数

先了解一下椭圆运动函数 circleRunEllipse 整体,主要使用函数:

/**
* 首页运维与服务背景图动画
* @param canvasID 画布ID
* @param ellipseHeight 椭圆运动高度
* @param ellipseWidth 椭圆运动宽度
* @param type 哪一个圈,大、中、小--【1 | 2 | 3】
*/
export function circleRunEllipse(canvasID, ellipseHeight, ellipseWidth, type) {
// 基础变量
let canvas: any;
if (document.getElementById(canvasID)) {
canvas = document.getElementById(canvasID);
} else {
return ;
}
let context = canvas.getContext('2d');
let width = canvas.width = 469;
let height = canvas.height = 1017;
let animationFrame = null; // 记录执行的动画,用于取消


// 椭圆运动
let circleX = width / 2 - 127; // 椭圆运动中心点
let circleY = height / 2;
let ellipseA = ellipseWidth; // 长轴a
let ellipseB = ellipseHeight; // 短轴b
let speed = 0.012; // 控制运动速度
let ellipseTime = 0; // 控制运动时间变化


/**
* 椭圆运动执行
*/
function ellipseRun() {
if (animationFrame) {
window.cancelAnimationFrame(animationFrame);
}
animationFrame = window.requestAnimationFrame(ellipseRun);
context.clearRect(0, 0, width, height);

// drawEllipse(circleX, circleY);
drawCircle(circleX + ellipseA * Math.cos(ellipseTime), circleY + ellipseB * Math.sin(ellipseTime));
if (type === 1) {
context.clearRect(0, 80, 35, 55); // 右侧点(25,80),高宽
context.clearRect(0, 880, 10, 5); // 左侧点(0,885)

// 结束点21.09
ellipseTime += speed;
if (ellipseTime > 21.09) {
if (!clearAnimationFrame()) {
document.getElementsByClassName('service-cloud1')[0].className += ' service-cloud';
document.getElementsByClassName('service-cloud4')[0].className = 'service-cloud4';
} else {
return ;
}
ellipseTime = 16.8;
clearRun(5);
}
} else if (type === 2) {
context.clearRect(0, 720, 210, 200); // 左侧点(208,720),高宽
context.clearRect(0, 308, 20, 415); // 右侧点(2,308),高宽

// 结束点16.29
ellipseTime -= speed;
if (ellipseTime < 16.29) {
if (!clearAnimationFrame()) {
document.getElementsByClassName('service-cloud2')[0].className = 'service-cloud2';
} else {
return ;
}
ellipseTime = 19.45;
clearRun(5);
}
} else {
context.clearRect(0, 300, 43, 400); // 左侧点(40,700),高宽
context.clearRect(0, 0, 175, 307); // 右侧点(175,305),高宽

context.clearRect(142, 716, 30, 62); // 服务器右侧点(142,778),高宽,左侧点(169,716)

// 结束点18.08
ellipseTime -= speed;
if (ellipseTime < 18.08) {
if (!clearAnimationFrame()) {
document.getElementsByClassName('service-cloud3')[0].className += ' service-cloud';
} else {
return ;
}
ellipseTime = 21.24;
clearRun(5);
}
}
}


/**
* 画实体圆,描述位置
*/
function drawCircle(x, y) {
context.save();
context.fillStyle = '#0ff';
context.globalAlpha = 0.92;
context.beginPath();
context.arc(x, y, 3.5, 0, Math.PI * 2); // 半径3
context.closePath();
context.fill();
context.restore();
}


/**
* 画椭圆,用于匹配设计稿路径
* 1、画椭圆,使用lineTo,把椭圆分割许多片段
* 2、椭圆的三角函数表达式 x = a*cos(t), y = b * sin(t);
*/
function drawEllipse(x, y) {
// 这样可以使得每次循环所绘制的路径(弧线)接近1像素
let step = (ellipseA > ellipseB) ? 1 / ellipseA : 1 / ellipseB;
context.save();
context.strokeStyle = 'blue';
context.beginPath();
context.moveTo(x + ellipseA, y);
for (let i = 0; i < Math.PI * 2; i += step) {
context.lineTo(x + ellipseA * Math.cos(i), y + ellipseB * Math.sin(i));
}
context.closePath();
context.stroke();
context.restore();
}


/**
* 定点,用于消除隐藏多余路径
*/
function drawPoint(x, y) {
context.save();
context.fillStyle = 'red';
context.globalAlpha = 0.95;
context.beginPath();
context.arc(x, y, 3, 0, Math.PI * 2);
context.closePath();
context.fill();
context.restore();
}


/**
* 停止运动
* @param time 时间,单位【秒】
*/
function clearRun(time) {
context.clearRect(0, 0, width, height);
window.cancelAnimationFrame(animationFrame);

let timer = null;

// 提前一秒执行闪动动画
let restartTimer = setTimeout(function() {
if (clearAnimationFrame()) {
clearTimeout(restartTimer);
clearTimeout(timer);
return ;
}

if (type === 1) {
document.getElementsByClassName('service-cloud1')[0].className = 'service-cloud1';
document.getElementsByClassName('service-cloud4')[0].className += ' service-cloud';
} else if (type === 2) {
document.getElementsByClassName('service-cloud2')[0].className += ' service-cloud';
} else {
document.getElementsByClassName('service-cloud3')[0].className = 'service-cloud3';
}
clearTimeout(restartTimer);
}, (time - 1) * 1000);

timer = setTimeout(function() {
animationFrame = window.requestAnimationFrame(ellipseRun);
clearTimeout(timer);
}, time * 1000);
}


/**
* 清除运动
*/
function clearAnimationFrame() { ... }


// 指定开始点执行椭圆运动
if (type === 1) {
ellipseTime = 16.8;
// ellipseTime = 21.09; // 结束点
if (document.getElementsByClassName('service-cloud4').length > 0) {
document.getElementsByClassName('service-cloud4')[0].className += ' service-cloud';
}
} else if (type === 2) {
ellipseTime = 19.45;
// ellipseTime = 16.29; // 结束点
if (document.getElementsByClassName('service-cloud2').length > 0) {
document.getElementsByClassName('service-cloud2')[0].className += ' service-cloud';
}
} else if (type === 3) {
ellipseTime = 21.24;
// ellipseTime = 18.08; // 结束点
}
let startTimer = setTimeout(function() {
animationFrame = ellipseRun();
clearTimeout(startTimer);
}, 1000);
}


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK