[英]How can I make Angular component animations follow CSS class changes, rather than static styles?
I've created a block-cursor date/time input field that uses Angular states and animations to indicate both ongoing states (like being disabled) or animated transitional states (like a red flash when an invalid keystroke has been entered).我创建了一个块光标日期/时间输入字段,它使用 Angular 状态和动画来指示正在进行的状态(如被禁用)或动画过渡状态(如输入无效按键时的红色闪光)。 These input fields can be seen in use here: https://skyviewcafe.com/
这些输入字段可以在这里看到: https : //skyviewcafe.com/
export const BACKGROUND_ANIMATIONS = trigger('displayState', [
state('error', style({ backgroundColor: getBackgroundColor(ERROR_BACKGROUND, '#F67') })),
state('normal', style({ backgroundColor: getBackgroundColor(NORMAL_BACKGROUND, 'white') })),
state('confirm', style({ backgroundColor: getBackgroundColor(CONFIRM_BACKGROUND, '#6C6') })),
state('warning', style({ backgroundColor: getBackgroundColor(WARNING_BACKGROUND, '#FC6') })),
state('view-only', style({ backgroundColor: getBackgroundColor(VIEW_ONLY_BACKGROUND, 'black') })),
state('disabled', style({ backgroundColor: getBackgroundColor(DISABLED_BACKGROUND, '#CCC') })),
state('dark-error', style({ backgroundColor: getBackgroundColor(ERROR_BACKGROUND, '#C36', true) })),
state('dark-normal', style({ backgroundColor: getBackgroundColor(NORMAL_BACKGROUND, '#333', true) })),
state('dark-confirm', style({ backgroundColor: getBackgroundColor(CONFIRM_BACKGROUND, '#292', true) })),
state('dark-warning', style({ backgroundColor: getBackgroundColor(WARNING_BACKGROUND, '#B80', true) })),
state('dark-view-only', style({ backgroundColor: getBackgroundColor(VIEW_ONLY_BACKGROUND, '#0A0', true) })),
state('dark-disabled', style({ backgroundColor: getBackgroundColor(DISABLED_BACKGROUND, '#444', true) })),
transition('normal => error', animate(FLASH_DURATION)),
transition('error => normal', animate(FLASH_DURATION)),
transition('normal => confirm', animate(FLASH_DURATION)),
transition('confirm => normal', animate(FLASH_DURATION)),
transition('warning => error', animate(FLASH_DURATION)),
transition('error => warning', animate(FLASH_DURATION)),
transition('dark-normal => dark-error', animate(FLASH_DURATION)),
transition('dark-error => dark-normal', animate(FLASH_DURATION)),
transition('dark-normal => dark-confirm', animate(FLASH_DURATION)),
transition('dark-confirm => dark-normal', animate(FLASH_DURATION)),
transition('dark-warning => dark-error', animate(FLASH_DURATION)),
transition('dark-error => dark-warning', animate(FLASH_DURATION))
]);
The above animations are defined in an abstract superclass so that concrete subclasses can use them like this:上面的动画定义在一个抽象的超类中,以便具体的子类可以像这样使用它们:
@Component({
selector: 'tbw-time-editor',
animations: [BACKGROUND_ANIMATIONS],
templateUrl: '../digit-sequence-editor/digit-sequence-editor.directive.html',
styleUrls: ['../digit-sequence-editor/digit-sequence-editor.directive.scss', './time-editor.component.scss'],
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimeEditorComponent), multi: true },
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => TimeEditorComponent), multi: true }]
})
export class TimeEditorComponent extends DigitSequenceEditorDirective<number> implements OnInit {
...
First of all, I'd prefer to cut the number of display states in half.首先,我更愿意将显示状态的数量减少一半。 I consider it a hack to have to have all of those
dark_
-prefixed states.我认为必须拥有所有这些
dark_
前缀状态是一种黑客行为。 I'd rather have these colors automatically update, as they do for DOM elements, simply by adding the tbw-dark-mode
class to the body of my HTML document.我宁愿让这些颜色自动更新,就像它们对 DOM 元素所做的那样,只需将
tbw-dark-mode
类添加到我的 HTML 文档的正文中即可。
I'm also limited to supporting only the two pre-defined modes, light and dark.我也仅限于支持两种预定义的模式,亮和暗。 Users can customize both the light mode and the dark mode, but a third mode, or generalized "skins" would be impossible.
用户可以自定义亮模式和暗模式,但第三种模式或通用“皮肤”是不可能的。
Timing also matters.时机也很重要。 These colors are generated once during the initialization of the application in which my components are embedded, and I see no access to an Angular API that allows these state definitions to be updated later.
这些颜色在嵌入我的组件的应用程序的初始化期间生成一次,并且我看不到对允许这些状态定义稍后更新的 Angular API 的访问。
The function getBackgroundColor()
at least allows me to check once how colors have been defined at start-up, but it's not perfect (iOS Safari messes up and thinks everything is transparent), so I have to define fixed fallback values which can't be updated from a style sheet.函数
getBackgroundColor()
至少允许我在启动时检查颜色是如何定义的,但它并不完美(iOS Safari 搞砸了,认为一切都是透明的),所以我必须定义固定的后备值,这些值不能从样式表更新。
I did discover a disgusting hack to get some dynamic updating of colors, but it's not something I'd want to rely on!我确实发现了一个令人作呕的 hack 来动态更新颜色,但这不是我想要依赖的东西! Instead of using a string for each color, I defined a dynamic color object like this:
我没有为每种颜色使用一个字符串,而是定义了一个动态颜色对象,如下所示:
class DynamicColor extends String {
constructor(private colorKey: string) {}
// ...
toString(): string {
return this.colorTable[colorKey];
}
}
Even that requires some forced type coercion to string
, and forced screen refreshing to make changes take effect.即便如此,也需要对
string
一些强制类型强制,并强制刷新屏幕以使更改生效。
Is there a better way?有没有更好的办法? A way to use CSS classes instead of statically-defined styles?
一种使用 CSS 类而不是静态定义样式的方法? An API I haven't found yet to update the animations which are installed by the
@Component
decorator?我还没有找到更新
@Component
装饰器安装的动画的 API?
Why not use CSS variables for the colors?为什么不为颜色使用 CSS 变量?
https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
You can then just change, for example the background color from --color-1
to --color-2
in the state animations.然后,您可以更改,例如在状态动画中将背景颜色从
--color-1
更改为--color-2
。
And in a separate part of your application you can change the definitions of these variables using something like this:在应用程序的单独部分中,您可以使用如下方式更改这些变量的定义:
@Component({ /*…*/ })
export class MyComponent {
@HostBinding("style.--color-1")
private color1: string;
changeColor1(value: string) {
this.color1 = value;
}
}
Note: Support for CSS variables is pretty good as long as you don't need to support IE: https://caniuse.com/css-variables注意:只要不需要支持 IE,对 CSS 变量的支持就不错了: https : //caniuse.com/css-variables
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.