Отказ от ответственности: Графические и модельные материалы, использованные в этой статье, предназначены только для личного изучения, исследования и оценки. Пожалуйста, не переделывайте, не распространяйте незаконно, не перепечатывайте, не публикуйте, не коммерциализируйте и не занимайтесь другой деятельностью, направленной на извлечение прибыли.
Справочная информация
Если вы играли в 🎮
《King of Glory》
, 《Onmyoji》
и другие мобильные игры, вы наверняка заметили анимацию запуска, вертикальную прорисовку карт и другие сцены, часто использующие статическую простую анимацию базового изображения и локальный эффект потока жидкости. Такие анимации потока могут проявляться в медленно текущем потоке воды 🌊
, развевающемся на ветру флаге 🎏
, рукаве игрового персонажа 🧜♀️
, погодных эффектах облаков, дождя, тумана, замедляющихся со временем ⛅
и т.д. Этот эффект перехода не только экономит затраты на разработку полномасштабной анимации, но и делает игровой экран более восторженным, авантюрным, 💰
и продвинутым, а также легче привлекает игроков.
В данной статье используется технология front-end разработки в сочетании с SVG
и CSS
для достижения подобного эффекта разжижения потока. Знания в этой статье: mask-image
、 feTurbulence
feDisplacementMap
、 filter
、 canvas
метод рисования, TimelineMax
анимация и input[type=file]
локальная загрузка ресурсов изображения и т.д.
Эффект
Давайте сначала рассмотрим эффект реализации. Все следующие примеры и рисунок баннера статьи 👆
применяются с эффектом анимации потока жидкости, созданным содержимым этой статьи. Поскольку GIF
сжатие изображения серьезное, эффект анимации не выглядит очень гладким 🙃
, вы можете испытать эффект самостоятельно через следующую ссылку демо-страницы и создать свой собственный легенду
, коллекцию
Skin vertical painting 😅
.
🌀
Рассеивание тумана The Legend of Zelda: Breath of the Wild
.
💃
Порхание Diao Chan: Призрачный танец кошачьей тени
🌅
Волна Хугуанг
🔠
Текстовое сжижение
📌
Советы: страница опыта развертывается в Gitpage функция загрузки изображения на самом деле не загружается на сервер, но только будет загружен в браузер локально, страница не будет получать никакой информации, вы можете испытать его с уверенностью, не беспокойтесь об утечке конфиденциальности.
Codepen
Посмотреть перо
paint-heat-map by dragonir (@dragonir)
на CodePen.
Accomplish
Страница в основном состоит из 2
частей, верхняя используется для загрузки изображения, и вы можете нарисовать путь горячей точки, нажав 🖱
проведите мышью, чтобы добавить эффект потока к изображению; внизу находится область управления, нажмите кнопку 🔘
清除画布, вы можете очистить нарисованный эффект текучей анимации, нажмите кнопку 🔘
切换图片 для загрузки локального изображения.
📌
Примечание, есть также невидимая функция, когда вы закончите рисовать, вы можете нажать🖱
правой кнопкой мыши, а затем выбрать сохранить изображение, сохраненное изображение является путь мы рисуем анимацию жидкости Используя эту тепловую карту и используя знанияCSS
в этой статье, вы можете преобразовать статические изображения в динамические изображения!
Структура HTML-страницы
Элемент #sketch
в основном используется для рисования и загрузки чертежной доски тепловой карты эффекта потока; #button_container
— область управления кнопками в нижней части страницы; элемент svg
фильтра filter
Фильтры для достижения эффектов анимации потока жидкости, включая фильтры feTurbulence
и feDisplacementMap
.
<main id="sketch">
<canvas id="canvas" data-img=""></canvas>
<div class="mask">
<div id="maskInner" class="mask-inner"></div>
</div>
</main>
<section class="button_container">
<button class="button">清除画布</button>
<button class="button"><input class="input" type="file" id="upload">上传图片</button>
</section>
<svg>
<filter id="heat" filterUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<feTurbulence id="heatturb" type="fractalNoise" numOctaves="1" seed="2" />
<feDisplacementMap xChannelSelector="G" yChannelSelector="B" scale="22" in="SourceGraphic" />
</filter>
</svg>
💡 feTurbulence и feDisplacementMap
- feTurbulence : Фильтр использует функцию шума
Perlin
для создания изображения, которое может быть использовано для имитации искусственных текстур, таких как муар и мрамор. - feDisplacementMap : Фильтр смещения карты, который заменяет значения пикселей из in в пространство
in
изображения на значения пикселей изin2
в пространство из изображения. То есть, он может изменять пиксельное положение элементов и графики. Обходя все пиксели исходной графики,feDisplacementMap
переставляет и заменяет новую позицию для формирования новой графики. Основное применение этого фильтра в промышленности — деформация, искажение и разжижение графики.
Стили CSS
Далее рассмотрим реализацию стиля, элемент main
в качестве основного контейнера и основной шаблон в качестве фонового изображения; canvas
в качестве холста, занимающего пространство 100%
; .mask
и .mask-inner
используются для создания эффекта контура горячей точки и фонового изображения, как показано ниже, что достигается с помощью mask-image
. Наконец, для генерации эффекта динамического потока, .mask-inner
передают filter:url(#heat)
ранее сгенерированный svg в качестве источника фильтра, а последующие действия будут на JavaScript
Постоянно изменяя свойства фильтра svg
, генерируется анимация потока жидкости.
main {
position: relative;
background-image: url('bg.jpg');
background-size: cover;
background-position: 100% 50%;
}
canvas {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
mask-mode: luminance;
mask-size: 100% 100%;
backdrop-filter: hard-light;
mask-image: url('mask.png');
}
.mask-inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('bg.jpg') 0% 0% repeat;
background-size: cover;
background-position: 100% 50%;
filter: url(#heat);
mask-image: url('mask.png')
}
💡 маска-изображение
Атрибут mask-image
CSS
используется для задания изображения слоя маски на элементе.
Синтаксис
// The default, a transparent black image layer, i.e. no mask layer.
mask-image: none;
// <mask-source><mask> or CSS image url
mask-image: url(masks.svg#mask1);
// <image> image as mask
mask-image: linear-gradient(rgba(0, 0, 0, 1.0), transparent);
mask-image: image(url(mask.png), skyblue);
// multiple values
mask-image: image(url(mask.png), skyblue), linear-gradient(rgba(0, 0, 0, 1.0), transparent);
// global value
mask-image: inherit;
mask-image: initial;
mask-image: unset;
Совместимость :
⚡ Эта функция все еще находится в стадии разработки в некоторых браузерах и требует
browser prefix
для совместимости с различными браузерами.
Методы JavaScript
① Построение тепловой карты
Слушайте события движения мыши и щелчка и рисуйте «горячие точки» волнового пути на canvas
.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var sketch = document.getElementById('sketch');
var sketchStyle = window.getComputedStyle(sketch);
var mouse = { x: 0, y: 0 };
canvas.width = parseInt(sketchStyle.getPropertyValue('width'));
canvas.height = parseInt(sketchStyle.getPropertyValue('height'));
canvas.addEventListener('mousemove', e => {
mouse.x = e.pageX - canvas.getBoundingClientRect().left;
mouse.y = e.pageY - canvas.getBoundingClientRect().top;
}, false);
ctx.lineWidth = 40;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';
canvas.addEventListener('mousedown', () => {
ctx.beginPath();
ctx.moveTo(mouse.x, mouse.y);
canvas.addEventListener('mousemove', onPaint, false);
}, false);
canvas.addEventListener('mouseup', () => {
canvas.removeEventListener('mousemove', onPaint, false);
}, false);
var onPaint = () => {
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
var url = canvas.toDataURL();
document.querySelectorAll('div').forEach(item => {
item.style.cssText += `
display: initial;
-webkit-mask-image: url(${url});
mask-image: url(${url});
`;
});
};
После завершения рисования вы можете щелкнуть правой кнопкой мыши на странице, чтобы сохранить сгенерированную тепловую карту волнового пути, и непосредственно поместить тепловую карту, которая вас устраивает, в CSS
, вы можете добавить локальный волновой эффект к понравившемуся изображению, как показано ниже Изображение представляет собой колеблющуюся карту теплового пути, используемую на этой странице.
② Генерирование анимации
Для генерации обновляемого в реальном времени эффекта волны в этой статье используется TweenMax
для достижения той же функции путем изменения значения свойства baseFrequency
свойства feTurbulence
, вы также можете использовать другие библиотеки анимации или с помощью requestAnimationFrame
.
feTurb = document.querySelector('#heatturb');
var timeline = new TimelineMax({
repeat: -1,
yoyo: true
}),
timeline.add(
new TweenMax.to(feTurb, 8, {
onUpdate: () => {
var bfX = this.progress() * 0.01 + 0.025,
bfY = this.progress() * 0.003 + 0.01,
bfStr = bfX.toString() + ' ' + bfY.toString();
feTurb.setAttribute('baseFrequency', bfStr);
}
}),
0);
③ Очистите холст
Нажмите кнопку 清除画布
, чтобы очистить нарисованный волновой путь, в основном очищая значение атрибута элемента страницы mask-image
и очищая canvas
.
function clear() {
document.querySelectorAll('div').forEach(item => {
item.style.cssText += `
display: none;
-webkit-mask-image: none;
mask-image: none;
`;
});
}
document.querySelectorAll('.button').forEach(item => {
item.addEventListener('click', () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
clear();
})
});
④ Переключение изображений
Нажмите для переключения изображения, вы можете загрузить локальное изображение в качестве базовой карты рисунка, эта функция заключается в получении ресурса изображения через input[type=file]
, а затем установить его на новый, изменив CSS
Canvas background.
document.getElementById('upload').onchange = function () {
var imageFile = this.files[0];
var newImg = window.URL.createObjectURL(imageFile);
clear();
document.getElementById('sketch').style.cssText += `
background: url(${newImg});
background-size: cover;
background-position: center;
`;
document.getElementById('maskInner').style.cssText += `
background: url(${newImg});
background-size: cover;
background-position: center;
`;
};
На данном этапе все функции реализованы. Давайте сделаем стартовую страницу вашего любимого скина волны или мини-игры Odyssey таким способом 🤣 .
📥 Адрес источника: https://github.com/dragonir/paint-heat-map
Резюме:
Знания, включенные в эту статью, в основном включают в себя:
Если вы хотите узнать другие знания о front-end или другие знания, которые не описаны подробно в этой статье, связанные с технологией разработки Web 3D, вы можете прочитать мои предыдущие статьи. Пожалуйста, при перепечатке указывайте адрес и автора оригинала. Если вы считаете статью полезной для вас, не забывайте следить за мной 👍 .
Приложение
- Моя 3D колонка доступна по этой ссылке 👈
- [1]. 🌐 Используйте Three.js для создания крутого 3D экрана цифровой земли в стиле киберпанк
- [2]. 🦊 Three.js реализует 3D-игру с открытым миром: Мультивселенная Али (Ali’s multiverse)
- [3]. 🔥 Three.js создает эффект пламени для реализации динамичного логотипа «Кольцо Аэрдена
- [4]. 🐼 Three.js реализует 3D-страницу развлечений на тему зимних Олимпийских игр 2022 года, включая «Бинг Дун Дун
...
- [1]. 📷 Во front-end реализована очень впечатляющая функция сканирования на стороне браузера (browser-side scanning)
- [2]. 🌏 The Legend of Zelda: Breath of the Wild (Легенда о Зельде: Дыхание дикой природы)
- [3]. 😱 Реализация визуальных эффектов в стиле cyberpunk 2077 с помощью CSS всего за несколько шагов
...
смотрите
- [1]. https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/feTurbulence
- [2]. https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/feDisplacementMap
- [3]. https://developer.mozilla.org/zh-CN/docs/Web/CSS/mask-image
- [4]. https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter