0

I created a CSS keyframe animation for a form field to expand on focus via scaleX.


@keyframes formField {
  0% {
    transform: scaleX(1);
  }

  50% {
    transform: scaleX(1.03);
  }

  80% {
    transform: scaleX(.98);
  }

  100% {
    transform: scaleX(1);
  }
}

But the drawback is since form fields are different widths, they expand different amounts. My client would like all the form fields to expand the same amount (e.g. 10 px) regardless of their width. So I can't use scaling by a factor (e.g. scaleX(1.03)).

So, I don't think I can use CSS transforms for this.

Next, I thought I might create an Angular directive that gets the pixel width of the object it's applied to, increment the width by 10px and return it to the original width, with transitions.

Edit

So I have created this directive:

import { ElementRef, HostListener, Component } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations';

@Component({
  /* tslint:disable-next-line:component-selector */
  selector: '[focusField]',
  animations: [
    trigger('isFocused', [
      transition('*<=> *', [
        style({ transform: 'scaleX(1)' }),
        animate(200, style({ transform: `scaleX(${this.scaleFactor})` }))
      ])
    ])
  ],
  template: `
    <ng-content></ng-content>
  `
})
/* tslint:disable-next-line:component-class-suffix */
export class FocusFieldDirective {
  constructor(private _elementRef: ElementRef) {}

  fieldWidth: number;
  scaleFactor: number;

  @HostListener('focus', ['$event'])
  onFocusField(event: MouseEvent): void {
    this.fieldWidth = this._elementRef.nativeElement.offsetWidth;
    this.scaleFactor = this.fieldWidth + 10 / this.fieldWidth;
  }
}

On focus on the input field with the directive applied, I correctly get the element's width and the scale factor. However, I'm getting an error trying to use the scaleFactor in the animation, with this line:

animate(200, style({ transform: `scaleX(${this.scaleFactor})` }))

The error thrown: TypeError: undefined is not an object (evaluating 'this.scaleFactor')

Steve
  • 14,401
  • 35
  • 125
  • 230
  • Hello. As far as i know can build your own directive for that. In a directive you have access to the element can you can calculate the needed ratio for your fixed px increasement. You also can add animations to the element: https://stackoverflow.com/questions/42878197/angular-2-how-to-set-animations-on-a-directive – MullisS Apr 02 '19 at 14:28
  • I saw that post. But It still looked like to change the properties of the element you use a CSS transform — not an element width in px. I realize can can access the width from the DOM and increment it, but not with a css transition. – Steve Apr 02 '19 at 14:32
  • 1
    You can simply archive that by calculation the ratio you need. For example you want your elements to scale up 10 px (height): `scaleFactor = (elementHeight + 10 / elementHeight)`. – MullisS Apr 02 '19 at 14:36
  • @MullisS I'm having an issue applying the variable to the animation style property... please see updated question. – Steve Apr 02 '19 at 15:26
  • Hello. This is not a directive (https://angular.io/guide/attribute-directives). You made a Component. The right solution is to build a directive and use it for your component or any other html element. – MullisS Apr 02 '19 at 15:34
  • I followed the instructions at https://stackoverflow.com/questions/42878197/angular-2-how-to-set-animations-on-a-directive since, as it says in that question, you cannot apply animations to a directive. So, you can fake a directive with a component without a template. – Steve Apr 02 '19 at 15:37
  • @MullisS Everything works as expected _except_ the line I noted: using the scale factor in the `style` of the animation. – Steve Apr 02 '19 at 15:43
  • Hello. Here is a working solution with a directive: https://stackblitz.com/edit/angular-cimvzk?file=src%2Fapp%2Fapp.component.html – MullisS Apr 02 '19 at 15:56
  • OK, using AnimationBuilder. I'm not familiar with that. Thanks. – Steve Apr 02 '19 at 15:59

0 Answers0