В последнее время я был настолько одержим The Legend of Zelda: Breath of the Wild на Nintendo Switch, что колонка вот-вот прекратится (грех, грех). Наверное, у каждого игрока Zelda возникнет этот вопрос, т.Почему эта игра такая веселая? !Очень интересно, что ответ на этот вопрос, кажется,Почему интерфейс так меняется с каждым днем?«Это тонкие отношения, и это дало мне некоторые новые идеи…
В игровом опыте Zelda есть одна вещь, которая хорошо принята, и этоИнтуитивно понятный открытый мир. Другими словами, в этой игреЕсли вы хотите что-то сделать, пока вы можете придумать любой способ, вы можете почти достичь этого, основываясь на этом пути.. Например, если вы видите, что на дереве висит яблоко, то вы хотите сорвать это яблоко, по крайней мере, следующими способами:
- Сруби дерево и собери яблоко
- Заберитесь на дерево, покатайтесь на лошади или принесите ящик, чтобы добраться до яблок.
- Сбить яблоко из лука и стрел
- Вентилятор или бомба создают ударную волну, которая сносит яблоко.
- Скользите с окрестных гор к яблоням
- Поджечь дерево и оставить печеные яблоки
- ...
Эта степень свободы делает приключенческий опыт игры полным сюрпризов. Для всевозможных хитрых механических головоломок решения часто открыты и не уникальны. Так совпало, что моя недавняя работа как-то связана с использованием различных механизмов рендеринга во внешнем интерфейсе.При оценке браузера со степенью свободы вы можете увидеть почти открытый мир уровня Zelda.
Возьмем в качестве примера треугольник. Треугольник — простейшая геометрическая фигура, и нарисовать его не составит труда любому фронтовику. Но сколько существует технических решений для рисования треугольника в сегодняшней области фронтенда? Можно сказать, что ответ очень цветущий. Давайте начнем шаг за шагом. Следующие различные упражнения можно разделить на три типа в зависимости от степени подбрасывания:
- 2B Play
- Нормальная игра
- Позорная игра
2B Play
Сначала давайте начнем с наименее простого способа стать мошенником:
персонаж
Что может быть лучше, чем скопировать-вставить один△Как насчет более простого способа рисования персонажей? На самом деле это'\u25b3'Только специальные символы Юникода.
картина
выглядит<img src="三角形.jpg"/>Рутины очень мало, но в этом нет ничего плохого 🙄
HTML
Просто вертикально центрируйте серию прямоугольников равномерно растущей ширины, не получится треугольник 😅
<div class="triangle">
<div style="width: 1px; height: 1px;"></div>
<div style="width: 2px; height: 1px;"></div>
<div style="width: 3px; height: 1px;"></div>
<div style="width: 4px; height: 1px;"></div>
<!-- ...... -->
</div>
Нормальная игра
Если приведенная выше реализация кажется слишком циничной, то мы можем использовать несколько «обычных» операций, чтобы нарисовать тот же треугольник:
CSS
В CSS полно хитростей и уловок, и следующая операция может стать стандартным ответом на многие вопросы на собеседовании. Все, что нам нужно, это простой HTML:
<div class="triangle"></div>
Подберите стиль границы волшебного контейнера:
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
Можно смоделировать треугольник.Demo
Icon Font
Практика использования шрифтов в качестве иконок также является возвратом. Просто конфигурация стиля шрифта примерно такая:
@font-face {
font-family: Triangle;
src: url(./triangle.woff) format("woff");
}
.triangle:before { content:"\t666" }
такой<i class="triangle"></i>теги, вы можете пройти:beforeВставьте специальные символы, а затем отобразите соответствующий шрифт значка 😑Demo
SVG
Много раз мы привыкли напрямую представлять и использовать SVG в качестве статического ресурса, такого как изображение, но на самом деле, пока вы немного понимаете его синтаксис, вы обнаружите, что рисовать простую графику непосредственно рукописным SVG несложно:
<svg width="100" height="100">
<polygon points="50,0 100,100 0,100" style="fill: red;"/>
</svg>
Clip Path
SVG и CSS имеют много общего, но CSS, хотя и длиннее стилей, уже давно лишен возможности «рисовать форму». К счастью, clip path, недавно добавленный в спецификацию CSS, позволяет нам рисовать больше фигур в форме, похожей на SVG. Это просто должно выглядеть так:
.triangle {
width: 10px; height: 10px;
background: red;
clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
Чем это отличается от знакомой пограничной рутины? В дополнение к более интуитивно понятному и лаконичному коду, он также может поддерживать атрибут фонового изображения для нарисованной фигуры, но, к сожалению, он в основном совместим с IE.Demo
Canvas
Ни один из методов до сих пор не требовал написания JS-кода, что немного обидно. К счастью, у нас есть Canvas, от которого можно отказаться. просто нужен один<canvas>Этикетка сопоставляется с кодом клея следующим образом:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.fillStyle = 'red'
ctx.moveTo(50, 0)
ctx.lineTo(0, 100)
ctx.lineTo(100, 100)
ctx.fill()
Позорная игра
Если вы все еще считаете, что описанная выше операция слишком обычная, давайте воспользуемся несколькими последними методами, чтобы изучить свободный масштаб браузера:
CSS Houdini
Можно сказать, что на недавней конференции CSS CSS Houdini заслужил достаточно внимания. В этом наборе спецификаций, которые значительно расширяют возможности управления CSS, основной реализованной является CSS Paint. Короче говоря, с помощью этого API вы можете программно управлять процессом рендеринга изображения через холст везде, где свойство CSS требует изображения.
пройти черезCSS.paintWorklet.addModuleAPI, мы можем определить ворклет рисования, используемый для рисования холста:
<script>
CSS.paintWorklet.addModule('/worklet.js')
</script>
Обычный контекст холста можно получить в рабочей программе Paint:
class TrianglePainter {
paint(ctx, geom, properties) {
const offset = geom.width
ctx.beginPath()
ctx.fillStyle = 'red'
ctx.moveTo(offset / 2, 0)
ctx.lineTo(offset, offset)
ctx.lineTo(0, offset)
ctx.fill()
}
}
registerPaint('triangle', TrianglePainter)
Пока это так, его можно использовать в CSS.paintПравила таковы:
.demo {
width: 100px;
height: 100px;
background-image: paint(triangle);
}
Мы также можем использовать переменную CSS, чтобы определить в CSS что-то вроде--triangle-sizeили--triangle-fillПараметры для управления визуализацией холста, чтобы холст автоматически перерисовывался при обновлении параметров. В сочетании с анимацией это также дает большой простор для фантазии в области спецэффектов. В то время как вышеупомянутый холст используется в конце, Houdini обеспечивает больший контроль над рендерингом на основе CSS.
Полигоны WebGL
Основные браузеры довольно хорошо поддерживают WebGL, но по-прежнему кажется, что это не основная технология, которая должна быть у всех во фронтенде. Это может быть связано с его более крутой кривой обучения. У многих студентов может быть неправильное представление о WebGL, то есть о том, что это набор JS API наподобие холста. На самом деле, при написании WebGL-приложений, в дополнение к написанию связующего JS-кода, работающего в рамках CPU, то, что действительно выполняется на GPU, пишется на языке GLSL.шейдер. Однако из-за сложности самой библиотеки для рисования во вводном примере на связующий код JS приходится абсолютное большинство. Согласно пошаговому руководству по компьютерной графике, даже если это просто завершение процесса рендеринга треугольника, потребуется около сотни строк кода. Из-за нехватки места мы лишь кратко резюмируем ключевые вещи, которые необходимо сделать в этом процессе, в следующие три шага:
- Пишите вершинные и фрагментные шейдеры на GLSL.
- Определяется буфер вершин, и в него передаются данные каждой вершины треугольника.
- Сделайте некоторые приготовления в функции рендеринга, которую мы реализуем сами. После загрузки шейдерной программы вызовите
drawArrayAPI рисует данные в буфере.
этот процесс(Demo) На первый взгляд управление просто более многословное и подбрасывающее полотно.Кроме поддержки 3D в чем разница? В последнем способе мы видим разницу.
Функции стиля WebGL
Описанный выше процесс в основном выполняется шаг за шагом в каждом руководстве по WebGL. Подумайте над этим вопросом: нужно ли предусмотреть три вершины, чтобы нарисовать треугольник? Не обязательно.
Учащиеся, знакомые с холстом, знают, что при обработке изображений попиксельные операции, подобные приведенным ниже, могут легко привести к проблемам с производительностью:
for (let i = 0; i < width; i++) {
for (let j = 0; j < height; j++) {
// ...
}
}
Но в WebGL такого нет.сериалциклический. Шейдеры, которые вы пишете на GLSL, будут скомпилированы в GPU.параллельновоплощать в жизнь. Звучит круто? Как упоминалось выше, у нас есть два шейдера, а именновершинный шейдера такжефрагментный шейдер:
- Код вершинного шейдера выполняется повершинно, например для треугольника он выполняется трижды.
- Код фрагментного шейдера выполняется пофрагментно (в грубом понимании — попиксельно).Для области 100x100 GPU будет вызывать фрагментный шейдер для этих 1w пикселей параллельно.Этот параллельный процесс прозрачен для вас.
Таким образом, для фрагментного шейдера с «попиксельным выполнением», если ему известны координаты, где он находится каждый раз, когда он вызывается, он может вычислить окончательный цвет на основе этой позиции. Таким образом, мы можем вычислять цвет попиксельно на основе определенной формулы, даже не нуждаясь в буфере вершин. Функция, предназначенная для шейдера таким образом, называется функцией формирования, то есть функцией формирования. Обычный полигональный шейдер выглядит так:
#define TWO_PI 6.28318530718
// 由 JS 传入的屏幕分辨率
uniform vec2 u_resolution;
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color = vec3(0.0);
float d = 0.0;
// 重新映射空间坐标到 -1. 与 1. 间
st = st * 2.-1.;
// 多边形边数量
int N = 3;
// 当前像素的角度与半径
float a = atan(st.x,st.y)+PI;
float r = TWO_PI/float(N);
// 调节距离的造型函数
d = cos(floor(.5+a/r)*r-a)*length(st);
color = vec3(1.0-smoothstep(.4,.41,d));
// color = vec3(d);
gl_FragColor = vec4(color,1.0);
}
Это новая область.Поскольку программирование шейдеров требует написания одного и того же лаконичного и параллельного кода для многих пикселей, они полностью прозрачны друг для друга и не могут быть отлажены по желанию, что делает порог для программирования шейдеров на самом деле очень высоким. Пример здесь в очень хорошем буквареThe Book of ShadersЕсть соответствующие главы, а заинтересованные студенты могут открыть дверь в новый мир🤔
P.S. Почему мы хотим быть здесь далеко? Этот подход на самом деле чем-то похож на принцип рендеринга шрифтов.В последнее время я также изучаю некоторые связанные знания.Я надеюсь, что в то время будет больше контента, которым можно поделиться~
Суммировать
Бесспорно, что обычное развитие бизнеса легко входит в скучную и повторяющуюся стадию, но если мы посмотрим немного дальше, то обнаружим, что у нас действительно есть много доступных технических средств для оптимизации взаимодействия в области фронтенда. Простой треугольник можно нарисовать более чем дюжиной схем на четырех языках: HTML/CSS/JS/GLSL, в более сложных сценах распускается сотня цветов. Сильные возможности рендеринга браузера следует рассматривать как открытый мир: независимо от того, что вы хотите нарисовать, у вас всегда есть способ добиться этого.
Однако, в отличие от более продвинутых операций Зелдари, чем кокетливее и лаконичнее, чем управляемее техническое решение, тем сложнее будет реализация. Но вкратце, будь то игры, коды или жизнь, я считаю, что есть несколько способов быть счастливым~ Я надеюсь, что каждый сможет насладиться процессом и найти свою долю удовольствия~