How to handle resizing the screen with Angular Animations? - javascript

How do you handle resizing the window with Angular Animations properties like width?
For example:
This code will animate the width of an element and for all sizes will not flood off screen or look too small.
Desktop:
mobile:
Until the user resizes the screen. On resize the animation is completed and therefore will not react to the window resize.
function setEndWidth() {
if(MatchMediaService.bp('sm')){
return '70vw';
} else {
return '30vw';
}
}
function setStartWidth() {
if(MatchMediaService.bp('sm')){
return '0px';
} else {
return '20vw';
}
}
#Component({
moduleId: module.id,
selector: 'menu-container',
templateUrl: 'menu.html',
styleUrls: ['./menu.scss'],
animations: [
trigger('goodmorning', [
state('void', style({
'width': '0',
'transform': 'rotate(0)',
'transform-origin': '0 0'
})),
state('harwood', style({
'width': setEndWidth(),
'transform': 'rotate(-30deg)',
'transform-origin': '0 0'
})),
transition('void => *', animate(2000, keyframes([
style({
'width': '0',
'transform': 'rotate(0)',
'transform-origin': '0 0'
}),
style({
'width': setStartWidth(),
'transform': 'rotate(0)',
'transform-origin': '0 0'
}),
style({
'width': setEndWidth(),
'transform': 'rotate(-30deg)',
'transform-origin': '0 0'
})
]))),
transition('void => *', animate('2.5s 0s cubic-bezier(0.455, 0.03, 0.515, 0.955)'))
])
]
})
HTML:
<line-thing [#goodmorning]="'harwood'"></line-thing>

Related

Heartland payment integration iframe refresh on react state update

I am integrating heartland as a payment gateway in my application.
Here's my code.
When I try to update the zip code it will rerender and update the amount.
I want to update the value of fields: submit: value of embedded HPS.
Currently, it's in componentDidUpdate so it is now duplicating the fields as well.
How update the value and keep all the state including card, CVV, etc details?
I don't have any state value of these fields and once I somehow rerender the component it will vanish the field values.
Heartland Documentation
componentDidUpdate() {
console.log('render')
this.state.hps = new Heartland.HPS({
publicKey: 'pkapi_cert_jKc1FtuyAydZhZfbB3',
type: 'iframe',
// Configure the iframe fields to tell the library where
// the iframe should be inserted into the DOM and some
// basic options
fields: {
cardNumber: {
target: 'iframesCardNumber',
placeholder: '•••• •••• •••• ••••'
},
cardExpiration: {
target: 'iframesCardExpiration',
placeholder: 'MM / YYYY'
},
cardCvv: {
target: 'iframesCardCvv',
placeholder: 'CVV'
},
submit: {
value: `Pay ${this.state.amount}` || "Pay 0",
target: 'iframesSubmit'
}
},
// Collection of CSS to inject into the iframes.
// These properties can match the site's styles
// to create a seamless experience.
style: {
'input': {
'background': '#fff',
'border': '1px solid',
'border-color': '#bbb3b9 #c7c1c6 #c7c1c6',
'box-sizing': 'border-box',
'font-family': 'serif',
'font-size': '16px',
'line-height': '1',
'margin': '0 .5em 0 0',
'max-width': '100%',
'outline': '0',
'padding': '0.5278em',
'vertical-align': 'baseline',
'height' : '50px',
'width' : '100% !important'
},
'#heartland-field': {
'font-family':'sans-serif',
'box-sizing':'border-box',
'display': 'block',
'height': '50px',
'padding': '6px 12px',
'font-size': '14px',
'line-height': '1.42857143',
'color': '#555',
'background-color': '#fff',
'border': '1px solid #ccc',
'border-radius': '0px',
'-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
'-webkit-transition': 'border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s',
'-o-transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
'transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
'width' : '100%'
},
'#heartland-field[name=submit]': {
'background-color':'#36b46e',
'font-family':'sans-serif',
'text-transform':'uppercase',
'color':'#ffffff',
'border':'0px solid transparent'
} ,
'#heartland-field[name=submit]:focus': {
'color':'#ffffff',
'background-color':'#258851',
'outline':'none'
} ,
'#heartland-field[name=submit]:hover': {
'background-color':'#258851'
} ,
'#heartland-field-wrapper #heartland-field:focus' : {
'border':'1px solid #3989e3',
'outline':'none',
'box-shadow':'none',
'height':'50px'
},
'heartland-field-wrapper #heartland-field' : {
'height':'50px'
},
'input[type=submit]' : {
'box-sizing':'border-box',
'display': 'inline-block',
'padding': '6px 12px',
'margin-bottom': '0',
'font-size': '14px',
'font-weight': '400',
'line-height': '1.42857143',
'text-align': 'center',
'white-space': 'nowrap',
'vertical-align': 'middle',
'-ms-touch-action': 'manipulation',
'touch-action': 'manipulation',
'cursor': 'pointer',
'-webkit-user-select': 'none',
'-moz-user-select': 'none',
'-ms-user-select': 'none',
'user-select': 'none',
'background-image': 'none',
'border': '1px solid transparent',
'border-radius': '4px',
'color': '#fff',
'background-color': '#337ab7',
'border-color': '#2e6da4'
},
'#heartland-field[placeholder]' :{
'letter-spacing':'3px'
},
'#heartland-field[name=cardCvv]' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/cvv1.png?raw=true) no-repeat right',
'background-size' :'63px 40px',
},
'input#heartland-field[name=cardNumber]' : {
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-inputcard-blank#2x.png?raw=true) no-repeat right',
'background-size' :'55px 35px'},
'#heartland-field.invalid.card-type-visa' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-visa#2x.png?raw=true) no-repeat right',
'background-size' :'83px 88px',
'background-position-y':'-44px'
},
'#heartland-field.valid.card-type-visa' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-visa#2x.png?raw=true) no-repeat right top',
'background-size' :'82px 86px'
},
'#heartland-field.invalid.card-type-discover' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-discover#2x.png?raw=true) no-repeat right',
'background-size' :'85px 90px',
'background-position-y' : '-44px'
},
'#heartland-field.valid.card-type-discover' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-discover#2x.png?raw=true) no-repeat right',
'background-size' :'85px 90px',
'background-position-y' : '1px'
},
'#heartland-field.invalid.card-type-amex' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-savedcards-amex#2x.png?raw=true) no-repeat right',
'background-size' :'50px 90px',
'background-position-y':'-44px'
},
'#heartland-field.valid.card-type-amex' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-savedcards-amex#2x.png?raw=true) no-repeat right top',
'background-size' :'50px 90px'
},
'#heartland-field.invalid.card-type-mastercard' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-mastercard.png?raw=true) no-repeat right',
'background-size' :'62px 105px',
'background-position-y':'-52px'
},
'#heartland-field.valid.card-type-mastercard' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-mastercard.png?raw=true) no-repeat right',
'background-size' :'62px 105px',
'background-position-y':'-1px'
},
'#heartland-field.invalid.card-type-jcb' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-jcb#2x.png?raw=true) no-repeat right',
'background-size' :'55px 94px',
'background-position-y':'-44px'
},
'#heartland-field.valid.card-type-jcb' :{
'background':'transparent url(https://github.com/hps/heartland-php/blob/master/examples/end-to-end/assets/images/ss-saved-jcb#2x.png?raw=true) no-repeat right top',
'background-size' :'55px 94px',
'background-position-y':'2px'
},
'input#heartland-field[name=cardNumber]::-ms-clear' : {
'display':'none'
}
},
// Callback when a token is received from the service
onTokenSuccess: function (resp) {
alert('Here is a single-use token: ' + resp.token_value);
},
// Callback when an error is received from the service
onTokenError: function (resp) {
alert('There was an error: ' + resp.error.message);
},
// Callback when an event is fired within an iFrame
onEvent: function (ev) {
console.log(ev);
}
});
}

Creating a slide in animation with the Angular ng-content element

I'm trying to create a component that will slide in content projected with ng-content (This is the Stackblitz).
This is the animation.
import {
trigger,
state,
style,
transition,
animate,
group,
} from '#angular/animations';
export const SlideInOutAnimation = [
trigger('slideInOut', [
state(
'in',
style({
height: '100%',
opacity: '1',
visibility: 'visible',
})
),
state(
'out',
style({
height: '0px',
opacity: '0',
visibility: 'hidden',
})
),
transition('in => out', [
group([
animate(
'400ms ease-in-out',
style({
opacity: '0',
})
),
animate(
'600ms ease-in-out',
style({
'max-height': '0px',
})
),
animate(
'700ms ease-in-out',
style({
visibility: 'hidden',
})
),
]),
]),
transition('out => in', [
group([
animate(
'1ms ease-in-out',
style({
visibility: 'visible',
})
),
animate(
'600ms ease-in-out',
style({
height: '100%',
})
),
animate(
'800ms ease-in-out',
style({
opacity: '1',
})
),
]),
]),
]),
];
And this is the HelloComponent refactored to use the animation.
import {
Component,
Input,
OnChanges,
SimpleChanges,
ViewEncapsulation,
} from '#angular/core';
import { SlideInOutAnimation } from './animation';
#Component({
animations: [SlideInOutAnimation],
selector: 'hello',
template: `<ng-content [#slideInOut]="animationState"></ng-content>`,
styles: [
`hello { position: absolute;
background: red;
height: 0px;
bottom: 0;
visibility: hidden;
}`,
],
encapsulation: ViewEncapsulation.None,
})
export class HelloComponent implements OnChanges {
#Input() animationState: string = 'in';
ngOnChanges(changes: SimpleChanges) {
console.log(changes.animationState);
}
}
When the animationState is toggled it is logged in the console. However, the projected content does not animate in.
Any ideas?
As suggested by Andrei in the comments I use #HostBinding instead and now it works.
#HostBinding('#slideInOut')
get currentAnimationState() {
return this.animationState;
}
This is a new Stackblitz with the working demo.

Animating the Removal of a dynamic Angular Component?

In this stackblitz demo when we click Create success the components view display is animated (From opacity 0 to opacity 1 over 5 seconds.).
If we clear the container (this.container.clear()) the removal of the element is not animated. The animations attribute looks like this:
animations: [
trigger('fadeInOut', [
transition(':enter', [
style({ opacity: 0 }),
animate(5000, style({ opacity: 1 }))
]),
transition(':leave', [
animate(5000, style({ opacity: 0 }))
])
])
],
How would we enable the triggering of the leave animation in this case?
Update your alert.component.ts to this:
import { Component, Input, EventEmitter, Output } from '#angular/core';
import { trigger, style, animate, transition } from '#angular/animations';
#Component({
selector: "alert",
template: `
<section [#fadeInOut]>
<h1 (click)="output.next('output')">Alert {{type}}</h1>
<section>
`,
styles: [`
:host {
display: block;
overflow: hidden;
}`],
animations: [
trigger('fadeInOut', [
transition(':enter', [
style({ opacity: 0 }),
animate(5000, style({ opacity: 1 }))
]),
transition(':leave', [
animate(5000, style({ opacity: 0 }))
])
])
],
host: { '[#fadeInOut]': 'in' }
})
export class AlertComponent {
#Input() type: string = "success";
#Output() output = new EventEmitter();
}
Thanks to https://stackblitz.com/edit/angular-animate-dynamically-created-component?file=app%2Fhello.component.ts

Angular 2 animations pass an Input

I need a way to configure my animations dynamically. For example, I want my consumer to be able to pass as Input of the numbers of the animate declaration or any CSS property.
animations: [
trigger('heroState', [
state('inactive', style({
backgroundColor: '#eee',
transform: this.transform
})),
state('active', style({
backgroundColor: '#cfd8dc',
transform: this.transform
})),
transition('inactive => active', animate(this.animateInActive),
transition('active => inactive', animate('100ms ease-out'))
])
]
class Cmp {
#Input() transform = 'scale(1)';
#Input() animateInActive = '200ms ease-out';
}

Angular 2 - Add animation handler directly on the selector

In all the angular 2 API animation examples, the animation handler is implemented on innerHtml,
I would like to put it directly on the component selector.
In the example below, [#visibility]="visibility" is on the div tag, but I want it on the selector: 'vps-node' so my template is simply <ng-content> with out the parent div tag
#Component({
selector: 'vps-node',
template: `<div [#visibility]="visibility"><ng-content></ng-content></div>`,
animations: [
trigger('visibility', [
state('in', style({ transform: 'translateX(0)' })),
transition('void => *', [
animate(300, keyframes([
style({ opacity: 0, transform: 'translateX(-100%)', offset: 0 }),
style({ opacity: 1, transform: 'translateX(15px)', offset: 0.3 }),
style({ opacity: 1, transform: 'translateX(0)', offset: 1.0 })
]))
]),
transition('* => void', [
animate(300, keyframes([
style({ opacity: 1, transform: 'translateX(0)', offset: 0 }),
style({ opacity: 1, transform: 'translateX(-15px)', offset: 0.7 }),
style({ opacity: 0, transform: 'translateX(100%)', offset: 1.0 })
]))
])
])
]
})
Thought i'd share this but I have managed to make the animation trigger on the host element.
Check the following code where I handle page transitions.
#Component({
selector: 'styles',
templateUrl: './styles.template.html',
host: {
'(#routeAnimation.start)': 'pageEnterStarted($event)',
'(#routeAnimation.done)': 'pageEnterCompleted($event)',
'[#routeAnimation]': 'true',
},
animations: [
trigger('routeAnimation', [
state('*', style({ opacity: 1})),
transition('void => *', [
style({ opacity: 0}),
animate(250)
]),
transition('* => void', animate(250, style({opacity: 0})))
])
]
})
export class StylesComponent {
pageEnterStarted() {
}
pageEnterCompleted() {
}
}
Turns out the host:property needed to be in a bracket.
host: { '[ #visibility ]': 'visibility' },
selector: 'vps-row-node',
host: { '[#visibility]': 'visibility' },
template: `<ng-content></ng-content>`,
animations: [...]

Categories

Resources