Легко создавайте мини-плакаты для обмена программами

внешний интерфейс GitHub iOS Canvas

Плакат мини-программы

GitHub.com/Джейсон Рид/Опасно…

нужно

Совместное использование апплета с кругом друзей может быть достигнуто только с помощью плаката с кодом апплета.Есть два способа сгенерировать код апплета, один — использовать внутренний метод, другой — использовать холст, который поставляется с апплет; разработан внутренний метод Это очень сложно, потому что генерация картинок потребляет много памяти, а также сильно нагружает сервер; поэтому использование холста апплета является хорошим выбором, но поскольку холст относительно глубокий, много ям, и есть разные плакаты, которые нужно воспроизводить Написание процесса рендеринга делает код избыточным и сложным в обслуживании.Кроме того, ситуация с разными версиями устройств разная.Поэтому необходимость Компоненты генерации небольших программных плакатов очень актуальны.

В реальной разработке я обнаружил, что элементы плаката представляют собой не что иное, как следующее: пока эти элементы реализованы, различные плакаты могут быть сгенерированы через файл конфигурации.

Классификация элементов в плакатах

проблема, которую нужно решить

  • единичная проблема

  • проблема с сокрытием холста

  • Прямоугольник со скругленными углами, изображение со скругленными углами

  • текст из нескольких абзацев

  • Проблемы с очень длинным текстом и сокращениями MText

  • Прямоугольник содержит текст

  • Иерархия между несколькими элементами

  • Несоответствие между размером изображения и размером рендеринга

  • холст к изображению

  • Проблема клипа IOS 6.6.7

  • О получении экземпляра холста

единичная проблема

Рисунок на холсте использует единицу измерения px, но необходимо преобразовать px разных устройств, поэтому единица rpx используется в компоненте единообразно, и здесь возникает вопрос, как преобразовать единицу измерения.

Получите размер экрана устройства через wx.getSystemInfoSync, чтобы получить соотношение, а затем выполните преобразование, код выглядит следующим образом:

const sysInfo = wx.getSystemInfoSync();
const screenWidth = sysInfo.screenWidth;
this.factor = screenWidth / 750;	// 获取比例
function toPx(rpx) {	// rpx转px
	return rpx * this.factor;
}
function toRpx(px) {	// px转rpx
	return px / this.factor;
},

проблема с сокрытием холста

В процессе рисования плаката мы не хотим, чтобы пользователь видел холст, поэтому мы должны скрыть холст, первая мысль — использовать display:none; но это будет пустым при преобразовании в изображение, поэтому это не сработает, поэтому можно только управлять абсолютным позиционированием холста и перемещать его за пределы визуального интерфейса.Код выглядит следующим образом:

.canvas.pro {
    position: absolute;
    bottom: 0;
    left: -9999rpx;
}

Прямоугольник со скругленными углами, изображение со скругленными углами

Поскольку холст не обеспечивает готовый закругленный API, мы можем только рисовать его вручную. На самом деле, округлый прямоугольник состоит из 4 линий (желтых) и 4 дуги (красных), следующим образом:

Дугу можно реализовать с помощью API canvasContext.arcTo Входной параметр этого API состоит из двух контрольных точек и радиуса, что соответствует примеру на рисунке выше.

canvasContext.arcTo(x1, y1, x2, y2, r)

Далее мы можем легко написать функцию для создания прямоугольника со скругленными углами.

/**
 * 画圆角矩形
 */
_drawRadiusRect(x, y, w, h, r) {
    const br = r / 2;
    this.ctx.beginPath();
    this.ctx.moveTo(this.toPx(x + br), this.toPx(y));    		// 移动到左上角的点
    this.ctx.lineTo(this.toPx(x + w - br), this.toPx(y));		// 画上边的线
    this.ctx.arcTo(this.toPx(x + w), this.toPx(y), this.toPx(x + w), this.toPx(y + br), this.toPx(br));													// 画右上角的弧		
    this.ctx.lineTo(this.toPx(x + w), this.toPx(y + h - br));	// 画右边的线
    this.ctx.arcTo(this.toPx(x + w), this.toPx(y + h), this.toPx(x + w - br), this.toPx(y + h), this.toPx(br));											  // 画右下角的弧
    this.ctx.lineTo(this.toPx(x + br), this.toPx(y + h));		// 画下边的线
    this.ctx.arcTo(this.toPx(x), this.toPx(y + h), this.toPx(x), this.toPx(y + h - br), this.toPx(br));													// 画左下角的弧
    this.ctx.lineTo(this.toPx(x), this.toPx(y + br));			// 画左边的线
    this.ctx.arcTo(this.toPx(x), this.toPx(y), this.toPx(x + br), this.toPx(y), this.toPx(br));													// 画左上角的弧
}

есликаркаспросто используйтеthis.ctx.stroke();

еслирисовать цветные блокипросто используйтеthis.ctx.fill();

еслиокруглое изображениепросто используйте

this.ctx.clip();
this.ctx.drawImage(***);

clip()метод вырезания любой формы и размера из оригинального холста. Как только область обрезана, все последующие рисунки ограничиваются обрезанной областью (нет доступа к другим областям на холсте). Вы можете сохранить текущую область холста с помощью метода save() перед использованием метода clip() и восстановить ее в любой момент позже (с помощью метода restore()).

текст из нескольких абзацев

Если есть несколько последовательных текстов в разных форматах, пользователю нереально указать координаты для каждого текста, потому что длина предыдущего текста не фиксирована.Решение здесь состоит в том, чтобы использоватьctx.measureText(Начала поддерживать базовую библиотеку 1.9.90) Апи для расчета ширины куска текста, помните, что единица возвращаемой ширины - px(яма), чтобы узнать координаты следующего абзаца текста.

Проблемы с очень длинным текстом и сокращениями MText

Установите ширину текста наctx.measureTextЗнайте ширину текста, если он превышает заданную ширину, использовать «...» для лишней части; для многострочного текста обнаружена, что высота шрифта примерно равна размеру шрифта, а также PARAMETER LINEHEIGHT предоставляется, чтобы пользователи настроить высоту строки, таким образом, мы знаем Y-координату следующей строки.

Прямоугольник содержит текст

Это также используетctx.measureTextинтерфейс для управления шириной прямоугольника, конечно, пользователь также может установить поля paddingLeft и paddingRight;

Вертикальное центрирование текста может установить базовое выравнивание текста по середине (this.ctx.setTextBaseline('middle');), установите координаты текста на центральную линию прямоугольника; отцентрируйте его по горизонталиthis.ctx.setTextAlign('center');;

Иерархия между несколькими элементами

Поскольку у холста нет API для установки уровня элементов рисования, он может быть отрисован только в соответствии с тем, что более поздний уровень рисования выше, чем предыдущий рисунок, поэтому пользователю необходимо пройти в поле zIndex и использовать массив сортировка (Array.prototype.sort) для отрисовки по порядку.

Несоответствие между размером изображения и размером рендеринга

Для рисования используемctx.drawImage()API;

При использованииdrawImage(dx, dy, dWidth, dHeight), изображение будет сжато, чтобы соответствовать нарисованному размеру, и изображение будет деформировано, как показано ниже:

Поддерживается начиная с базовой библиотеки 1.9.0drawImage(sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight), sx и sy — координаты левого верхнего угла прямоугольной рамки выбора исходного изображения, sWidth и sHeight — ширина и высота прямоугольной рамки выбора исходного изображения, как показано ниже:

Если размер чертежа шире размера исходного изображения, то ширина размера чертежа равна ширине исходного изображения; в противном случае, если размер чертежа больше размера исходного изображения, высота размера чертежа равна равна высоте исходного изображения;

мы можем пройтиwx.getImageInfoAPI получает размер исходного изображения;

холст к изображению

Вызывается после рисования холстаwx.canvasToTempFilePathAPI преобразует холст в вывод изображения, поэтому вам нужно обратить внимание,wx.canvasToTempFilePathнужно написать вthis.ctx.drawв обратном вызове, и использование этого интерфейса в компоненте должно передать это во втором параметре (яма),следующим образом

this.ctx.draw(false, () => {
    wx.canvasToTempFilePath({
        canvasId: 'canvasid',
        success: (res) => {
            wx.hideLoading();
            this.triggerEvent('success', res.tempFilePath);
        },
        fail: (err) => {
            wx.hideLoading();
            this.triggerEvent('fail', err);
        }
    }, this);
});

Проблема клипа IOS 6.6.7

В версии IOS 6.6.7, когда метод клипа постоянно обрезает картинки, действует только первая.Это баг WeChat, и официальное подтверждение (Developers.WeChat.QQ.com/community/…

О получении экземпляра холста

мы можем использоватьwx.createCanvasContextПолучите экземпляр апплета, но не забудьте использовать его в компоненте в качестве второго параметра, как показано ниже.

this.ctx = wx.createCanvasContext('canvasid', this);

Как использовать компоненты

GitHub.com/Джейсон Рид/Опасно…