Произвольная графика в форме 1С:Предприятие 8.x

Растровая PNG иллюстрация 482x387x32 (размер: 21KB сжатый)

Интерактивное отображение произвольной 2D графики в форме приложения 1С:Предприятие можно реализовать в стандартном поле управляемой формы с установленным видом Поле HTML документа, которое предназначено для отображения изображений описанных языками HTML, XML и их расширениями SVG или VML. Формирование изображения в релизах до релиза 8.3.14 выполняется встроенным в платформу 1С браузером MS Internet Explorer, чьи версия, функциональность и опции отличаются от IE установленного в системе.

Масштабируемая векторная SVG иллюстрация (размер: 4.6KB несжатый)

Начиная с релиза 8.3.14 в платформу встроен кроссплатформенный движок WebKit с поддержкой HTML5, OpenGL, SVG и т.д. (подробней работа WebKit в составе платформы описана на //habr.com)

Приведенные ниже заметки описывают средства динамического синтеза графики для отображения в управляемых формах 1С и разработки алгоритмов интерактивного взаимодействия с этой графикой в форме.

Поле HTML документа

Управляемая форма может содержать элемент вида Поле HTML документа, у которого свойство ПутьКДанным должно указывать на реквизит формы типа Строка, в котором может находиться произвольный гипертекст удовлетворяющий требованиям HTML5. Элемент Поле HTML документа создает НаКлиенте объект веб-браузера Webkit, в котором открывается документ соответствующий гипертексту из реквизита источника данных. Элемент Поле HTML документа обеспечивает НаКлиенте полный динамический доступ к веб-документу, компоновке его элементов, их свойствам и скриптам.

Источник данных

Строковый реквизит формы, служащий источником данных для поля HTML документа может содержать URI, из которого Webkit загрузит код документа или может содержать код  документа удовлетворяющий требованиям HTML5. Минимальная корректная структура предполагает содержание:

Компактное описание средств компоновки и представления данных HTML5 изложено в публикации Экстракт языка гипертекстовой разметки HTML, средств назначения стилей в публикации Экстракт каскадных таблиц стилей CSS, программных средств в публикации Экстракт JavaScript.

SVG – Scalable Vector Graphics

Разметка SVG предоставляет расширенные возможности создания графических элементов в Поле HTML документа, для этого описание элементов svg должны быть включены в гипертекст реквизита поля или в сам документ. Кроме того svg картинка может быть размещенная на форме в Декорации типа Картинка. Этот раздел далее содержит некоторые важные замечания справочного характера, имеющие практическое значения.

SVG в HTML

Платформа 1С:Предприятие поддерживает описание графики SVG в поле HTML документа формы начиная с релиза п 8.3.14.xxx. SVG описание предоставляет достаточно развитые графические средства отображения линий, эллипсов, полигонов, текстов, с заливами и окантовками, поворотами, искажениями, операциями с цветами и прозрачностью.

SVG в Картинке

Стандарт предусматривает svg-заголовок:

Но для корректного отображения в форме 1С достаточным svg-заголовком будет:

...

...

Элементы SVG

Формат описания состава svg-элементов для гипертекста и для картинки является общим. В  него входит раздел описания стилей DEFS и описание графических элементов различных видов: линий, эллипсов, полигонов, текстов, которые приведены ниже.

Контейнер и система координат

Изображения SVG - использует планарную систему с началом координат, которая по умолчанию находится в левом верхнем углу svg-контейнера размещенного на странице браузера. Если svg-контейнер будет размещен браузером с отступом от начала страницы, то все его элементы на странице тоже окажутся смещенными. Атрибут position:absolute применим к svg-контейнеру, но неприменим к svg-элементам. Пример гарантированного совмещения начала координат svg-объекта с началом координат страницы:

Пример: viewBox уменьшил и сдвинул отображение координатной системы SVG на странице браузера

Браузер не знает о геометрии элементов в svg-контейнере и судит о его размере только по свойства width и height, которые задают его формальный размер для браузера. Исходя из этого размера браузер компонует другие элементы страницы и отображает полосы прокрутки. Если полосы прокрутки браузера не нужны, свойства размера можно не указывать совсем, если же полосы предстоит использовать, то свойства размера должны точно соответствовать размеру svg-изображения.

Размер и положение svg-элементов в svg-контейнере ничем не ограничены, поэтому если в svg-контейнере не использован элемент обрезки <clipPath>, то svg-изображение может использовать все пространство страницы браузера доступное body и не ограничивается границами svg-контейнера, если только для него не задан стиль overflow:hidden.

Координаты и параметры svg-элементов - действительные числа: положительные, отрицательные, дробные с десятичной точкой в качестве разделителя.

Более детальное описание элементов SVG приведено в публикации Масштабируемая векторная графика в разметке SVG

Текстовые блоки HTML

Если в поле необходимо реализовать отображение текста с автоматическим переносом по словам в пределах заданной ширины колонки, то их отображение удобнее реализовать средствами тэга DIV, для которого доступно абсолютное или относительное позиционирования и многочисленные свойства стиля отображения:

style="transform: rotate(-30deg);" поворачивает

"border-right:none;" без правой границы

.

VML

В релизах платформы 1С:Предприятие до 8.3.13.xxxx Поле HTML документа формы поддерживало в составе гипертекста описание векторной графики в формате VML. В более поздних релизах платформы любая vml разметка в гипертексте уже игнорируется.

...

///

Отображение и Система координат


!!! Гипертекстовый документ отображается в Поле HTML документа с отступом от левого и верхнего края, если размер документа выйдет за правую или нижнюю границы, то в поле будут автоматически отображены полосы прокрутки. Изменить описанные свойства поля можно следующими способами:

  • <style>body{margin:0; padding:0px}</style> - модифицирует внешний и внутренний отступы документа, устраняя их полностью
  • <style>body{overflow:hidden;}</style> - отменяет отображение полос прокрутки при выходе документа за границы
    • overflow-x:hidden; overflow-y:hidden; - отменяют отображение горизонтальной и вертикальной полосы прокрутки отдельно
    • <style>html{overflow:hidden;}</style> - отменяет отображение полос прокрутки в стиле html эквивалентно стилю body
      • overflow: auto | hidden | scroll | visible | inherit - предусмотренные значения
    • предположительно: оригинальные полосы прокрутки Wibkit отключаются средой 1С в любом случае, а наблюдаемые в поле полосы создаются 1С (оригинальные полосы можно кратковременно наблюдать, если в событии onLoad вызывать alert(), который на время своего отображения блокирует содержимое поля до того, как 1С отключит оригинальные полосы).
  • <style>svg{overflow:visible;}</style> - отображает элементы блока svg выходящие за его границы (позволяет в тэге svg не указывать размеры).
  • <meta name="format-detection" content="telephone=no"> - отключает отображение телефонов как ссылок
Левый верхний угол Поля HTML документа с увеличением x20 крат

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

  1. красная линия (0,0)-(1,1)
  2. черная линия (1,1)-(8,8)
  3. синий прямоугольник (10,10)-(14,14)

!!! Браузер WebKit получает в свое распоряжение пространство формы 1С внутри рамки Поля HTML документа. По умолчанию html-документ отображается браузером WebKit с отступами слева и сверху шириной 8 пикселей, но отступ может быть установлен любым свойствами margin и padding стиля body.

Справа и снизу отступ полей не делается, поэтому элементы Поля HTML документа могут использовать пространство целиком, а в случае выхода за его пределы поле отображает полосы прокрутки.

Документ допускает использование только положительных координат. Элементы html-документа выходящие в отрицательные области системы координат не обрезаются, а полностью не отображается, и полосы прокрутки для этих случаев не отображаются.

Интерактивность

Поле HTML документа позволяет реализовать интерактивную работу с содержимым поля с помощью кода js в гипертексте, значений тэгов html-документа и методов управляемой формы. К сожалению некоторые средства предусмотренные стандартом HTML5 фактически не работают на движке Webkit в актуальных версиях платформы до 8.3.17.xxxx, поэтому ниже приведенные способы будут разделены на Теоретические (как должно работать по стандарту) и Практические (как реально работает в форме 1С).

Для обработки событий, которые могут происходить в Поле HTML документа, для него необходимо установить универсальный обработчик НаКлиенте ПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка), который платформа будет вызывать для предусмотренных событий.

Нажатия мыши

Клик мыши в Поле HTML документа обрабатывается 1С автоматически и не требует специального программирования в гипертексте. Для события, при котором изменяется состояние нажатий кнопок мыши, 1С вызывает обработчик события ПриНажатии и передает в него структуру данных события. Структура данных события содержит много свойств и вложенных структур, среди которых наиболее интересными являются:

  • ДанныеСобытия.Event
    • .Event.type -
    • .Event.which - номер кнопки мыши
    • .Event.offsetX, .offsetY - отступ в объекте без учета прокрутки (если под мышью нет объекта, то им будет body)
    • .Event.layerX, .layerY - отступ в объекте без учета прокрутки (если под мышью нет объекта, то им будет body)
    • .Event.clientX, .clientY - отступ в отображаемом окне
    • .Event.pageX, .pageY - отступ в документе
    • .Event.screenX, .screenY - отступ в физическом экране
    • .Event.x, .у - не используется (имеет значение undefined)
    • .Event.shiftKey, .altKey, .ctrlKey - Ложь Булево
  • ДанныеСобытия.Button
    • .Button.id -
    • .Button.offsetLeft -
    • .Button.offsetTop -
    • offsetWidth - 200 Число
    • .Button.offsetHeight -
    • outerText - "Подготовка к начальному состоянию" Строка
    • innerText - "Подготовка к начальному состоянию" Строка
    • outerHTML - "<div class="sp" id="c42e96a9-59dc-11e9-8658-d0509947e11a" style="left:100; top:120;
    • ">Подготовка к начальному состоянию</div>" Строка
    • innerHTML "Подготовка к начальному состоянию" Строка
  • ДанныеСобытия.Document
    • .Document.body -
      • .Document.body.offsetWidth -
      • .Document.body.offsetHeight - высота окна
      • .Document.body.offsetLeft -
      • .Document.body.offsetTop -
      • .Document.body.scrollLeft -
      • .Document.body.scrollTop -
      • .Document.body.outerHTML -
Практически

При вызове обработчика 1С создает структуру данных события используя данные браузера WebKit, но при этом многие данные о событии теряются, и это создает существенные сложности для обработки события. Так например, свойство ДанныеСобытия.Event.which должно содержать значение кнопки вызвавшей клик, но фактически оно всегда установлено в значение 1. Кроме того, 1С не вызывает обработчик ни для событий клавиатуры, ни для событий мыши без клика, ни для изменения геометрии окна, ни для многих других полезных событий, которые возникают в браузере.

Поэтому для полноценной обработки событий в html-документ необходимо внедрить обработчики событий на JavaScript, которые будут предварительно обрабатывать событие в движке WebKit, и при необходимости обработки события в модуле 1С будут вызывать программно событие клика.

Ниже в примере обработчик события onmousedown получает сведения о состоянии прокрутки body через положение svg элемента с id='svgcanvas' методом getBoundingClientRect(), формирует строку параметров события в теге невидимой кнопки с id='onMouseDown' и вызывает программный клик по этой кнопке, который будет передан обработчику события 1С:

Обработка события в модуле формы определяет источник события по имени кнопки onMouseDown, получает данные скрипта из тега этой кнопки и может использовать структуру Document.body.scroll с актуальными параметрами положения svg элемента:

///

Обновление поля HTML документа

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

Практически

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

Пример внесения изменений в таблицу стилей и в стиль оформления отдельного элемента HTML документа:

///

Прокрутка документа

Размер страницы html-документа может существенно превышать размер поля формы, в этом случае клиентское пространство поля будет отображать только часть страницы с заданным отступом от левого и верхнего края.

Существует три основные задачи, в которых необходимо взаимодействовать с прокруткой программными средствами:

  • клик мыши в графический элемент страницы требует точного определения координаты с точностью до пикселя в системе координат страницы, которая может быть прокручена пользователем относительно системы координат клиентской области поля
  • клиентскую область поля необходимо прокрутить в определенную область страницы
  • гипертекст страницы был динамически обновлен и после обновления прокрутку клиентской области поля необходимо установить в прежнее положение
Теоретически

При переустановке значения реквизита данных поля html документа документ будет перезагружен и все состояния документа будут сброшены, в том числе и положение прокрутки, поэтому текущее положение прокрутки страницы перед обновлением реквизита необходимо получить, а после обновления реквизита восстановить. Для этого в браузере предусмотрены специальные средства.

Для получения текущего положения прокрутки следовало использовать код:

Восстановить положение прокрутки документа следовало в событии onload элемента body вызовом метода window.scrollTo() с параметрами предыдущих значений положения:

К сожаление, описанные методы работали на браузерном движке EI, но на современных релизах платформы 1С начиная с 8.3.14 браузерный движок был заменен на WebKit, в котором по неизвестным причинам эти методы уже не работают

Практически

Это кажется странным, но в современных релизах платформы 1С механизмом прокрутки и полосами прокрутки управляет не движок браузера WebKit, а какой-то гибридный адаптер между формой и браузером.  По этой причине большая часть средств отслеживания прокрутки в скриптах JS документа будут работать частично или некорректно, в частности body.offsetTop, window.pageYOffset, document.scrollingElement.scrollTop, body.getBoundingClientRect().top всегда имеют нулевое значение, независимо от реальной прокрутки и положения ползунка, что также относится и к горизонтальной прокрутке.

Более того, событие прокрутки onscroll в body не возникает и не обрабатывается, поэтому отследить прокрутку не всегда удается в тот момент, когда она осуществляется.

Тем не менее, значение прокрутки все-таки можно получить из координат положения элементов на странице полученных методом .getBoundingClientRect(); Следует помнить, что этот метод не работает корректно для body, но работает для элементов div и svg:

Управлять положением прокрутки можно через свойства scrollLeft и scrollTop объекта body.

  • устанавливаемые значения свойств scrollLeft и scrollTop должны быть положительным
  • после установки значения свойств остаются нулевыми

Получение размеров

Размер экрана — это ширина и высота всего экрана: монитора или мобильного дисплея. о размере экрана можно с помощью свойства screen объекта window:
window.screen.width
window.screen.height

Доступный размер экрана — это ширина и высота активного экрана без панели инструментов операционной системы.:
= window.screen.availWidth
= window.screen.availHeight

Размер внешнего окна — это ширина и высота текущего окна браузера, включая адресную строку, панель вкладок и другие панели браузера:
= window.outerWidth
= window.outerHeight

Внутренний размер окна — это ширина и высота области просмотра (вьюпорта).
= window.innerWidth
= window.innerHeight

внутренний размер окна без полос прокрутки, то делаем следующее:
= document.documentElement.clientWidth
= document.documentElement.clientHeight

размера веб-страницы используйте следующее (включает в себя внутренние отступы страницы, но не включает границы, внешние отступы и полосы прокрутки):
= document.documentElement.scrollWidth
= document.documentElement.scrollHeight
Если pageHeight больше, чем внутренняя высота окна, значит, присутствует вертикальная полоса прокрутки.

Изменение размера


После формирования документа размер окна клиента доступен в свойствах Элемент.Документ.body

  • .clientWidth и .clientHeight содержат размер окна доступного для содержания
  • .scrollWidth и .scrollHeight -
  • .offsetWidth и .offsetHeight содержат размер body с учетом внешнего отступа margin

<body onResize='onResize.click()'>
<button id='onResize' style='display:none'></button> устанавливает по событию onResize документа нажатие одноименной скрытой кнопки, которое вызовет обработку события в 1С

Размер окна доступен в свойствах Элемент.Документ.body

  • clientWidth 898 Число
  • clientHeight 863 Число
  • offsetWidth 898 Число
  • offsetHeight 863 Число
  • scrollWidth 898 Число
  • scrollHeight 863 Число

События мыши

.x .y .clientX .clientY

.pageX .x - в окне

.offsetX .offsetY

.screenY абсолютные

pageYOffset всегда 0

событие scroll не вызывается и при описании в <body onscroll='...'>, и при программном назначении document.body.scroll(function() {...})
пример назначения и отмены обработчиков событий: .on("scroll", handler), поэтому убрать установленный обработчик можно с помощью .off( "scroll" )

Контекстное меню

.

Примеры

...

Источники

  • Масштабируемая векторная графика (Scalable Vector Graphics — SVG) //developer.mozilla.org
  • Простой и содержательный сайт от Alexandr_T //svg-art.ru
    • Online генераторы примеров //svg-art.ru
  • Размеры в SVG (интерактивное демо: Вьюпорт, Ширина и высота, viewBox, preserveAspectRatio, Единицы измерения, Системы координат) //css.yoksel.ru
  • Peter Collingridge's personal site (SVG basics, Interactive SVGs, 3D Graphics with Processing.js...) //www.petercollingridge.co.uk
  •  "Живые" картинки со Snap.SVG //infostart.ru
  • Разбираемся с WebKit в 1С, на примере интеграции TinyMCE в управляемую форму в УТ 11.4 //habr.com
  • Как получить размеры экрана, окна и веб-страницы в JavaScript?  //habr.com

Leave a Reply