Я хотел бы поделиться с вами эффектом на картинке ниже, который я недавно реализовал.
Если мы хотим нарисовать анимацию кривой ниже
Если вы каждый раз рисуете короткую линию для соединения, изображение ниже разделится на пять сегментов.
Прочитайте еще десять абзацев
Если количества разделенных сегментов достаточно, рисование одного сегмента за раз будет выглядеть как изогнутая траектория.
квадратичная кривая Безье/** * Анимация квадратичной кривой Безье* @param {Array<number>} координаты начальной начальной точки* @param {Array<number>} координаты точки кривизны (то есть точка поворота, а не точные координаты, только приблизительное направление) * @param {Array<number>} Координаты конечной точки * @param {number} процент отрисовки процентов (0–100) */ function drawCurvePath(start, point, end, процент){ ctx.beginPath(); //Начинаем рисовать линии ctx.moveTo(start[0], start[1]); //Перемещаем перо в начальную точку for (var t = 0; t <= процент / 100; t += 0.005 ) { //Получаем координаты каждой временной точки var x =квадратичныйBezier(start[0],point[0],end[0],tvar y =); quadaticBezier(start[1], point[1], end[1], t); ctx.lineTo(x, y); //Рисуем прямую линию от предыдущей точки времени до текущей точки времени} ctx.stroke( ); //Обводка} /** * Уравнение квадратичной кривой Безье* @param {Array<number>} start start point* @param {Array<number>} точка кривизны* @param {Array<number>} end end point * @param {число} прогресс рисования (0-1) */ functionquadaticBezier(p0, p1, p2, t) { var k = 1 - t; return k * k * p0 + 2 * (1 - t) * t * р1 + т * т * р2 }
Более подробную информацию о кривой Безье можно найти в этом блоге.
в полный код
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, Initial-scale=1.0> <meta http-equiv=X-UA -Compatible content=ie=edge> <title>Анимация квадратичной кривой Безье</title> <style> body { background: #0f1632 } #canvas { border: 1px Solid #ccc; } #img { display: none; <!--Просто скройте изображение, оно будет помещено в кавычки позже --> } </style></head><body> <canvas id=canvas width =1500 высота =750></canvas> <img id=img src=https://s3.imgsha.com/2019/04/22/light.png> <script> var ctx = document.getElementById('canvas').getContext('2d'); var img = document.getElementById('img'); var процент = 0; var data = { start: [400, 200], точка: [ 300, 100], конец: [100, 400], отдел: 'данные 1', значение: 4321 } функция init(){ процент = 0; //Сбрасываем процесс каждый раз draw(); } function draw(){ ctx.clearRect(0, 0, 1500, 750); //Очищаем холст каждый раз ctx.strokeStyle = ' # ffffff'; //Установим стиль линии drawCurvePath(data.start, data.point, data.end, процент); //По мере увеличения процесса это контролирует скорость анимации if (percent <=) 100) { //Продолжить вызов, если рисование не завершено. Если рисование завершено, прогресс будет сброшен requestAnimationFrame(draw); }else{ init() } } function drawCurvePath(start, point, end, процент) / /... } functionquadaticBezier( p0, p1, p2, t) { //... } </script></body></html>
анимация выходит
Как упоминалось ранее, параметр point
в функции drawCurvePath(start, point, end, percent)
— это не конкретная точка кривизны, а общее направление.
Давайте посмотрим на ситуацию, когда point
меняется на [200,200]
Если вы хотите добиться эффекта падения, вам нужно добавить к линии эффект градиента от верха к низу, от дальнего к ближнему.
/** * Создание линейного градиента* @param {Array<number>} start start point* @param {Array<number>} точка кривизны* @param {Array<number>} end end point* @param {number} Drawing прогресс (0-1) */function createLinearGradient(start,end,startColor,endColor){ var lineGradient = ctx.createLinearGradient(...start, ...end); lineGradient.addColorStop(0, startColor); // lineGradient.addColorStop(0.3, '#fff'); lineGradient.addColorStop(1, endColor); return lineGradient}//Функция рисования нуждается в некоторых корректировках function draw(){ // ctx.strokeStyle = '#ffffff'; ctx.strokeStyle = createLinearGradient(data.start, data.end, 'rgba(255,255,255,.2)', '#fff' ); //...}
Подробную информацию о градиенте холста см. на MDN.
Головной ореол Чтобы добавить ореол на голове, вам нужно нарисовать круг и установить радиальный градиент. Используйте функцию drawCurvePath
, чтобы получить значения x, y и сбросить положение круга.
function createHeadLight(x,y){ ctx.beginPath(); //Создаем радиальный градиент var radiusGradient = ctx.createRadialGradient(x, y, 0, x, y, 20); radiusGradient.addColorStop(0, rgba(255,255,255, 1); )); радиальныйGradient.addColorStop(.2, rgba(255,255,255,.8)); radiusGradient.addColorStop(1, Transparent); ctx.fillStyle = radiusGradient; //Рисуем круг ctx.arc(x, y, 20, 0, 2 * Математика .PI, ложь); ctx.fill();}//Функция drawCurvePath нуждается в некоторых корректировках function drawCurvePath(start, point, end, процент) { //... ctx.stroke(); // Обводка createHeadLight(x,y) // Draw круг, как рисование частоты линии}
Подробную информацию arc
для рисования окружностей можно найти в MDN.
Добавление текста очень похоже на добавление ореола головы. Оба используют функцию drawCurvePath
для получения x, y и сброса положения текстового блока.
/** * Создать текст* @param {String} данные отдела* @param {Number} data* @param {Number} координата оси X* @param {Number} координата оси Y*/function drawText(department, value, x, y) { ctx.fillStyle = '#fff' ctx.font = 22px Microsoft Yahei; ctx.fillText(department, x + 30, y + 20); //Чтобы сделать текст в правом нижнем углу ореола x, ось y нужно сместить на некоторое расстояние var width = ctx.measureText(value).width //Получаем ширину; текста ctx.fillStyle = createLinearGradient([x + 30, 0], //Диапазон отрисовки текстового градиента по оси X: [x+30,x+30+ширина текста], [x + 30 + ширина, 0], //Здесь y установлен в 0, так как API для получения высоты текста не существует. Также допускается запись 0 '#fffd00', '#ff6d00' ); ctx.fillText(value.toLocaleString(), x + 30, y +); 50 ); } //Функция drawCurvePath нуждается в некоторых корректировках function drawCurvePath(start, point, end, процент, отдел, значение) { //... createHeadLight(x,y) drawText(отдел, значение, x, y) }Добавьте текст и изображения в конечное положение после завершения анимации.
Обратите внимание, что при добавлении текста и картинок после завершения анимации необходимо очистить холст сразу после завершения анимации кривой, а затем уже добавлять текст и картинки.
/** * Создать изображение* @param {Number} координата оси X* @param {Number} координата оси Y*/function drawImg(x, y) { ctx.drawImage(img, x - img.width / 2, y - img.height); }//Функция рисования нуждается в некоторых корректировках draw(){ //... if (percent <= 100) { requestAnimationFrame(draw); }else{ ctx.clearRect(0, 0, 1500, 750); // Очищаем холст сразу после завершения анимации кривой drawText(data.department, // Отображаем текст data.value, data.end[0], data .end[1 ]) drawImg(data.end[0], data.end[1]) //Отрисовка изображения setTimeout(function(){ //Перерисовка init() через 2000 мс },2000) } }Заканчивать
Полный код этого примера
Полный код примера на первой картинке статьи
Справочная статья: Использование холста для рисования анимации кривой — углубленное понимание кривых Безье
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.