This project is no longer maintained. This addon was a proof-of-concept for my EmberFest talk previewing a user-friendly API for container/element queries and showcasing a few different strategies for respsonive components. At the time ember community was still discovering how best to support element resize events with element modifiers. I am happy to say that the base primitives have matured and an implementation that best illustrates these ideas continued in a newer addon by Isaac Lee with his project ember-container-query
. I highly recommend everyone use it!
This addon gives you tools to help you create responsive components that areeasier to develop, test, and use.
Instead of using media queries ember-fill-up
focuses on using containerqueries. Container queries, also known as element queries, end up being more powerfulespecially when building out responsive components. You can get the general idea of ContainerQueries from this article, however it should be noted that this addon tries to achieve the same result in an Ember Way
This addon does not aim at providing support for the custom css elementqueries syntax,however with this addon you should be able to achieve many of the same solutions indesigning your responsive components.
ember-fill-up
detects changes on elements by using a ResizeObserver
. If your browser doesn'tsupport ResizeObserver
then you may need to install a polyfill.
Check out the motivations and ideas behind ember-fill-up
in my talk at EmberFest 2019.
Check out the demo app (currentlyrequires a browser that supports ResizeObserver
)
ember install ember-fill-up
If your browser does not support ResizeObserver
natively then you will need to install a polyfill. There are a few options thatyou can try (1, 2).
For this example we can set up the que-etc/resize-observer-polyfill
polyfill withour dummy app.
First we install the polyfill dependencies:
npm install resize-observer-polyfill
Then we create an intializer:
ember g initializer setup-resize-detector-polyfill
Inside the initializer file app/initializers/setup-resize-detector-polyfill.js
we add the ResizeObserver
polyfill when it doesn't exist:
import ResizeObserver from 'resize-observer-polyfill';
export function initialize() {
if (!window.ResizeObserver) {
// eslint-disable-next-line no-console
console.info(
'initializer:setup-resize-detector-polyfill: ResizeObserver not found. Polyfilling...'
);
window.ResizeObserver = ResizeObserver;
}
}
export default {
before: 'register-resize-observer-detector',
initialize
};
Note: To be able to import from npm packages like this you maybe need to install ember-auto-import
in your app.
Your app should be all set now for older browsers that don't support ResizeObserver
. As an example, the dummy app of this addon has been setup with this initializer.
{{fill-up}}
element modifierThe element modifier can be placed on any element and a resize detector willbe installed on it. Anytime a change is detected on that element the onChange
callback is called.The changeHandler
in this example will receive a single argument which isthe element on which the change occured.
<FillUp />
componentThe <FillUp />
component is using the element modifier behind the scenes, and providesadditional niceties making it easier to manage detected changes.One fundamental difference is that the component between the component and the element modifier is that the component has a root element where all content from the component's block is put. It's changes from this root element that are being tracked.
<FillUp />
componentThe <FillUp />
component is pretty useful and abstracts away the element modifier while its api provides several handy responsive features.
breakpoints
The breakpoints can be passed in via definitions defined by template helpers in the templateor by functional definitions defined in javascript. It should be noted that all breakpointvalues here are using numbers represented by pixel values.
@param {number} value
- The value to test whether or not the dimension is greater than@param {number} value
- The value to test whether or not the dimension is greater than or equal to@param {number} value
- The value to test whether or not the dimension is less than@param {number} value
- The value to test whether or not the dimension is less than or equal to@param {number} value
- The value to test whether or not the dimension is equal to@param {number} inclusiveLowerBound
- The (inclusive) lowerbound to compare if the value is greater than or equal to.@param {number} exclusiveUpperBound
- The (exclusive) upperbound to compare if the value is less than.All definitions accept an optional options
argument. For examples on how to specify these for the template helpers or functional javascript breakpoint definitions check out the exampletall
breakpoint in the sections below.options
@param {Object} [options]
- (optional) Options that can be passed to provide additional context to the defintion, currently only used for specifying the dimension.@param {"width"|"height"} [options.dimension="width"]
- (optional) Passing in a key of dimension
with a value of width
or height
will specify which dimension the breakpoint definition is for. By default, if no options are passed in, the "width"
dimension will be used.import { lte, gt } from 'ember-fill-up/definitions';
// ...
// on the component definition:
breakpoints: {
small: lte(400),
large: gt(400),
tall: gt(700, { dimension: 'height' })
}
With the definition on your component on the breakpoints
property theycan then be passed into the @breakpoints
argument on the <FillUp />
component.
@breakpoints
argumentAny breakpoint definitions passed in to the @breakpoints
argument of the <FillUp />
component will be turned into attribute labels on the component's root div element whenthose breakpoints are active.
For example:
would end up with the following root element, only when the small breakpoint is active:
<div [fill-up-small]></div>
You can also override the fill-up
prefix seen here in the attribute fill-up-small
, byspecifying an @attributePrefix
argument on the component.
For example:
would end up with the attribute prefix bp-small
:
<div [bp-small]></div>
onChange
handlerThe changeHandler
passed to onChange
on the component will be calledwhenever a size change is detected on component's root element.The onChange
on the <FillUp>
component is different than the one on theelement modifier, it receives an object with additional useful properties.
Example:
onChange(change)
@param {Object} change
- The change object containing useful items relevant to the change@param {string} change.element
- The element from which a size change was detected@param {string} change.width
- The clientWidth
of the changed element@param {string} change.height
- The clientHeight
of the changed element@param {Object.<string, boolean>} change.breakpoints
- If breakpoints were passed in,this would represent a hash of breakpoint labels assigned to a boolean representing whetheror not the breakpoint is active for the current change.The component also yields a useful block param, in this example, denoted by F
: <FillUp as |F|></FillUp>
. This block param provides useful information of the most recent change.
|F|
block param
@param {Object} F
- The last change object containing useful items relevant to the change@param {string} F.element
- The element from which a size change was detected@param {string} F.width
- The clientWidth
of the changed element@param {string} F.height
- The cleintHeight
of the changed element@param {Object.<string, boolean>} F.breakpoints
- If breakpoints were passed in,this would represent a hash of breakpoint labels assigned to a boolean representing whetheror not the breakpoint is active for the current change.Any attributes specified on the <FillUp />
component will be "splatted" on the component'sroot div.
For example:
Results in the component's root div element receiving the class:
This applies for other attributes that you might want to set on the root element.
Note: This only applies to the angle-bracket invokation of the component, see belowfor the limtiations related to the cury-bracket usage.
The curly bracket invokation of the fill-up component will also work with the examplesin this documentation with the one exception of being able to "splat" attributes.In this case the only attribute that can be set are classes via the classNames
argument(which should only be used for the curly-bracket invokation of the fill-up component)
Results with the root div element receiving the class:
As a way of getting started you could consider one of following three strategiesfor making a responsive component.
By passing in a class and using the active attributes available on the root element of the <FillUp />
component you can use CSS selectors to style things appropriately.
In this example we've passed in a class of my-component
and a single breakpoint forwhen a breakpoint is greater than 500 pixels. In our css below, by default, there is afont-size
of 15px
for this component using the my-component
class. When theattribute [fill-up-large
] is applied when the large
breakpoint is active the.my-component[fill-up-large]
selector will apply, changing the font-size
to 50px
.
.my-component {
font-size: 15px;
}
.my-component[fill-up-large] {
font-size: 50px;
}
The idea behind this technique is to use the yielded block param and use thenecessary breakpoint information conditionally where applicable.
In the case you have components that need to look radically different given abreakpoint it might be easier to use child components and swap between them.
Here we would have a main <Greeting />
component, with three child components:
<Greeting::Small />
<Greeting::Medium />
<Greeting::Large />
When the <Greeting />
component is rendered, depending on which breakpoint isactive, it will use the corresponding child component.It's important in this case to try and create symmetry between the componentarguments and the data available to each of children components. In this caseour parent <Greeting />
receives a @model
argument that we're passingalong to each of the chldren components.
greeting.hbs
:
See the Contributing guide for details.
I want to thanks others who have worked on the concept of container and element queries before. Their work has made for invaluable reference in exploring the idea and current options.
element-resize-detector
react-sizeme
css-element-queries
ember-element-query
* Lucas Wiener, Tomas Ekholm, and Philipp Haller also authored an excellent paper summarizing the differences in detecting changes in element sizes. I highly encourage reading it over.
This project is licensed under the MIT License.
Auto fill in all directions Auto fill in vertical direction only with creating new rows Auto fill in all directions Notice the little square (fill handle) in the corner of the selected cell. You can d
此属性属于Paint类型,它表示要在形状内填充的颜色。 您可以使用方法setFill()设置形状的填充颜色,如下所示 - path.setFill(COLOR.BLUE); 默认情况下,笔触颜色的值为BLACK 。 以下是具有不同颜色的三角形图。
问题内容: 有谁知道迭代和高效的洪水填充算法? 还是有没有办法实现没有堆栈溢出错误的递归算法? 尝试了使用堆栈的@ Flood填充, 但是我找不到在白色和黑色图像上工作的方法。 问题答案: 这个算法对我很好。
淡出过渡 以下是在JavaFX中演示Fade Transition的程序。 将此代码保存在名为FadeTransitionExample.java的文件中。 import javafx.animation.FadeTransition; import javafx.application.Application; import javafx.scene.Group; import javaf
Ember检查器是一个浏览器插件,用于调试Ember应用程序。 灰烬检查员包括以下主题 - S.No. 灰烬检查员方式和描述 1 安装Inspector 您可以安装Ember检查器来调试您的应用程序。 2 Object Inspector Ember检查器允许与Ember对象进行交互。 3 The View Tree 视图树提供应用程序的当前状态。 4 检查路由,数据选项卡和库信息 您可以看到检查
英文原文: http://emberjs.com/guides/getting-ember/index/ Ember构建 Ember的发布管理团队针对Ember和Ember Data维护了不同的发布方法。 频道 最新的Ember和Ember Data的 Release,Beta 和 Canary 构建可以在这里找到。每一个频道都提供了一个开发版、最小化版和生产版。更多关于不同频道的信息可以查看博客