Я пытаюсь обновить проект Polymer 2, чтобы использовать Polymer 3, и я на 90%, но не могу получить анимацию для добавления новых элементов для правильной работы.Артефакты добавляются через теневой дом, и кажется, что даже если имя класса добавлено, анимация не работает.
Я пытался изменить способ добавления ключевых кадров в файл javascript, а также поместить классы анимации в ": host" вместо ": host :: slotted"
index.html
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>masonry-layout demo</title>
<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script type="module">
import '@polymer/iron-demo-helpers/demo-pages-shared-styles';
import '@polymer/iron-demo-helpers/demo-snippet';
</script>
<script>
function addBelow() {
let newArticle = document.createElement('article');
newArticle.innerHTML = 'added below';
document.getElementById('masonry').appendChild(newArticle);
}
function addAbove() {
let newArticle = document.createElement('article');
let masonry = document.getElementById('masonry');
newArticle.innerHTML = 'added above';
document.getElementById('masonry').prependChild(newArticle);
}
</script>
<script type="module" src="../masonry-layout.js"></script>
<custom-style>
<style is="custom-style" include="demo-pages-shared-styles">
</style>
<style>
article {
background: #36abcc;
width: 29%;
height: 200px;
margin: 2%;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
grain-masonry {
background: #ccc;
}
</style>
</custom-style>
</head>
<body>
<div class="vertical-section-container centered">
<h3>Basic masonry-layout demo</h3>
<button onclick="addBelow();">add below</button>
<button onclick="addAbove();">add above</button>
<demo-snippet>
<template>
<masonry-layout id="masonry">
<article>
Power
</article>
<article style="height: 100px;">
To
</article>
<article style="height: 190px;">
The
</article>
<article style="height: 310px;">
People
</article>
<article>
Power
</article>
<article style="height: 140px;">
To
</article>
<article style="height: 210px;">
The
</article>
<article style="height: 230px;">
People
</article>
</masonry-layout>
</template>
</demo-snippet>
</div>
</body>
</html>
masonry-layout.js
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import {afterNextRender} from '@polymer/polymer/lib/utils/render-status.js';
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
import './masonry.pkgd.min.js';
/**
* `masonry-layout`
* Polymer 3 wrapper for masonry javascript library
*
* @customElement
* @polymer
* @demo demo/index.html
*/
class MasonryLayout extends PolymerElement {
static get is() {
return 'masonry-layout'
}
static get properties() {
return {
itemSelector: {
type: String,
reflectToAttribute: true,
value: 'article'
},
transitionDuration: {
type: Number,
reflectToAttribute: true,
value: 0
}
};
}
static get template() {
return html`
<style>
@keyframes containerMasonryMoveToOrigin {
from {
opacity: 0;
}
to { transform: translateY(0); opacity: 1; }
}
:host {
display: block;
width: 100%;
}
:host .masonry-layout-animate-move-up) {
transform: translateY(200px);
opacity: 0;
animation: containerMasonryMoveToOrigin 5s ease forwards;
}
.masonry-layout-animate-move-down) {
transform: translateY(-200px);
opacity: 0;
animation: containerMasonryMoveToOrigin 0.65s ease forwards;
}
</style>
<slot id="slot"></slot>
`;
}
init() {
this.raw = new Masonry(this, {
itemSelector: this.itemSelector,
transitionDuration: this.transitionDuration,
initLayout: false
});
afterNextRender(this, function () {
this.layout();
});
}
connectedCallback() {
super.connectedCallback();
this.init();
this._loadObserver = function (event) {
let target = event.target;
if (target.tagName === 'IMG') {
this.layout();
}
}.bind(this);
this.addEventListener('load', this._loadObserver, true);
this.toggleSlotObsever = false;
this._slotObserver = new FlattenedNodesObserver(this.$.slot, (info) => {
if (this.toggleSlotObsever) {
let addedElements = info.addedNodes.filter((node) => {
return (node.nodeType === Node.ELEMENT_NODE && node.nodeName === this.itemSelector.toUpperCase())
});
let removedElements = info.removedNodes.filter((node) => {
return (node.nodeType === Node.ELEMENT_NODE && node.nodeName === this.itemSelector.toUpperCase())
});
if (addedElements.length > 0 || removedElements.length > 0) {
this.reInit();
}
}
this.toggleSlotObsever = true;
});
}
disconnectedCallback() {
this._slotObserver.disconnect();
this.removeEventListener('load', this._loadObserver);
}
layout() {
this.raw.layout();
}
reInit() {
this.raw.destroy();
this.init();
}
appendChild(element) {
this.toggleSlotObsever = false;
element.classList.add('masonry-layout-animate-move-up');
element.addEventListener('animationend', function (event) {
//event.target.classList.remove('masonry-layout-animate-move-up');
});
super.appendChild(element);
this.raw.addItems(element);
afterNextRender(this, function () {
this.layout();
this.toggleSlotObsever = true;
});
}
appendChildren(elements) {
for (let element of elements) {
this.appendChild(element);
}
}
prependChild(element) {
this.insertBefore(element, this.children[0]);
}
prependChildren(elements) {
for (let element of elements) {
this.prependChild(element);
}
}
insertBefore(element, before) {
if (element.nodeName === '#document-fragment') {
element = element.querySelector(this.itemSelector);
}
this.toggleSlotObsever = false;
element.classList.add('masonry-layout-animate-move-down');
element.addEventListener('animationend', function (event) {
//event.target.classList.remove('masonry-layout-animate-move-down');
});
super.insertBefore(element, before);
this.raw.prepended(element);
afterNextRender(this, function () {
this.layout();
this.toggleSlotObsever = true;
});
}
}
window.customElements.define('masonry-layout', MasonryLayout);