二次貝塞爾曲線
公式:
實(shí)現(xiàn)墜落效果:
代碼如下:
const c = document.getElementById("myCanvas");
? ? ? const ctx = c.getContext("2d");
? ? ? let percent = 0;
? ? ? const data = {
? ? ? ? start: [400, 200],
? ? ? ? point: [300, 100],
? ? ? ? end: [100, 400],
? ? ? ? department: "數(shù)據(jù)1",
? ? ? ? value: 4321
? ? ? };
? ? ? function init() {
? ? ? ? percent = 0; //每次重置進(jìn)程
? ? ? ? draw();
? ? ? }
? ? ? function draw() {
? ? ? ? ctx.clearRect(0, 0, c.width, c.height); //每次清除畫布
? ? ? ? ctx.fillStyle = "#000";
? ? ? ? ctx.fillRect(0, 0, c.width, c.height);
? ? ? ? //設(shè)置線條樣式
? ? ? ? ctx.strokeStyle = createLinearGradient(
? ? ? ? ? data.start,
? ? ? ? ? data.end,
? ? ? ? ? "#fff",
? ? ? ? ? "rgba(255,255,255,.3)"
? ? ? ? );
? ? ? ? drawCurvePath(data.start, data.point, data.end, percent);
? ? ? ? percent += 0.8; //進(jìn)程增加,這個(gè)控制動(dòng)畫速度
? ? ? ? if (percent <= 100) {
? ? ? ? ? //沒(méi)有畫完接著調(diào)用,畫完的話重置進(jìn)度
? ? ? ? ? requestAnimationFrame(draw);
? ? ? ? } else {
? ? ? ? ? init();
? ? ? ? }
? ? ? }
? ? ? function quadraticBezier(p0, p1, p2, t) {
? ? ? ? const k = 1 - t;
? ? ? ? return k * k * p0 + 2 * k * t * p1 + t * t * p2;
? ? ? }
? ? ? function drawCurvePath(start, point, end, percent) {
? ? ? ? ctx.beginPath(); //開(kāi)始畫線
? ? ? ? ctx.moveTo(start[0], start[1]); //畫筆移動(dòng)到起點(diǎn)
? ? ? ? for (let t = 0; t <= percent / 100; t += 0.005) {
? ? ? ? ? //獲取每個(gè)時(shí)間點(diǎn)的坐標(biāo)
? ? ? ? ? const x = quadraticBezier(start[0], point[0], end[0], t);
? ? ? ? ? const y = quadraticBezier(start[1], point[1], end[1], t);
? ? ? ? ? ctx.lineTo(x, y); //畫出上個(gè)時(shí)間點(diǎn)到當(dāng)前時(shí)間點(diǎn)的直線
? ? ? ? }
? ? ? ? ctx.stroke(); //描邊
? ? ? }
? ? ? // 線性漸變
? ? ? function createLinearGradient(start, end, startColor, endColor) {
? ? ? ? const lineGradient = ctx.createLinearGradient(...start, ...end);
? ? ? ? lineGradient.addColorStop(0, startColor);
? ? ? ? lineGradient.addColorStop(1, endColor);
? ? ? ? return lineGradient;
? ? ? }
? ? ? draw();