Skip to content

Commit

Permalink
standalone components
Browse files Browse the repository at this point in the history
  • Loading branch information
ribizli committed Nov 26, 2022
1 parent 29a4fc4 commit ec364ad
Show file tree
Hide file tree
Showing 20 changed files with 129 additions and 165 deletions.
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"printWidth": 140,
"singleQuote": true
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}
44 changes: 36 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build:prod": "ng build --configuration production"
"watch": "ng build --watch --configuration development"
},
"private": true,
"dependencies": {
Expand All @@ -38,4 +38,4 @@
"ts-node": "~10.9.0",
"typescript": "~4.8.4"
}
}
}
39 changes: 21 additions & 18 deletions projects/ngx-image2dataurl/src/lib/image-to-data-url.directive.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,51 @@
import { Directive, EventEmitter, HostListener, Inject, InjectionToken, Input, OnChanges, Optional, Output, SimpleChanges } from '@angular/core';
import { Directive, EventEmitter, HostListener, Inject, InjectionToken, Input, OnChanges, Optional, Output } from '@angular/core';
import { ImageFileProcessor, ImageResult, Options, ResizeOptions } from './interfaces';
import { fileToDataURL, getImageTypeFromDataUrl, resizeImage } from './utils';


export const IMAGE_FILE_PROCESSOR = new InjectionToken<ImageFileProcessor>('ImageFileProcessor');

@Directive({
selector: 'input[type=file][imageToDataUrl]'
selector: 'input[type=file][imageToDataUrl]',
standalone: true,
})
export class ImageToDataUrlDirective implements OnChanges {

@Output() imageSelected = new EventEmitter<ImageResult>();

@Input('imageToDataUrl') options: Options = {};

constructor(@Optional() @Inject(IMAGE_FILE_PROCESSOR) private imageFileProcessors: ImageFileProcessor[]) {
constructor(
@Optional()
@Inject(IMAGE_FILE_PROCESSOR)
private imageFileProcessors: ImageFileProcessor[]
) {
this.imageFileProcessors = imageFileProcessors || [];
}

ngOnChanges(changes: SimpleChanges): void {
ngOnChanges() {
if (!this.options) {
this.options = {};
}

if (this.options.allowedExtensions) {
this.options.allowedExtensions = this.options.allowedExtensions.map(ext => ext.toLowerCase());
this.options.allowedExtensions = this.options.allowedExtensions.map((ext) => ext.toLowerCase());
}
}

@HostListener('change', ['$event'])
async readFiles(event) {
for (let file of event.target.files as File[]) {
async readFiles(event: Event) {
for (let file of Array.from((event.target as HTMLInputElement).files)) {
const result: ImageResult = {
file,
url: URL.createObjectURL(file)
url: URL.createObjectURL(file),
};
let ext: string = file.name.split('.').pop();
ext = ext && ext.toLowerCase();
if (ext && this.options.allowedExtensions
&& this.options.allowedExtensions.length
&& this.options.allowedExtensions.indexOf(ext) === -1) {
if (
ext &&
this.options.allowedExtensions &&
this.options.allowedExtensions.length &&
this.options.allowedExtensions.indexOf(ext) === -1
) {
result.error = new Error('Extension Not Allowed');
} else {
try {
Expand All @@ -56,15 +62,12 @@ export class ImageToDataUrlDirective implements OnChanges {
}
}

private async resize(dataURL: string, options: ResizeOptions): Promise<{ dataURL: string, type: string }> {
private async resize(dataURL: string, options: ResizeOptions): Promise<{ dataURL: string; type: string }> {
if (!options) return null;
const resisedDataUrl = await resizeImage(dataURL, options);
return {
dataURL: resisedDataUrl,
type: getImageTypeFromDataUrl(resisedDataUrl)
type: getImageTypeFromDataUrl(resisedDataUrl),
};
}

}


This file was deleted.

2 changes: 1 addition & 1 deletion projects/ngx-image2dataurl/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface ImageResult {
resized?: {
dataURL: string;
type: string;
}
};
}

export interface ResizeOptions {
Expand Down
20 changes: 8 additions & 12 deletions projects/ngx-image2dataurl/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ export function createImageFromDataUrl(dataURL: string) {
});
}

export async function resizeImage(dataURL: string, {
bgColor,
maxHeight,
maxWidth,
quality = 0.7,
type = getImageTypeFromDataUrl(dataURL)
}: ResizeOptions = {}) {

export async function resizeImage(
dataURL: string,
{ bgColor, maxHeight, maxWidth, quality = 0.7, type = getImageTypeFromDataUrl(dataURL) }: ResizeOptions = {}
) {
const image = await createImageFromDataUrl(dataURL);

if (!document) throw new Error('Work only in browser, document not defined');
Expand All @@ -26,20 +22,20 @@ export async function resizeImage(dataURL: string, {
let width = image.width;

if (width > maxWidth) {
height = Math.round(height * maxWidth / width);
height = Math.round((height * maxWidth) / width);
width = maxWidth;
}

if (height > maxHeight) {
width = Math.round(width * maxHeight / height);
width = Math.round((width * maxHeight) / height);
height = maxHeight;
}

canvas.width = width;
canvas.height = height;

//draw image on canvas
const ctx = canvas.getContext("2d");
const ctx = canvas.getContext('2d');

if (bgColor) {
ctx.fillStyle = bgColor;
Expand All @@ -65,5 +61,5 @@ export function fileToDataURL(file: File): Promise<string> {
const typeRE = /^data:([^,;]+)/;
export function getImageTypeFromDataUrl(dataURL: string): string {
let matches = dataURL.match(typeRE);
return matches && matches[1] || undefined;
return (matches && matches[1]) || undefined;
}
1 change: 0 additions & 1 deletion projects/ngx-image2dataurl/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
*/
export * from './lib/interfaces';
export { createImageFromDataUrl, getImageTypeFromDataUrl } from './lib/utils';
export * from './lib/image-to-data-url.module';
export * from './lib/image-to-data-url.directive';
22 changes: 0 additions & 22 deletions projects/ngx-image2dataurl/src/test.ts

This file was deleted.

5 changes: 2 additions & 3 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
<img [src]="src" *ngIf="src"><br>
<input type="file" [imageToDataUrl]="options"
(imageSelected)="selected($event)">
<img [src]="src" *ngIf="src" /><br />
<input type="file" [imageToDataUrl]="options" (imageSelected)="selected($event)" />
21 changes: 15 additions & 6 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { NgIf } from '@angular/common';
import { Component } from '@angular/core';
import { ImageResult, Options } from "ngx-image2dataurl";
import { ImageResult, ImageToDataUrlDirective, IMAGE_FILE_PROCESSOR, Options } from 'ngx-image2dataurl';
import { RotateImageFileProcessor } from './rotate-image-file-processor';

@Component({
selector: 'app-root',
standalone: true,
imports: [ImageToDataUrlDirective, NgIf],
providers: [
{
provide: IMAGE_FILE_PROCESSOR,
useClass: RotateImageFileProcessor,
multi: true,
},
],
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
styleUrls: ['./app.component.css'],
})
export class AppComponent {
src: string = null;
Expand All @@ -13,13 +24,11 @@ export class AppComponent {
maxHeight: 128,
maxWidth: 128,
},
allowedExtensions: ['JPG', 'PnG']
allowedExtensions: ['JPG', 'PnG'],
};

selected(imageResult: ImageResult) {
if (imageResult.error) alert(imageResult.error);
this.src = imageResult.resized
&& imageResult.resized.dataURL
|| imageResult.dataURL;
this.src = (imageResult.resized && imageResult.resized.dataURL) || imageResult.dataURL;
}
}
23 changes: 0 additions & 23 deletions src/app/app.module.ts

This file was deleted.

37 changes: 18 additions & 19 deletions src/app/rotate-image-file-processor.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { createImageFromDataUrl, getImageTypeFromDataUrl, ImageFileProcessor } from "ngx-image2dataurl";
import { Injectable } from "@angular/core";

import { createImageFromDataUrl, getImageTypeFromDataUrl, ImageFileProcessor } from 'ngx-image2dataurl';
import { Injectable } from '@angular/core';

@Injectable()
export class RotateImageFileProcessor implements ImageFileProcessor {
async process(dataURL: string): Promise<string> {
const canvas = document.createElement('canvas');
const image = await createImageFromDataUrl(dataURL);
canvas.width = image.height;
canvas.height = image.width;
const ctx = canvas.getContext("2d");
//ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(Math.PI / 2);
ctx.drawImage(image, -image.width / 2, -image.height / 2);
//ctx.restore();
return canvas.toDataURL(getImageTypeFromDataUrl(dataURL));
}

}
export class RotateImageFileProcessor implements ImageFileProcessor {
async process(dataURL: string): Promise<string> {
const canvas = document.createElement('canvas');
const image = await createImageFromDataUrl(dataURL);
canvas.width = image.height;
canvas.height = image.width;
const ctx = canvas.getContext('2d');
//ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(Math.PI / 2);
ctx.drawImage(image, -image.width / 2, -image.height / 2);
//ctx.restore();
return canvas.toDataURL(getImageTypeFromDataUrl(dataURL));
}
}
2 changes: 1 addition & 1 deletion src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const environment = {
production: true
production: true,
};
Loading

0 comments on commit ec364ad

Please sign in to comment.