How to make a image rotation (click : 0° -> 180° / click again : 180° -> 0°) on image button with Angular 4 ?
I use Angular Material too.
This is my button :
<!-- Button open left menubar -->
<button md-icon-button class="left-menubar-button" (click)="start.toggle()">
<md-icon class="md-custom-theme-gray">label_outline</md-icon>
</button>
This button will open a sidenav, and I want to animate it to get more userfriendly
Thanks
You do not need material as Angular brings built in animations. Here goes an example:
import { Component } from '#angular/core';
import { trigger, state, style, animate, transition } from '#angular/animations';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
// Each unique animation requires its own trigger. The first argument of the trigger function is the name
trigger('rotatedState', [
state('default', style({ transform: 'rotate(0)' })),
state('rotated', style({ transform: 'rotate(-180deg)' })),
transition('rotated => default', animate('1500ms ease-out')),
transition('default => rotated', animate('400ms ease-in'))
])
]
})
export class AppComponent {
state: string = 'default';
rotate() {
this.state = (this.state === 'default' ? 'rotated' : 'default');
}
}
And in template:
<button (click)="rotate()">Press me to rotate</button>
And make sure to add binding to tag you are operating on:
<img [#rotatedState]='state' />
In addition make sure you import the animation module to your app like so:
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#NgModule({
...,
imports: [
...,
BrowserAnimationsModule
],
...
})
Check stackblitz with working example
Related
I want to switch between two classes (light and dark) at TAG Body.
What I did? I created a service:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class ThemeService {
body = document.body;
constructor() { }
changeLight() {
this.body.classList.replace('light', 'dark');
}
changeDark() {
this.body.classList.replace('dark', 'light');
}
}
It is working as expected but I know that this code does not use best practices.
What is the correct way to change between these two classes?
Edit: Added a service to the stackblitz, but again, there are many ways to do this. This is just a starting point.
While the "right way" is subjective, you have some options to make it "Angular-y"
Component:
import { Component, Inject } from '#angular/core';
import { DOCUMENT } from '#angular/common';
// Create a type that accepts either the string 'light' or 'dark' only
type Theme = 'light' | 'dark';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
// Default to 'light' theme
currentTheme: Theme = 'light';
// Inject document which is safe when used with server-side rendering
constructor(#Inject(DOCUMENT) private document: Document) {
// Add the current (light) theme as a default
this.document.body.classList.add(this.currentTheme);
}
// Swap them out, and keep track of the new theme
switchTheme(newTheme: Theme): void {
this.document.body.classList.replace(this.currentTheme, newTheme)
this.currentTheme = newTheme;
}
}
HTML:
<p>
Current theme: {{ currentTheme }}
<button (click)="switchTheme('light')">Light mode</button>
<button (click)="switchTheme('dark')">Dark mode</button>
</p>
Many ways to do this, but one benefit of defining the types is if you provide a bad value, such as:
<p>
Current theme: {{ currentTheme }}
<button (click)="switchTheme('light')">Light mode</button>
<button (click)="switchTheme('dark')">Dark mode</button>
<button (click)="switchTheme('noop')">Invalid</button>
</p>
You'll get an error:
Argument of type '"noop"' is not assignable to parameter of type 'Theme'.
StackBlitz
app.component.ts
<div>
<app-head></app-head>
<app-body></app-body>
</div>
head.component.ts
...
#Component({
selector: 'app-head',
templateUrl: './head.component.html',
styleUrls: ['./head.component.scss'],
providers: []
})
...
body.component.ts
...
#Component({
selector: 'app-body',
templateUrl: './body.component.html',
styleUrls: ['./body.component.scss'],
providers: []
})
...
So the pages loads with content head + body but now I wanted to route to a different page and replace entire existing page with the new page. How do I do that?
In my app.module.ts I have the following...
const routes: Routes = [
{ path: 'newPage', component: NewComponent}
]
I wanted use when clicked a button to be redirected to this page and replace existing <app-head> and <app-body> is this possible?
If I just use below I still see the current <app-head> and <app-body>
<button type="button" (click)="loadNewPage()" >
body.component.ts
loadNewPage() {
this.router.navigate(['/newPage']);
}
The results give me the current page.... and doesnt really apply since I am not concating the contents together. I want to replace the head.html and body.html with newpage.html from the NewComponent.ts
You need to replace the content in AppComponent with a router-outlet component and move that replaced content to a new component such as HomeComponent. Use the HomeComponent in your default route so it will load when you initially visit the site.
It's probably best if you check the documentation for Routing & Navigation since this is a pretty fundamental topic in Angular and there are a lot of details you should learn before you get too far.
App.component.html
<router-outlet></router-outlet>
home.component.html
<div>
<app-head></app-head>
<app-body></app-body>
</div>
app-routing.module.ts
const routes: Routes = [
{ path: '', component: HomeComponent }
{ path: 'newPage', component: NewComponent}
]
You will want to put a <router-outlet></router-outlet> in your app component and move what's in your current app component to a new component. Then update your routes to:
const routes: Routes = [
{ path: '', component: TheStuffYouMovedComponent },
{ path: 'newPage', component: NewComponent }
]
I am using this angular ng2 slide menu library. Can you please suggest me how to close the menu after selecting any item.
The configuration says there is an option. Not sure how to configure the value.
Thanks,
Raja K
as per angular ng2 slide library documentation
in your template you add config attribute, like
<cuppa-slidemenu
[menulist]="menuItemsArray"
[config]="config"
(open)="onMenuOpen()"
(close)="onMenuClose()"
(onItemSelect)="onItemSelect($event)">
</cuppa-slidemenu>
and in your ts file, you can define config, as shown in documentation.
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
config = {
closeOnCLick: true
};
}
here is a live working demo
I have noticed that the directive (swipeup) does not seem to be working:
I have tried using (swipeleft) and that works:
<div [#myAnimation] (swipeup)="showActionBar = false" fxFlex="56px" *ngIf="showActionBar" fxLayoutWrap fxLayoutAlign="start center"fxLayoutGap="8px" class="overview-actions">
Does anyone have a solution / work-around for this. I have looked but didn't find a solution linked to my problem.
Thank you,
J.
You can import the hammer config from #angular/platform-browser and override it. Swipe up and down are off by default as they can cause issues for the user when they are trying to scroll.
app.module.ts
import * as Hammer from 'hammerjs';
import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '#angular/platform-browser';
export class HammerConfig extends HammerGestureConfig {
overrides = <any>{
'swipe': { direction: Hammer.DIRECTION_ALL }
};
}
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [
{
provide: HAMMER_GESTURE_CONFIG,
useClass: HammerConfig
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
According to this can you try this?
var hammertime = new Hammer(document.body);
hammertime.get('swipe').set({ direction: Hammer.DIRECTION_ALL });
And according to the documentation
"By default it adds a set of tap, doubletap, press, horizontal pan and swipe, and the multi-touch pinch and rotate recognizers. The pinch and rotate recognizers are disabled by default because they would make the element blocking, but you can enable them by calling:
hammertime.get('pinch').set({ enable: true });
hammertime.get('rotate').set({ enable: true });
Enabling vertical or all directions for the pan and swipe recognizers:
hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammertime.get('swipe').set({ direction: Hammer.DIRECTION_VERTICAL });
What I want to do is when I hover on the 'click me' button then it should show an image on the web page and when i unhover it should not show any image with the help of mouseover option
here is what i tried to do in app.component.ts and my.component.ts files
here is the code for app.component.ts :
import { Component } from '#angular/core'; //importing components from angular
import { MyComponent } from './my.component'; //importing components from my.component
#Component({
selector: 'my-app',
template: `<h1> Hi Buddy!! </h1>
<mytag></mytag>`,
directives: [MyComponent] //adding directives from mycomponents
})
export class AppComponent { }
and here is the code for my.component.ts:
import { Component } from "#angular/core";
#Component({
selector:'mytag',
template: `<button (mouseover)="<img [src]="image"> " >click me</button>` // here i tried to flash image by hovering
})
export class MyComponent{
public image="http://lorempixel.com/400/200";
myclick(klm){
console.log(klm);
}
}
so what changes should i make in the class or meta data of my.component.ts in order to do so
You can use Angular Animations module to achieve the same.
Make the below changes to your MyComponent:
import { Component } from '#angular/core'
import { trigger, state, style, transition, animate, keyframes, group } from '#angular/animations';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#Component({
selector:'mytag',
template: `<button (mouseover)="toggleOnOff()">click me</button>
<img [src]="image" [#switchImageDisplay]="showImage"/>
`
,
animations: [
trigger("switchImageDisplay",[
state("show", style({
display : 'block'
})),
state("hide", style({
display : 'none'
})),
transition('show <-> hide',[animate('0s')]),
])
]
})
export class SwitchDisplayComponent {
public image="http://lorempixel.com/400/200";
public showImage : string;
toggleOnOff(){
console.log("Previous display value is",this.showImage);
this.showImage = (this.showImage === "show") ? "hide" : "show";
console.log("Current display value is",this.showImage);
}
}
Explanation:
toggleOnOff() function sets a string variable showImage as show and hide.
In Animations we create a trigger and give it a name. In our case we have named it as "switchImageDisplay". We declared two states in the animation trigger that is "show" and "hide". In those states we defined what CSS to be used. Finally we defined a transition, which is 2 ways binded and is performed in 0 seconds. If you want the image to be hidden over a period of time increase the time.
In template code, we have binded the img tag to the animation using the code [#switchImageDisplay]="showImage". Based on the "showImage" value, the animation "switchImageDisplay"'s state is defined.
Import the import { BrowserAnimationsModule } from '#angular/platform-browser/animations'; in your app.module.ts and in the imports array as well.