trying to do a gallery with lightbox but does not pop up - html

I'm new on angular,
And I'm trying to make a gallery with a lighbox that shows up when an image is clicked.
I already try the examples with bootstrap and also tried to do it by myself, but when I click on the img-link, the links throws me up to the home page maybe there is a config that I didn't know how to use it or is missing.
I don't know if its a problem about routes or if I need to do other commponent for that.
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
import { Component, OnInit } from '#angular/core';
import { CuadrosService, Cuadro } from '../cuadros.service';
#Component({
selector: 'app-galeria',
templateUrl: './galeria.component.html',
styleUrls: ['./galeria.component.css']
})
export class GaleriaComponent implements OnInit {
Cuadro:any [] = [];
constructor(private _cuadosService:CuadrosService ) {
console.log("constructor")
}
ngOnInit(): void {
this.Cuadro = this._cuadosService.getCuadros();
console.log(this.Cuadro);
}
}
.container-galeria {
display: flex;
flex-wrap: wrap;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 400px;
background-color: rgba(0, 0, 0, .80);
justify-content: space-around;
}
.img-galeria {
width: 100%;
height: 100%;
object-fit: cover;
padding: 10px;
}
.img-galeria:hover {
transform: scale(1.05);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);
}
.item-galeria:nth-child(1) {
grid-column-start: span 2;
}
.item-galeria:nth-child(2) {
grid-row-start: span 2;
}
.lightbox {}
.lightbox:active {
display: block;
position: fixed;
flex-wrap: wrap;
height: fit-content;
width: fit-content;
max-width: 1200px;
max-height: 800px;
background-color: rgba(0, 0, 0, 0.3);
z-index: 2000;
justify-content: center;
}
<hr>
<div class="container-galeria container">
<div class=" lighbox item-galeria col-4" *ngFor="let cuadro of Cuadro">
<img class="img-galeria" [src]="cuadro.foto" alt="">
</div>
</div>
<app-footer></app-footer>
Any idea? or somthing wrong in my code?
Thanks for the help.

So the way I am seeing it your lightbox is missing a t in the class name.
Secondly I would set a onclick listener for each image to remove and set an active class instead of using the :active css selector. The css selector :active will be removed as soon as the person stops clicking.
You will have to Pass your Element in to the function to determine what image will be active.
Also you might want to add a function to exit the active mode
<div class="lightbox item-galeria col-4" *ngFor="let cuadro of Cuadro" (click)="toggleActive($event, item)">
<img class="img-galeria" [src]="cuadro.foto" alt="">
</div>
The function:
import { Component, OnInit } from '#angular/core';
import { CuadrosService, Cuadro } from '../cuadros.service';
#Component({
selector: 'app-galeria',
templateUrl: './galeria.component.html',
styleUrls: ['./galeria.component.css']
})
export class GaleriaComponent implements OnInit {
Cuadro:any [] = [];
constructor(private _cuadosService:CuadrosService ) {
console.log("constructor")
}
ngOnInit(): void {
this.Cuadro = this._cuadosService.getCuadros();
console.log(this.Cuadro);
}
toggle(event, item): void {
if(item.classList.contains("active")){
item.classList.remove("active"));
}else{
item.classList.add("active"));
}
}
I might add that I didn't test the code and some parts of code may need a little tweak.
I hope I could help.

Related

Is there a way to change the appeareance of an html text when hovering on the div that contains it?

I need to color and zoom the text when the cursor "approaches" the text (so basically when the mouse enters the area of the div surrounding the text). Right now i can make it work coloring the text only when i hover directly on it. I'll paste a snippet of the code.
HTML:
<div fxLayout="row wrap" class="max container">
<div fxFlex="100%" fxLayoutAlign="center">
<!--here there is an image-->
</div>
<div fxFlex="100%" class="centered-text" fxHide fxShow.gt-lg>
<h2 [ngClass]="{'gradient' : this.gradient,'lighter':lighter, 'zoom':zoom, 'scale':1.2}" style="margin: 0;" class="font">
hoverMe
</h2>
</div>
</div>
Typescript:
import {Component, Input, OnInit} from '#angular/core';
#Component({
selector: 'iet-box-academy',
templateUrl: './box-academy.component.html',
styleUrls: ['./box-academy.component.scss']
})
export class BoxAcademyComponent implements OnInit {
#Input() scale = 1;
#Input() img = '';
#Input() title = 'TITOLO';
#Input() descr = '';
#Input() align = "centerer";
#Input() lighter = false;
#Input() zoom = true;
#Input() gradient: boolean = false;
constructor() {
}
ngOnInit(): void {
}
}
CSS:
.container {
position: relative;
text-align: center;
color: black;
}
.zoom {
transition: transform .2s; /* Animation */
margin: 0 auto;
}
.zoom:hover {
transform: scale(1.5);
color: #00D3FF;
}
https://jsfiddle.net/wdfc7g9a/14/
You can add the :hover to the parent and add a child selector:
Change:
.zoom:hover {
transform: scale(1.5);
color: #00D3FF;
}
To:
.container:hover .zoom {
transform: scale(1.5);
color: #00D3FF;
}
Demo:
.container {
border: 1px solid red;
}
.container:hover .zoom {
background: yellow;
}
<div class="container">
This is a text
<div class="zoom">highlight this text</div>
More text
</div>
I recommend you to use centered-text class instead of zoom class. Because it is easier to give a transparent padding to it so you can have the "approaching" animation played without needing to hover directly on the text.
This code will fix your problem the moment you copy paste it to your Custom CSS:
.centered-text {
transition: all 0.3s;
margin: 0 auto;
padding:13px;
}
.centered-text:hover {
transform: scale(1.4);
color: #00D3FF;
transition: all 0.3s;
}

How to add line break to custom tooltip directive using angular 7

I am new to angular 7 directives. I created a custom tooltip directive using angular 7. Now, I am unable to specify line breaks when i pass the tooltip text from my html. I want a line break after the Tootltip Title text I pass from html. Any idea how to achieve this?
Tried to pass
and 
 code for line break in my input string to the tooltip directive. Didn't work either.
Here is what I tried so far.
My directive : tooltip.directive.ts:
import { Directive, Input, ElementRef, HostListener, Renderer2 } from '#angular/core';
#Directive({
selector: '[tooltip]'
})
export class TooltipDirective {
#Input('tooltip') tooltipTitle: string;
#Input() placement: string;
#Input() delay: number;
tooltip: HTMLElement;
offset = 10;
constructor(private el: ElementRef, private renderer: Renderer2) { }
#HostListener('mouseenter') onMouseEnter() {
if (!this.tooltip) { this.show(); }
}
#HostListener('mouseleave') onMouseLeave() {
if (this.tooltip) { this.hide(); }
}
show() {
this.create();
this.setPosition();
this.renderer.addClass(this.tooltip, 'ng-tooltip-show');
}
hide() {
this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');
window.setTimeout(() => {
this.renderer.removeChild(document.body, this.tooltip);
this.tooltip = null;
}, 0);
}
create() {
this.tooltip = this.renderer.createElement('span');
this.renderer.appendChild(
this.tooltip,
this.renderer.createText(this.tooltipTitle) // textNode
);
this.renderer.appendChild(document.body, this.tooltip);
this.renderer.addClass(this.tooltip, 'ng-tooltip');
this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
}
setPosition() {
const hostPos = this.el.nativeElement.getBoundingClientRect();
const tooltipPos = this.tooltip.getBoundingClientRect();
let top, left;
if (this.placement === 'top') {
top = hostPos.top - tooltipPos.height - this.offset;
left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
}
/* other positions to be added */
this.renderer.setStyle(this.tooltip, 'top', `${top}px`);
this.renderer.setStyle(this.tooltip, 'left', `${left}px`);
}
}
CSS :
/* Styles for tooltip */
.ng-tooltip {
position: absolute;
max-width: 150px;
font-size: 14px;
text-align: center;
color: #f8f8f2;
padding: 3px 8px;
border-radius: 2px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
background-color: #38393b;
z-index: 1000;
opacity: 0;
}
.ng-tooltip:after {
content: "";
position: absolute;
border-style: solid;
}
.ng-tooltip-top:after {
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-color: #38393b transparent transparent transparent;
}
.ng-tooltip-show {
opacity: 1;
}
From the html file, I invoke the tooltip directive by passing the text like this:
<div tooltip="Title: ( want a line break here) 
 {{someVariable}}" placement="top" class="remark">Hover Here</div>
This can be resolved by taking any of the approach,
Either create two different input such as #Input('Title'): string and #Input('Body'): string and pass into two different parameters.
OR
if you want to pass it in a single parameter make a use of interface such as
export interface IToolTip {
title?: string;
body: string;
footer?: string;
}
Assign this interface to your tooltip variable #Input('tooltip') tooltipTitle: ITooltip; Rest of the things can taken care under create() funciton.
Thanks.

Angular assign css variable to before after class

Im trying to pass variable with [ngStyle] and read it on ::before class but unfortunately cannnot do it,
could someone point me on a right direction?
CSS:
.handle-slider__control {
height: 7px;
z-index:1;
background: $colour-alto;
position: relative;
margin:50px auto;
margin-bottom: 16px;
&.handle-slider__control--markers {
margin-bottom: 0;
}
}
.handle-slider__control::before {
position: absolute;
z-index:-1;
content:"";
left: var(--left);
right: var(--right);
background: $colour-red;
height:100%;
}
HTML:
<div [ngStyle]="getRangeColours()" class="handle-slider__control"></div>
And JS method:
getRangeColours()
{
return {"--left": "10%","--right": "10%"};
}
There is no information about wrongly passed data or anything. Im trying to change css parameters left, right based on data that are in component. If there is any other way to do it I would also consider it. THANKS!
Tested in Angular 9.1.11
test.component.ts
import { Component, OnInit, HostBinding } from '#angular/core';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
#HostBinding('style.--left.%') left: number = 20; // Change it to any Number at any point
#HostBinding('style.--right.%') right: number;
constructor() {}
ngOnInit(): void {
this.right = 10; // Change it to any Number at any point
}
}
test.component.html
<h2 class="handle-slider__control">CSS Variables in Angular</h2>
test.component.scss
.handle-slider__control {
height: 7px;
z-index:1;
background: blue;
position: relative;
margin:50px auto;
margin-bottom: 16px;
&.handle-slider__control--markers {
margin-bottom: 0;
}
}
.handle-slider__control::before {
position: absolute;
z-index:-1;
content:"";
left: var(--left);
right: var(--right);
background: red;
height:100%;
}
For Lower versions, try this (couldn't test though):
import { DomSanitizer } from '#angular/platform-browser';
public value: string;
#HostBinding("attr.style")
public get leftStyle(): any {
return this.sanitizer.bypassSecurityTrustStyle(`--left: value`);
}
constructor(private sanitizer: DomSanitizer) {
this.value = '10%';
}
About css variales thare are differents insteresting links about this, Take a look here or here, e.g.
I don't check it but
document.documentElement.style.setProperty('--left', "10%");
document.documentElement.style.setProperty('--rigth', "20%");
must be work
I just used different class instead of pseudocode with ngStyle on it like that:
.slider-colour-control {
position: absolute;
z-index:-1;
content:"";
background: $colour-red;
height:100%;
}

How to enable scroll on background component even if a Modal is Open?

I have a problem with Angular and Material for Angular, I have an application with many modals, they all lock background scrolling when they're open, but I have a notification modal, this notification modal isn't intended to block background scrolling.
I don't have any .noScroll class in this modal, but the background page in relation to the modal still won't scroll, I want to the user to be able to scroll the page even with the notification modal open.
The notification modal is a DialogRef from Material for Angular.
I tried using overflow: visible and auto, also tried to modify the backdrop to enable scroll, but no success :(
How do I make the backdrop of this particular modal to enable scrolling and possible override other configurations of the code?
Edit: Here is part of the code >
ModalService:
{
constructor(private matDialog: MatDialog) {
}
openNotificationsModal(topOffset, rightOffset): MatDialogRef<NotificationsModalComponent> {
return this.notificationsModal(topOffset, rightOffset);
}
private notificationsModal(topOffset, rightOffset, clazz?: string): MatDialogRef<NotificationsModalComponent> {
const config = {
panelClass: clazz ? clazz : 'notifications-modal',
backdropClass: 'cdk-overlay-transparent-backdrop',
data: {
topOffset,
rightOffset,
}
};
return this.matDialog.open(NotificationsModalComponent, config);
}
}
this is my modal component:
import { Component } from '#angular/core';
import { MatDialogRef } from '#angular/material';
#Component({
selector: 'aa-notifications-modal',
templateUrl: './notifications-modal.component.html',
styles: []
})
export class NotificationsModalComponent {
constructor(private dialogRef: MatDialogRef<NotificationsModalComponent>) {}
async ngOnInit() {
this.dialogRef.updatePosition({
top: '2.5rem'
});
}
output() {
this.dialogRef.close();
}
}
this is the scss of this modal:
aa-notifications-modal {
width: 100%;
}
.notifications-modal {
width: 100%;
max-width: 100% !important;
pointer-events: none !important;
.mat-dialog-container {
display: flex;
justify-content: flex-end;
background: transparent;
width: 100%;
box-shadow: none;
}
.align-triangle {
display: flex;
justify-content: flex-end;
padding: 0;
.triangle {
margin-right: 4rem;
width: 0;
height: 0;
border-left: 25px solid transparent;
border-right: 25px solid transparent;
border-bottom: 25px solid #fff;
}
}
.space {
padding: 0;
}
.content-modal {
display: flex;
justify-content: flex-end;
margin-right: 8rem;
aa-notifications-list {
width: 427px;
pointer-events: auto;
border-radius: 5px;
}
}
}
As I can understand you need to find out where overflow: hidden; likely it will be on body tag, a simple solution you can try to set overflow: auto !important;
But more elegant will be to provide Scroll strategy into your Dialog

circular border-radius artifacts in css

I am using react and have a circle component that I want to map on the screen. The problem is at certain view sizes I get small artifacts in the circles. Flat ends and only on certain rows of circles.
Circles have flat sides at view width 980px
ball hitbox
container hitbox
.ballholder{
display:flex;
flex-wrap: wrap;
justify-content: space-evenly;
background-color:rgb(206,35,212);
padding:0.5vw;
border-radius: 5%;
border:2px solid black;
}
.aball{
background-image: linear-gradient(to bottom right, white, whitesmoke, rgb(150,150,150));
color:black;
border-radius:50%;
display:flex;
justify-content:center;
align-items:center;
width:2vw;
height:2vw;
padding:0.05vw;
margin:0.20vw;
font-size:1.3vw;
}
Here's the parent component:
import React, { Component } from "react";
import { Switch, Route, Redirect, Link } from "react-router-dom";
import Ball from "./Ball";
import "../App.css";
export default class Ballswitch90 extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
const balls = this.state.balls.map((a, i) =>
a ? (
<Ball p={{ num: i + 1, clicked: false }} />
) : (
<Ball p={{ num: i + 1, clicked: true }} />
)
);
return <div className="ballholder">{balls}</div>;
}
}
Ball component:
import React, { Component } from 'react';
import { Switch, Route, Redirect, Link } from "react-router-dom"
import '../App.css'
export default class Ball extends Component {
constructor(props) {
super(props)
this.state = {
num:props.p.num,
clicked:props.p.clicked
}
}
render() {
return (
<div>
{this.state.clicked
?
<div className="aball">{this.state.num}</div>
:
<div className="aballred">{this.state.num}</div>
}
</div>
)
}
}
I've tried adding a padding and margin but that only changed the size at which the flats show up.
Probably the css rules with height and width make some problems.
You can see this snippet that works well:
https://codesandbox.io/embed/n6jrm1k2l
aball {
border-radius: 50%;
background-color: white;
border: 1px solid darkred;
padding: 1em;
/* Center the text contents */
display: inline-flex;
align-items: center;
justify-content: center;
color: black;
}
.aball:after {
content: "";
display: block;
/* Ensure the element is a square */
height: 0;
width: 100%;
padding-bottom: 100%;
}
.aball__value {
/* Set the height to 0 and overflow to visible to not interfere with the square styles */
overflow: visible;
height: 0;
/* Vertically center text since we set its height to 0 */
margin-top: -1em;
}