Create a custom Layout in Ext JS and Sencha Touch, extsencha
Original article: Creating Custom Layouts in Ext JS and Sencha Touch
The layout system is the most powerful and unique part of the Sencha framework. The layout processes the size and location of each component in the application, so you do not need to manually manage those fragments. Ext JS has many similarities with the layout class of Sencha Touch. Recently, they were analyzed in detail in Ivan Jouikov's post.
Although this is the case, many Ext JS and Sencha Touch developers may never understand the principles of the layout system. The Sencha framework has provided the most common application la s, so there is little need for additional functionality for applications, so no one would like to understand the internal operation of the layout system.
Imagine that your company needs to use 3D movie usel in applications to display interface elements, but there is no standard Sencha layout to provide this capability. How can this problem be solved?
Select base class
When developing any Ext JS or Sencha Touch custom components, the first step is to consider which base class should be selected for expansion. In this case, the layout is used to accommodate 3D Projects. Because you do not need any special functions, you only need to manage projects. Therefore, you need to start from the lowest level of layout inheritance chain. In the current situation, Ext. layout. container. Container (Ext JS) and Ext. layout. Default (Sencha Touch) are the best options.
In Ext JS, the layout system needs to manually manage a lot of size and positioning computing because it needs to support earlier browsers and cannot use modern CSS functions, such as Flexbox. The consequence is that the 3D carousel layout needs to override most Ext. layout. container. Container methods, such as calculate, getContainerSize, and getPositionOffset, to layout its child elements.
Another issue that needs to be noted is that when Ext JS layout executes "layout", multiple "cycles" must be managed for each "layout" execution. For example, if the box layout is configured as stretchmax, it takes at least two cycles. The layout first checks the maximum size of each sub-component, and expands all child components in the layout to the same size in the second cycle. The layout operation produces a large number of "la s" or "cycles" (adding or removing multiple entries). To provide performance, you may want to suspend the layout first, after the operation is complete, restore the layout.
In contrast, Sencha Touch's Ext. layout. default allows the browser to process the positioning and size of most projects in the layout through CSS (because Sencha Touch only supports modern browsers, all of which have implemented CSS Flexbox ). Therefore, Ext. layout. Default contains the main methods related to adding, removing, and relocating subentries.
Now we know that we will use those classes to extend the new 3D movie usel layout. Next we will gradually implement it.
CSS3 conversion and other magic
To create a 3D Carousel, you need to use some advanced CSS 3D transformations, such as conversion, transition, rotateX/rotateY, and translateZ. CSS 3D conversion can be very reproducible, but in general, the following things need to be implemented for the new Sencha layout:
Apply perspective and transformation in the parent container (make it look 3D)
Apply transformations to child components in the layout (rotate them around the boundaries of 3D shapes)
Conversion of DOM elements within the parent container (o physically rotate the 3D shape as the user interacts with it)
As you expected, the actual DOM elements generated through Ext JS and Sencha Touch are somewhat different. Therefore, although the methods used in the two frameworks are the same, however, the generated CSS is different. The additional CSS required for the new 3D deployment usel layout is as follows (Sencha Touch ):
.x-layout-carousel { -webkit-perspective : 1500px; -moz-perspective : 1500px; -o-perspective : 1500px; perspective : 1500px; position : relative !important;} .x-layout-carousel .x-inner { -webkit-transform-style : preserve-3d; -moz-transform-style : preserve-3d; -o-transform-style : preserve-3d; transform-style : preserve-3d;} .x-layout-carousel.panels-backface-invisible .x-layout-carousel-item { -webkit-backface-visibility : hidden; -moz-backface-visibility : hidden; -o-backface-visibility : hidden; backface-visibility : hidden;} .x-layout-carousel-item { display : inline-block; position : absolute !important;} .x-layout-carousel-ready .x-layout-carousel-item { -webkit-transition : opacity 1s, -webkit-transform 1s; -moz-transition : opacity 1s, -moz-transform 1s; -o-transition : opacity 1s, -o-transform 1s; transition : opacity 1s, transform 1s;} .x-layout-carousel-ready .x-inner { -webkit-transition : -webkit-transform 1s; -moz-transition : -moz-transform 1s; -o-transition : -o-transform 1s; transition : transform 1s;}
To make the CSS layout of Ext JS look basically the same, you also need to fine-tune the CSS selector.
To enable 3D render usel to respond to user interaction in Sencha Touch and Ext JS, You have to modify some additional CSS at runtime. The first thing to do is to expand the layout of the base class, and then study how to add interactive functions.
Extended layout base class
First, we need to extend Ext. layout. Default of Sencha Touch. The main goal is to add some configuration items for the new 3D movie usel perception, and some functions for correctly locating child components inside the layout.
The initial extension is as follows:
Ext.define('Ext.ux.layout.Carousel', { extend : 'Ext.layout.Default', alias : 'layout.carousel', config : { /** * @cfg {number} portalHeight * Height of the carousel, in pixels */ portalHeight : 0, /** * @cfg {number} portalWidth * Width of the carousel, in pixels */ portalWidth : 0, /** * @cfg {string} direction * 'horizontal' or 'vertical' */ direction : 'horizontal' //or 'vertical' }, onItemAdd : function () { this.callParent(arguments); this.modifyItems(); }, onItemRemove : function () { this.callParent(arguments); this.modifyItems(); }, modifyItems : function () { //calculate child positions, etc }});
Besides the config object, the Code defines three methods: onItemAdd, onItemRemove, and modifyItems. The first two methods simply overwrite Ext. layout. the Default method is used to edit the position of the child component after the child component is added or deleted. modifyItems is a new method used to calculate the required CSS 3D conversion.
When the layout is assigned to their containers, the behavior inside the layout system will remain active:
setContainer: function(container) { var options = { delegate: '> component' }; this.dockedItems = []; this.callSuper(arguments); container.on('centeredchange', 'onItemCenteredChange', this, options, 'before') .on('floatingchange', 'onItemFloatingChange', this, options, 'before') .on('dockedchange', 'onBeforeItemDockedChange', this, options, 'before') .on('afterdockedchange', 'onAfterItemDockedChange', this, options);},
For our layout extension, the following methods need to be added for further initialization:
Ext.define('Ext.ux.layout.Carousel', { //... setContainer : function (container) { var me = this; me.callParent(arguments); me.rotation = 0; me.theta = 0; switch (Ext.browser.name) { case 'IE': me.transformProp = 'msTransform'; break; case 'Firefox': me.transformProp = 'MozTransform'; break; case 'Safari': case 'Chrome': me.transformProp = 'WebkitTransform'; break; case 'Opera': me.transformProp = 'OTransform'; break; default: me.transformProp = 'WebkitTransform'; break; } me.container.addCls('x-layout-carousel'); me.container.on('painted', me.onPaintHandler, me, { single : true }); }, onPaintHandler : function () { var me = this; //add the "ready" class to set the CSS transition state me.container.addCls('x-layout-carousel-ready'); //set the drag handler on the underlying DOM me.container.element.on({ drag : 'onDrag', dragstart : 'onDragStart', dragend : 'onDragEnd', scope : me }); me.modifyItems(); } });
After the nebulous assigns a layout container, you must wait until the container is rendered before you can specify the event processing to the underlying DOM. Next, in order to allow the layout to manage sub-components, you need to fill the gap between functions (fill in the functional gaps ):
Ext.define('Ext.ux.layout.Carousel', { //... modifyItems : function () { var me = this, isHorizontal = (me.getDirection().toLowerCase() === 'horizontal'), ct = me.container, panelCount = ct.items.getCount(), panelSize = ct.element.dom[ isHorizontal ? 'offsetWidth' : 'offsetHeight' ], i = 0, panel, angle; me.theta = 360 / panelCount; me.rotateFn = isHorizontal ? 'rotateY' : 'rotateX'; me.radius = Math.round(( panelSize / 2) / Math.tan(Math.PI / panelCount)); //for each child item in the layout... for (i; i < panelCount; i++) { panel = ct.items.getAt(i); angle = me.theta * i; panel.addCls('x-layout-carousel-item'); // rotate panel, then push it out in 3D space panel.element.dom.style[ me.transformProp ] = me.rotateFn + '(' + angle + 'deg) translateZ(' + me.radius + 'px)'; } // adjust rotation so panels are always flat me.rotation = Math.round(me.rotation / me.theta) * me.theta; me.transform(); }, transform : function () { var me = this, el = me.container.element, h = el.dom.offsetHeight, style= el.dom.style; // push the carousel back in 3D space, and rotate it el.down('.x-inner').dom.style[ me.transformProp ] = 'translateZ(-' + me.radius + 'px) ' + me.rotateFn + '(' + me.rotation + 'deg)'; style.margin = parseInt(h / 2, 10) + 'px auto'; style.height = me.getPortalHeight() + 'px'; style.width = me.getPortalWidth() + 'px'; }, rotate : function (increment) { var me = this; me.rotation += me.theta * increment * -1; me.transform(); }});
In this example, a large number of complex operations are performed to determine the correct position of each sub-component, and the conversion value of CSS needs to be updated manually in the container.
Finally, you need to add event processing to capture the interaction between users and 3D movie usel:
Ext.define('Ext.ux.layout.Carousel', { //... onDragStart : function () { this.container.element.dom.style.webkitTransitionDuration = "0s"; }, onDrag : function (e) { var me = this, isHorizontal = (me.getDirection().toLowerCase() === 'horizontal'), delta; if (isHorizontal) { delta = -(e.deltaX - e.previousDeltaX) / me.getPortalWidth(); } else { delta = (e.deltaY - e.previousDeltaY) / me.getPortalHeight(); } me.rotate((delta * 10).toFixed()); }, onDragEnd : function () { this.container.element.dom.style.webkitTransitionDuration = "0.4s"; } });
Event processing simply evaluates whether the user has dragged the mouse to carousel, and then updates the CSS transition.
You can download the complete Sencha Touch code here. The Code of Ext JS extended from Ext. layout. container. Container is very similar to this Code, but there are some minor differences in API. The Ext JS code example can be downloaded here.
Review Ext. ux. layout. Carousel
Let's take a moment to review what happened.
Because the 3D deployment usel layout only needs to inherit the basic functions of the layout system, the Ext. layout. Default class of Sencha Touch is selected for extension. Next, you have added override methods such as onItemAdd, onItemRemove, and setContainer to add the running configurations required for the layout. It is best to implement some functional methods and event processing, so that the layout can manage the location of child components.
Although 3D movie usel is a whimsical example created using Sencha Touch or Ext JS, its focus is on creating creative la s in the Sencha application, which is actually quite simple. The key point is to understand how to initialize the layout and what happened during this period-in fact, the underlying framework code is not as complicated as you think. Although the Layout System of Sencha Touch and Ext JS may be slightly different at the underlying layer, the implementation method is actually the same.
Note: This is only a technical demonstration and cannot ensure that the Code can run on all browsers. In fact, the CSS3 conversion used already means some browsers have been checked, so please do not apply this to production.
Other interesting examples of customized layouts include this Sencha Fiddle by Sencha Support engineer Seth Lemmons involving a circle menu, and this video of a custom navigation component by Andrea Cammarata, Sencha Professional Services engineer.
Author: Arthur Kay
Arthur Kay is the Developer Relations Manager at Sencha, Inc. He studied Music and Computer Science at Loyola University Chicago and has been involved with the Web since the late 1990 s.
Sencha touch is different from Extjs ???
Recently, ExtJS, an Ajax framework compiled based on JavaScript, integrated the existing ExtJS into the JQTouch and Rapha ë l libraries and launched the Sencha Touch framework suitable for the cutting-edge Touch Web, this is the world's first HTML5-based Mobile App framework. In addition, ExtJS was renamed Sencha, JQTouch founder David Kaneda, And Rapha ë l co-founder have joined Sencha team.
Sencha Touch can make your Web apps look like Native apps. The beautiful user interface components and rich data management are fully compatible with Android and Apple iOS devices based on the latest HTML5 and CSS3 WEB standards. The following are some features officially provided by Sencha. 1. Based on the latest WEB standards-HTML5, CSS3, and JavaScript. The whole library is compressed and gzip is about 80 KB. Disabling some components will make it smaller. 2. Supports the best devices in the world. The Beta version is compatible with Android and iOS. Android Developers can also use theme customized for Android. 3. Enhanced touch events. Added a set of Custom Event Data Integration Based on standard events such as touchstart and touchend, such as tap, swipe, pinch, and rotate. 4. data integration. Provides powerful data packets, which are bound to component templates through Ajax, JSONp, and YQL, and written to local offline storage.
Learning sencha touch requires understanding ext js
It can also be zero. st is written based on extjs4.0 and has an intersection with extjs.
However, if you have the confidence to study it carefully, there is no problem.
So there is no problem if you don't use extjs to focus on getting started with st.