I'm trying to add web animation to my app.
I want to avoid using neon-animation as it is now deprecated.
I read this instructions : https://medium.com/collaborne-engineering/polymer-2-0-replace-neon-animation-with-web-animations-api-e82d7bd82e6 but I can't figure out how to use it in my case :
I have a page with two custom elements that are displayed if the route matches :
<app-route route="{{route}}" pattern="/list" active="{{listActive}}"></app-route>
<app-route route="{{route}}" pattern="/product/:id" active="{{productsActive}}" data="{{productsData}}"></app-route>
<catalog-product-page hidden$={{!productsActive}}></catalog-product-page>
<catalog-list-page id="productPage" hidden$={{!listActive}} item-route="{{route.prefix}}/product"></catalog-list-page>
The catalog-list-page contains a dom-repeat that loads a list of items pointing to a catalog-product-page.
How can I make catalog-product-page to get animated when an item is selected ?
Even though neon-animation is already deprecated but it's still a good example of using Web Animations. I recommend you to look its source code especially neon-animated-pages and neon-animatable.
How can I make catalog-product-page to get animated when an item is selected?
It has a lot of ways to do.
One of the simplest things I come up is this. In that plunker it has 2 components are my-app and my-page. Switch to first version (versions on the sidebar) is just a simple toggle display block to none and so on. Then switch to second version you will see simple transition and the added code is
if (selected === this.selected) return
this.animate({
opacity: [0, 1],
transform: ['translateY(16px)', 'translateY(0)']
}, {
duration: 250,
easing: 'ease-in-out'
})
This mean for entry page (switch to selected) it will play animation as the code shown. For exit page (switch to not selected) it will do nothing because its display is none. For other pages just return.
More examples of using Web Animations see here and W3C specification see here. I hope this help.
Note: In my experience of using Web Animations. It works very well in supported browsers but others it's not that good (you can find some issue on their repo).
Related
How do i set the theming of components of a model which is hidden:
If i not using the hideModel function everthing is working perfect, but if the model is hided i get an error 2 => BAD_DATA = 2,
this.viewerComponent.viewer.hideModel(this.viewerComponent.viewer.model);
The following things i already tried out:
this.viewerComponent.viewer.getHiddenModels()[0].setThemingColor(idArray[0], color, true);
this.viewerComponent.viewer.setThemingColor(idArray[0], color, this.viewerComponent.viewer.getHiddenModels()[0]);
This is not working for sure, since the model of the viewer will be null after hiding
this.viewerComponent.viewer.setThemingColor(idArray[0], color, this.viewerComponent.viewer.model());
Viewer Version 7
Thanks for help
Unfortunately, viewer.hideModel is a bit of a misnomer because it doesn't just hide the model, it actually unloads it. If you want to hide the model while still keeping all its data in memory, you might be able to achieve a similar result by calling viewer.hide(viewer.model.getRootId()). This will hide (or "ghost", if you have "ghosting" enabled; see below) the individual elements of the model while still keeping them in memory, so you can still configure properties like the theming color.
Lots of new functions released with React 16. One of them is the ReactDOM.createPortal(child, container) API, which is handy for visually breaking out of its container.
However, it seems like that it not only breaks out its container but also breaks the basic html rules which I learned from the first day of web development. The createPortal API let you render your component out of its parent, and break the html structure convention we expected.
In the other hand, we do retrieve more flexibility and now can render DOM in the sibling or else components.
IMO, I don't think this is a good deal to gain more flexibility by trading html convention in. Also the example supplied by official does not convince me.
What I am curious about is:
Is there anyone who face any condition that createPortal API is a must?
thanks
The examples in the docs are some of the cases where createPortal is really useful - specifically dialogs, hovercards, and tooltips.
The docs also specifically state:
Note:
It is important to remember, when working with portals, you’ll need to make sure to follow the proper accessibility guidelines.
As an example, the docs show how a modal could be built using createPortal(). You'll notice the modal is created in the #modal-root element, which is a root element alongside the #app-root element. This is a great example of how createPortal() can be used without violating any HTML rules.
<div id="app-root"></div>
<div id="modal-root"></div>
I ran into another use case a few months ago. Because React 16 portals were not available, I had to use a home-baked portal implementation.
I was creating SVG graphs. All of the lines, paths, and so forth needed to be rendered inside an <svg> element. But I wanted to use HTML to render text labels (for a number of reasons). This meant that an object on the graph and its label would necessarily be in separate parts of the DOM. But with portals, I could still keep all of a graph component's logic together. Here's a fictitious example:
const LabeledPoint = ({ x, y, r, labelText }) => [
<circle cx={x} cy={y} r={r} />,
<GraphLabel x={x + 5} y={y}>{labelText}</GraphLabel>,
];
You would use this component inside an <svg> element. The GraphLabel component would use a portal to render labelText in an HTML div element at the same coordinates as that <svg>, using absolute positioning to place it at the correct coordinates.
This way, all of the logic for a single component could be in one place even if I needed to render the actual DOM elements in different places for technical reasons.
Portals is very useful feature when you need to render your component outside the DOM hierarchy of the parent component.
You define a portal using the following syntax:
ReactDOM.createPortal(child, container)
The first argument (child) is any renderable React child, such as an
element, string, or fragment. The second argument (container) is a DOM
element.
See the following tutorial to see how and why to use portals:
https://www.youtube.com/watch?v=lOMU9BeIrO4
Before going into my answer, I'll just note that I interpret the question as "in which cases is there no alternative to using a portal, or a portal would be a demonstrably much better solution?"
There are very few cases where portals are the only solution. A lot of the time there's a way to structure your app so that you don't need to use them. There's some niche use cases, but even there it's usually not the only solution.
For example in the SVG use case, you could instead create a Labels component that takes an SVG React element as argument, and then loops recursively over the children to construct an HTML element with matching labels in the right position. That would as a bonus also make the SVG code a lot simpler. If the SVG is user editable, you'd have to store its state as a whole anyway on each change, allowing you to easily pass the state back into both SVG and label elements. That said, here the portal solution seems at least on par with the alternatives, and could be the simplest in some circumstances.
Dispatching plugin components
Portals can be useful for library/framework authors. It allows plugins to render multiple components in the same element, each of which the framework then portals to a different position in the UI (e.g. editor area, sidebar).
WordPress's block editor uses this for a few things, they call it SlotFill. For example if you're coding a new block in a plugin. You always provide an edit component for each block, which is rendered to the WYSIWYG editor. If it includes an InspectorControls component, everything inside it will go into the sidebar.
The Block Toolbar works in the same way. Content of the <BlockControls/> element is moved to the toolbar that is displayed right above the block content.
This is implemented as a portal to a registered slot.
The advantage of a portal here is that it allows a block's code to reuse the state and hooks in all components, even though they are not rendered in the same place. This makes the process of adding sidebar code very easy and with minimal repetition. If plugins instead needed to provide each of these components as a standalone React component, managing their state would be much more complex.
Example
You won't find ReactDOM.createPortal in the example itself. It's rather an example of how a plugin can benefit from a framework that uses it. See WordPress's source code if you're interested in the implementation details.
I added a simple useState hook to the mentioned InspectorControls example and removed some irrelevant parts.
edit: ( { attributes, setAttributes } ) => {
const [myColor, setMyColor] = useState('#fff');
return (
<div>
<InspectorControls key="setting">
// Simplified HTML, real world blocks use more complex HTML here.
<ColorPalette
value={myColor}
onChange={ setMyColor}
/>
</InspectorControls>
<TextControl
value={ attributes.message }
onChange={ ( val ) => setAttributes( { message: val } ) }
style={ {
backgroundColor: myColor,
color: attributes.text_color,
} }
/>
</div>
);
},
We are currently making the client retrieve the object states when the page loads (which will cause the 'pending' objects in the model to turn into different colors). Then we poll for changes to update the coloring (Firstly: pending object gets colored when the viewer loads, and then we keep polling to check and change state again, to make Forge render those in a different color and store their old color/material. When the polling received a change that an object should no longer be colored, it tells Forge to use the old color/material again.
The problem:
We've found out what the problem is, but we couldn't find out how to fix it. The problem is that changing materials in Forge doesn't work after startup anymore, it only works in the first ~3 seconds or so (the materials were used to show the colors).
However, setting overlays works even after the first ~3 seconds, (showing overlays instead of materials to show the colors).
This is not what we want to achieve. This looks unoptimized, because overlays will be shown through everything.
The materials, however, seem to be 'locked', as in, they cannot be changed anymore after the first ~3 seconds. It seems like they aren't refreshed or something
In the examples, we found they used viewer.impl.invalidate(true) to refresh the Forge viewer, but that doesn't do anything after ~3 seconds.
We've also tried every combination of viewer.impl.invalidate(true, true, true) as well as setting material.needsUpdate to true, as well as trying to re-render the entire scene.
We also found this: https://github.com/mrdoob/three.js/issues/790, but we couldn't find a good way to do that in Forge, we tried viewer.requestSilentRender() but that didn't do anything either.
Anyway, we've tried everything we could come up with and could find online to make the materials work, but nothing made a difference.
We are looking to find someone that's more experienced with how Forge works that can see what the material code is doing wrong.
As for the content, here is all the code you will need to understand what is happening:
DROPBOX LINK
And here is a small part of the "index.html" file that sets the color:
try
{
viewer.restoreAllColorOverlays(); //for materials instead of overlays: viewer.restoreAllColorMaterials();
$.each(colors, function(color, selectionIds)
{
viewer.setColorOverlay(selectionIds, color); //for materials instead of overlays: viewer.setColorMaterial(selectionIds, color);
});
}
catch(error)
{
console.error(error);
}
I have no idea how you implement your app, so I only tell what I found in your codes. If you want to resolve the issue you addressed, you can consider providing a reproducible case demonstrating that, I will gladly pass it to our dev team. Those following items should be in the reproducible case:
A short exact description of what you are trying to achieve. The behavior you observe versus what you expect, and why this is a problem.
A complete yet minimal sample source model to run a test in.
A complete yet minimal Forge app that can be run and debugged with a simple procedure to analyze its behavior lives in the sample model.
A complete yet minimal pure three.js app that can be run and demonstrated the shader effect you want. Note. Forge Viewer is using r71 three.js.
Detailed step-by-step instructions for reproducing the issue, e.g. which element to pick, what command to launch etc.
If your reproducible case could not be posted here publicly, please send it to the forge.help#autodesk.com and remove sensitive data or information before you send.
=== Something I found in your codes:
I found here are some wrong types and missing actions in your ColorMaterial extension. The color property of an material should the a type of the THREE.Color. Here is my modification:
Autodesk.Viewing.Viewer3D.prototype.setColorMaterial = function(objectIds, color)
{
if( !(color instanceof THREE.Color) ) throw 'Invalid argument: Color';
var material = new THREE.MeshPhongMaterial
({
color: color,
opacity: 0.8,
transparent: true
});
viewer.impl.matman().addMaterial( 'ColorMaterial-' + new Date().getTime(), material, true );
// ...........
};
Its' result is here:
In the ColorOverlay extension, The type of material color property is also wrong, it should be a type of THREE.Color, too. Changing it into THREE.Color should work fine. In addition, overlay is covers on 3D objects, so you should call viewer.hide() with your setColorOverlay() together. Otherwise, it won't look like a transparent object.
Without hidding 3D object of the wall:
hide 3D object of the wall:
I am relatively new to programming and have been reading up and watching videos on Polymer 1.0. But I am struggling to wrap my head around some of it, I have a general understanding of the elements and have been browsing the catalog. But I am not making certain connections. Such as how an item on a paper-menu element can be accessed by using on-iron-select calling _itemSelected?
how does on-iron-select link to paper-menu, and where is the documentation for this? I have looked trough the catalog and the bower repo I have downloaded and I can't see it.
I event build some basic elements and console logged this.$, even there I do not see this properties and attributes
In order to dive into what's going on, you need to understand Polymer 1.0's Behaviors.
Once that background info is established, the source for the <paper-menu> element will point you in the right direction:
Polymer({
is: 'paper-menu',
behaviors: [
Polymer.IronMenuBehavior
]
});
That Polymer.IronMenuBehavior in turn makes use of its own set of behaviors, including Polymer.IronSelectableBehavior. All those incremental behaviors create the overall functionality that you're seeing in the <paper-menu> element.
The nice thing about this approach is that any other element that also makes use of, e.g., Polymer.IronSelectableBehavior will share the same general properties and methods, and a collection of elements feels like more of a coherent library.
I have created a simple webpage with 4 different page. On home page there is a navigation link of each page like -
Page1
page2
Page3
Page4
So now I want to implement something like if I will click on any link it should open that page like we flip pages of a book with some transition effects. So how can achieve this by using html5 or css3 etc?
As it has been said, your question lacks a bit of former investigation to get some concrete answers, but here are some insights which can maybe help you:
Flip transform
Using CSS3 2D transforms and clipping
See the example made by Román Cortés: http://www.romancortes.com/blog/pure-css3-page-flip-effect/ (Only works with Chrome - the demo is quite old, when only this browser was handling those CSS properties, with the webkit- prefix)
The superposition of div with different z-index and the use of CSS3 2D translation/rotation transforms (with adapted origins) do most of the trick here. `box-shadow' and 'gradient' are added to simulate depth. The method by Hakim El Hattab, presented by nlob, is a kind of variant using the canvas to draw the flip instead.
Advantages:
Light + Compatible with IE9+, Firefox 19+, Chrome 25+,...
The example shows both the front and back of the pages
Inconvenient:
A bit flat...
Using CSS3 custom filters
See the example in Adobe's FilterLab: http://html.adobe.com/webplatform/graphics/customfilters/cssfilterlab/ ('Add Filter' > 'Custom' > 'page-curl' - Only works with Firefox Aurora and properly-set Chrome Canary - ie by enabling "CSS Shaders" in 'about:flags')
The trick here is to use a quite new CSS3 feature, the custom shaders, which allow you to apply webGL-like shaders to your DOM elements (A nice introduction to those notions here: HTML5rocks.com - Introduction to Custom Filters (aka CSS Shaders) by Paul Lewis). You can find many resources to implement the shaders. For instance:
Deforming Pages of 3D Electronic Books - Paper by Lichan Hong, Stuart K. Card, and Jindong (JD) Chen
Adobe's page-curl shader - Github
Advantages:
Real 3D rendering, with possibility to change the point of view, the lighting, ...
Inconvenient:
New technology - currently only compatible with Firefox Aurora and Chrome Canary + some restrictions to the DOM elements (see an example in this other thread)
Animation & Interface
All those solutions use the CSS transition to create the animation, by tweening the properties of the 2D transforms or the input attributes of the shaders.
The animation can be triggered by a basic CSS state (:hover for instance) or through Javascript, by handling the chosen event (click, drag, ...). You can for example use this handler to set the classes of your DOM element to trigger the transition:
CSS:
.page {
transform: translate(0px, 0px) rotate(0deg);
transition: transform 1s;
}
.curled-page {
transform: translate(42px, 42px) rotate(42deg);
}
- JS:
document.getElementById('page1-corner').onclick = function() {
var page1 = document.getElementById('page1');
page1.className += ' curled-page'; // Supposing page1 already has "page" as class.
};
If you dig a bit in all the given answers, you should be able to find your way.
Good luck!
you need to have understanding of following properties in css and basic javascript events.
preserve 3d,
transform origin,
transform rotate,
z-index.
And you cannot use hyperlinks for navigation as reloading the page would conflict your requirement of flipeffect.Nobody will be providing you the entire script for your task.you have to do it yourself.
The following is text-based. You do have to edit a file that is a sequence of page URLs, to make nextPage prevPage work.
https://pittendrigh.org?robopage=FliesBook