Подробности проекта
адрес гитхаба:github
демонстрационный пример:demo
задний план
В начале, когда компания делала какие-то страницы событий, часто приходилось использовать функцию обмена скриншотами тысяч людей, и это требование было не раз или два, а часто появлялось в различных сценариях скриншотов. Когда я впервые сталкиваюсь с такого рода спросом, я в основном иду на руки.canvas
API выполняет функцию рендеринга. Шаги в этом случае примерно следующие:
- написать строку
dom template
Этикетка - оказывать
template
сталиdom
Этикетка - начать захват
dom
элемент, рисоватьcanvas
-
canvas
Рендерить картинки
Основная проблема заключается в том, что повторное использование слишком плохое, а вторая - проблема производительности. Интерфейс, который видит пользователь, не обязательно такой же, как официально отображаемый интерфейс, и могут рендерировать различия.
Потому что я в основном используюvue
,правильноvue
Основная идея также была в некоторой степени изучена.vue
пройти черезvnode
Реализована работа по рендерингу на разных концах, можно ли пройтиvnode
Как насчет рендеринга на холст? то есть нетvnode -> html -> canvas
Но прямоvnode -> canvas
. использовать одновременноvue
на основе данных, чтобы добиться рендеринга на основе данных. Как только у вас появится идея, приступим к ее реализации.
исследование
В этой статье подробнее об этом:60 FPS on the mobile webВот краткий обзор:
Canvas — это метод рендеринга в немедленном режиме, который не хранит дополнительную информацию о рендеринге. Canvas выигрывает от немедленного режима, позволяющего отправлять команды рисования непосредственно на графический процессор. Но использование его для создания пользовательских интерфейсов требует более высокого уровня абстракции. Например, некоторые простые вещи, такие как отрисовка асинхронно загружаемого ресурса в элемент, могут вызвать проблемы, например отрисовка текста поверх изображения. В HTML это легко сделать благодаря порядку элементов и z-индексу в CSS. Рендеринг DOM — это сохраненный режим, сохраненный режим — это декларативный API для поддержки иерархии нарисованных в нем объектов. Преимущество API сохраненного режима заключается в том, что с их помощью обычно проще создавать сложные сценарии, такие как DOM, для вашего приложения. Обычно это связано с затратами на производительность, требуется дополнительная память для сохранения и обновления сцены, что может быть медленным.
Начинать!
Рендеринг холста - это на самом деле попытка.Раз предшественники наделали достаточно практики, то и мы будем стоять на плечах гигантов, основанных наvue
Для реализации рендеринга холста на основе данных. Просто сделай это!
обрабатывать vnode
Те, кто знаком с исходным кодом Vue, должны знать, что Vue передаетrender
функция, пройти вcreateElement
метод построенияvnode
,пройти через发布--订阅
режим для мониторинга данных и регенерацииvnode
. Все, что нам нужно сделать, этоvnode
Этот слой начинается. Поэтому мы реализуем функцию слушателя на основе исходного кода Vue и смешиваем ее с экземпляром Vue:
Vue.mixin({
// ...
created() {
if (this.$options.renderCanvas) {
// ...
// 监听vnode中引用的变化,重新渲染
this.$watch(this.updateCanvas, this.noop)
// ...
}
},
methods: {
updateCanvas() {
// 模拟Vue render 函数
// 寻找实例中定义的 renderCanvas 方法,并传入createElement方法
let vnode = this.$options.renderCanvas.call(this._renderProxy, this.$createElement)
}
})
Таким образом, мы можем с радостью использовать внутри компонента:
renderCanvas (h) {
return h(...)
}
обработка элемента холста
Для vnode рендеринга нам нужно сделать некоторые дополнительные ограничения, такие какdom
изdiv
должен соответствоватьcanvas
что там,dom
текст внутри, соответствующийcanvas
что внутри...
То есть мы можем сделать это с некоторыми ограничениями:
пользовательский ярлык | чертежная форма | аналогия дом |
---|---|---|
view/scrollView/scrollItem | rect | div |
text | text | span |
image | img | img |
Каждый из этих классов элементов наследуется от суперкласса, и, поскольку у них разные методы отображения, они реализуют свои собственные методы рисования для настраиваемого отображения.
Реализация механизма компоновки объектов рисования
Самый простой способ нарисовать макет холста — передать ряд координатных точек и связанных с ними базовых значений ширины и высоты для элемента холста, который в реальном проекте может выглядеть следующим образом:
renderCanvas(h) {
return h('view', {
style: {
left: 10,
top: 10,
width: 100,
height: 100
}
})
}
Действительно, писать таким образом немного неудобно, на данный момент есть несколько решений, одно из них — использоватьcss-layout
заниматься управлением.css-layout
Поддерживаемые свойства преобразования:
Это всего лишь слой преобразования, который поможет нам лучше писать холст с помощью CSS, но если мы очень недовольныcss in js
На самом деле, мы также можем написать загрузчик веб-пакетов для загрузки внешнего css:
const css = require('css')
module.exports = function (source, other) {
let cssAST = css.parse(source)
let parseCss = new ParseCss(cssAST)
parseCss.parse()
this.cacheable();
this.callback(null, parseCss.declareStyle(), other);
};
class ParseCss {
constructor(cssAST) {
this.rules = cssAST.stylesheet.rules
this.targetStyle = {}
}
parse () {
this.rules.forEach((rule) => {
let selector = rule.selectors[0]
this.targetStyle[selector] = {}
rule.declarations.forEach((dec) => {
this.targetStyle[selector][dec.property] = this.formatValue(dec.value)
})
})
}
formatValue (string) {
string = string.replace(/"/g, '').replace(/'/g, '')
return string.indexOf('px') !== -1 ? parseInt(string) : string
}
declareStyle (property) {
return `window.${property || 'vStyle'} = ${JSON.stringify(this.targetStyle)}`
}
}
Главное преобразовать файл css вAST
Синтаксическое дерево, а затем преобразовать синтаксическое дерево вcanvas
Требуемая форма определения. и внедряется в компонент как переменная.
Реализовать прокрутку списка
Если у нас много элементов и нам нужно прокрутить, мы должны решитьcanvas
Проблемы с прокруткой внутренних элементов. Здесь я предпочитаю использоватьZynga ScrollerЧтобы имитировать метод прокрутки пользователя, холст перерисовывается через возвращенные им координаты прокрутки.
подробныйобратитесь сюда
моделирование событий
дляclick,touch
Для моделирования событий dom решение, которое мы принимаем, состоит в том, чтобы обнаружить в соответствии с областью, по которой щелкнули, найти самый нижний элемент, рекурсивно найти родительский элемент и вызвать соответствующий обработчик событий, тем самым имитируя всплытие событий.
Подробная реализация может бытьобратитесь сюда
наконец
Рисование страниц на холсте также является новаторской попыткой, я надеюсь, что исследование здесь может вдохновить вас, и ваш пиар также приветствуется. Здесь также было сделано много оптимизаций производительности, поэтому я не буду вдаваться в подробности из-за ограниченности места, если вам интересно, вы можете обсудить их вместе.
Наконец: он не предназначен для полной замены рендеринга на основе DOM, который по-прежнему требует ввода текста, копирования/вставки, специальных возможностей и SEO. По этим причинам мы можем использовать комбинацию холста и рендеринга на основе DOM.