написать впереди
Благодаря усилиям команды Tencent Omi сегодня вы можете использовать движок Cax для рендеринга SVG с высокой производительностью в небольших программах!
SVG — это масштабируемая векторная графика (Scalable Vector Graphics), основанная на Extensible Markup Language, графическом формате, используемом для описания двухмерной векторной графики. Он был разработан консорциумом World Wide Web и является открытым стандартом. SVG имеет много преимуществ:
- SVG определяет графику в формате XML, которую можно создавать и изменять с помощью текстового редактора.
- Изображения SVG можно искать, индексировать, создавать сценарии или сжимать.
- SVG масштабируется, и качество увеличенного изображения не снижается
- Изображения SVG можно печатать с высоким качеством при любом разрешении.
- SVG можно читать и изменять многими инструментами (например, Блокнотом).
- SVG меньше по размеру и более сжимаем и программируем, чем изображения JPEG и GIF.
- SVG полностью поддерживает программирование DOM, интерактивное и динамическое.
Предпосылкой для поддержки этих превосходных функций является -Требуется поддержка тегов SVG. Например, в апплете напрямую пишем:
<svg width="300" height="150">
<rect
bindtap="tapHandler" height="100" width="100"
style="stroke:#ff0000; fill: #0000ff">
</rect>
</svg>
Вышеизложенное определяет структуру, стиль и поведение SVG при щелчке. Однако в настоящее время апплет не поддерживает теги SVG и поддерживает только отображение SVG в качестве фонового изображения после загрузки, напримерbackground-image: url("data:image/svg+xml.......)
или URL-адрес в качестве фонового изображения после base64.
Так что делать? Есть ли способ заставить апплет поддерживать SVG?Ответ - да! Нужны следующие вещи (стоящие на плечах великанов):
- JSX, самое сильное выражение пользовательского интерфейса в истории, поддерживает язык JS для написания взаимного преобразования XML-Hyperscript.
- Апплет имеет встроенный рендерер Canvas.
- Последний движок рендеринга от Cax
- HTM, Hyperscript Tagged Markup, может быть заменой для JSX или другого варианта, создание Hyperscript во время выполнения / время компиляции с использованием стандартного синтаксиса шаблона ES, созданного автором preact (также инженером Google)
Вот небольшое объяснение Hyperscript:
Например в JSX
<div>
Hello {this.props.name}
</div>
или htm в js:
html`<div>
Hello {this.props.name}
</div>`
в конечном итоге будет скомпилирован в:
h(
"div",
null,
"Hello ",
this.props.name
);
Вложенные элементы div также будут скомпилированы в h вложенных h, например
<div>
<div>abc</div>
</div>
После компиляции:
h(
"div",
null,
h(
"div",
null,
"abc"
)
)
Определение функции h также довольно лаконично:
function h(type, props, ...children) {
return { type, props, children }
}
Через выполнение h можно получить структурированные данные в js, так называемый виртуальный дом. Обратите внимание, что у htm есть небольшие накладные расходы во время выполнения, а у jsx - нет.
Краткое содержание одной фразы:
Используйте встроенный модуль визуализации Canvas апплета, реализуйте подмножество стандарта SVG в Cax и используйте JSX или HTM для описания поведения структуры SVG.
Посмотрите непосредственно на вариант использования в апплете:
import { html, renderSVG } from '../../cax/cax'
Page({
onLoad: function () {
renderSVG(html`
<svg width="300" height="220">
<rect bindtap="tapHandler"
height="110" width="110"
style="stroke:#ff0000; fill: #ccccff"
transform="translate(100 50) rotate(45 50 50)">
</rect>
</svg>`, 'svg-a', this)
},
tapHandler: function () {
console.log('你点击了 rect')
}
})
Среди них svg-a соответствует идентификатору cax-элемента в wxml:
<view class="container">
<cax-element id="svg-c"></cax-element>
</view>
Объявление зависимостей компонентов
{
"usingComponents": {
"cax-element":"../../cax/index"
}
}
Эффект, отображаемый в апплете:
можно использоватьwidth
,height
,bounds-x
а такжеbounds-y
Установите область связанного события, например:
<path width="100" height="100" bounds-x="50" bounds-y="50" />
Следует отметить, что на ограничивающую рамку, активируемую событием элемента, влияет преобразование самого себя или родительского узла, поэтому это не прямоугольная триггерная область абсолютных координат.
Еще один сложный пример использования SVG для рисования логотипа Оми:
renderSVG(html`
<svg width="300" height="220">
<g transform="translate(50,10) scale(0.2 0.2)">
<circle fill="#07C160" cx="512" cy="512" r="512"/>
<polygon fill="white" points="159.97,807.8 338.71,532.42 509.9,829.62 519.41,829.62 678.85,536.47 864.03,807.8 739.83,194.38 729.2,194.38 517.73,581.23 293.54,194.38 283.33,194.38 "/>
<circle fill="white" cx="839.36" cy="242.47" r="50"/>
</g>
</svg>`, 'svg-a', this)
Небольшой эффект отображения программы:
Используйте cax для рендеринга svg в omip и mps, вам не нужно использовать htm. Например, реализуйте два приведенных выше примера в omip:
renderSVG(
<svg width="300" height="220">
<rect bindtap="tapHandler"
height="110" width="110"
style="stroke:#ff0000; fill: #ccccff"
transform="translate(100 50) rotate(45 50 50)">
</rect>
</svg>, 'svg-a', this.$scope)
renderSVG(
<svg width="300" height="220">
<g transform="translate(50,10) scale(0.2 0.2)">
<circle fill="#07C160" cx="512" cy="512" r="512"/>
<polygon fill="white" points="159.97,807.8 338.71,532.42 509.9,829.62 519.41,829.62 678.85,536.47 864.03,807.8 739.83,194.38 729.2,194.38 517.73,581.23 293.54,194.38 283.33,194.38 "/>
<circle fill="white" cx="839.36" cy="242.47" r="50"/>
</g>
</svg>, 'svg-a', this.$scope)
Обратите внимание, что последний параметр, переданный в omip, не
this
, ноthis.$scope
.
В mps, чтобы быть более тщательным, вы можете создавать файлы svg отдельно и импортировать их через импорт.
//注意这里不能写 test.svg,因为 mps 会把 test.svg 编译成 test.js
import testSVG from '../../svg/test'
import { renderSVG } from '../../cax/cax'
Page({
tapHandler: function(){
this.pause = !this.pause
},
onLoad: function () {
renderSVG(testSVG, 'svg-a', this)
}
})
Например, test.svg:
<svg width="300" height="300">
<rect bindtap="tapHandler" x="0" y="0" height="110" width="110"
style="stroke:#ff0000; fill: #0000ff" />
</svg>
Будет скомпилирован mps в:
const h = (type, props, ...children) => ({ type, props, children });
export default h(
"svg",
{ width: "300", height: "300" },
h("rect", {
bindtap: "tapHandler",
x: "0",
y: "0",
height: "110",
width: "110",
style: "stroke:#ff0000; fill: #0000ff"
})
);
Итак, подведем итог:
- Вы можете использовать SVG непосредственно в mps, импортировав файлы SVG.
- Вы можете использовать SVG непосредственно в omip, используя JSX
- Вы можете использовать SVG непосредственно в нативном апплете так же, как вы используете html.
Это конец? Далеко не так, см. этот пример cax в апплете:
Подробный код:
renderSVG(html`
<svg width="300" height="200">
<path d="M 256,213 C 245,181 206,187 234,262 147,181 169,71.2 233,18 220,56 235,81 283,88 285,78.7 286,69.3 288,60 289,61.3 290,62.7 291,64 291,64 297,63 300,63 303,63 309,64 309,64 310,62.7 311,61.3 312,60 314,69.3 315,78.7 317,88 365,82 380,56 367,18 431,71 453,181 366,262 394,187 356,181 344,213 328,185 309,184 300,284 291,184 272,185 256,213 Z" style="stroke:#ff0000; fill: black">
<animate dur="32s" repeatCount="indefinite" attributeName="d" values="......太长,这里省略 paths........" />
</path>
</svg>`, 'svg-c', this)
Попробуйте еще раз знаменитого тигра SVG:
Если путь слишком длинный, код не будет опубликован.Вы можетенажмите здесь, чтобы посмотреть
это все? Продолжение следует..., последующие дополнения:
Pasiton Label.
import { html, renderSVG } from '../../cax/cax'
Page({
onLoad: function () {
const svg = renderSVG(html`
<svg width="200" height="200">
<pasition duration="200" bindtap=${this.changePath} width="100" height="100" from="M28.228,23.986L47.092,5.122c1.172-1.171,1.172-3.071,0-4.242c-1.172-1.172-3.07-1.172-4.242,0L23.986,19.744L5.121,0.88
c-1.172-1.172-3.07-1.172-4.242,0c-1.172,1.171-1.172,3.071,0,4.242l18.865,18.864L0.879,42.85c-1.172,1.171-1.172,3.071,0,4.242
C1.465,47.677,2.233,47.97,3,47.97s1.535-0.293,2.121-0.879l18.865-18.864L42.85,47.091c0.586,0.586,1.354,0.879,2.121,0.879
s1.535-0.293,2.121-0.879c1.172-1.171,1.172-3.071,0-4.242L28.228,23.986z"
to="M49.1 23.5H2.1C0.9 23.5 0 24.5 0 25.6s0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1C51.2 24.5 50.3 23.5 49.1 23.5zM49.1 7.8H2.1C0.9 7.8 0 8.8 0 9.9c0 1.1 0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1C51.2 8.8 50.3 7.8 49.1 7.8zM49.1 39.2H2.1C0.9 39.2 0 40.1 0 41.3s0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1S50.3 39.2 49.1 39.2z"
from-stroke="red" to-stroke="green" from-fill="blue" to-fill="red" stroke-width="2" />
</svg>`, 'svg-c', this)
this.pasitionElement = svg.children[0]
},
changePath: function () {
this.pasitionElement.toggle()
}
})
Pasiton предоставляет возможность переключения между двумя путями и цветами.Наиболее распространенными сценариями являются деформация пути после нажатия кнопки меню и кнопки закрытия.
Например, чтобы увидеть изменение цвета и пути одновременно:
Линейное движение
Вот пример использования SVG в mps:
import { renderSVG, To } from '../../cax/cax'
Page({
tapHandler: function(){
this.pause = !this.pause
},
onLoad: function () {
const svg = renderSVG(html`
<svg width="300" height="300">
<rect bindtap="tapHandler" x="0" y="0" height="110" width="110"
style="stroke:#ff0000; fill: #0000ff" />
</svg>`
, 'svg-a', this)
const rect = svg.children[0]
rect.originX = rect.width/2
rect.originY = rect.height/2
rect.x = svg.stage.width/2
rect.y = svg.stage.height/2
this.pause = false
this.interval = setInterval(()=>{
if(!this.pause){
rect.rotation++
svg.stage.update()
}
},15)
})
Эффект следующий:
комбинированное упражнение
import { renderSVG, To } from '../../cax/cax'
Page({
onLoad: function () {
const svg = renderSVG(html`
<svg width="300" height="300">
<rect bindtap="tapHandler" x="0" y="0" height="110" width="110"
style="stroke:#ff0000; fill: #0000ff" />
</svg>`
,'svg-a', this)
const rect = svg.children[0]
rect.originX = rect.width/2
rect.originY = rect.height
rect.x = svg.stage.width/2
rect.y = svg.stage.height/2
var sineInOut = To.easing.sinusoidalInOut
To.get(rect)
.to().scaleY(0.8, 450, sineInOut).skewX(20, 900, sineInOut)
.wait(900)
.cycle().start()
To.get(rect)
.wait(450)
.to().scaleY(1, 450, sineInOut)
.wait(900)
.cycle().start()
To.get(rect)
.wait(900)
.to().scaleY(0.8, 450, sineInOut).skewX(-20, 900, sineInOut)
.cycle()
.start()
To.get(rect)
.wait(1350)
.to().scaleY(1, 450, sineInOut)
.cycle()
.start()
setInterval(() => {
rect.stage.update()
}, 16)
}
})
Эффект следующий:
разное
- vscode установить плагин lit-html, чтобы сделать htm html
内容
выделять - Я также надеюсь, что функции, предоставляемые апплетом SVG, могут бытьоткрытые вопросыСообщите нам, пройдите оценку, и давайте сделаем это!
- Cax SVG Github
- Справочная документация