개요

먼저 multiparty로 req를 받아 파일과 필드값으로 나누어 준 뒤에 노드 썸네일을 통해 변환을 해 준다.

설치

1
npm install node-thumbnail

서버 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var multiparty = require('multiparty');
var thumb = require('node-thumbnail').thumb;

router.post('/thumbnail',function(req,res){
console.log("썸네일 변경!");
var form = new multiparty.Form();
form.parse(req,function(err,fields, files){
if(err){
console.log(err);
}
Object.keys(fields).forEach(function(name) {
console.log('got field named ' + name);
});
console.log("files:", files);

var fileName=fields.fileName[0];
var oldPath = files.imageFile[0].path;
console.log(fileName);
// 서버에서 돌리는 부분
var newPath = '/root/imageServer/public/images';

thumb({
basename:fileName.split(".")[0],
suffix:'',
source: oldPath,
destination: newPath,
width: 300
}).then(function() {
console.log('Success');
res.sendStatus(200)
}).catch(function(e) {
console.log('Error', e.toString());
res.sendStatus(500);
});

})
})

default options

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
defaults = {
prefix: '',
suffix: '_thumb',
digest: false,
hashingType: 'sha1', // 'sha1', 'md5', 'sha256', 'sha512'
width: 800,
concurrency: <num of cpus>,
quiet: false, // if set to 'true', console.log status messages will be supressed
overwrite: false,
basename: undefined, // basename of the thumbnail. If unset, the name of the source file is used as basename.
ignore: false, // Ignore unsupported files in "dest"
logger: function(message) {
console.log(message);
}
};

설치하기

1
npm install ngx-infinite-scroll --save

동작 특성

window scroll 이벤트를 감지하여 callback을 발생시킨다.
실제 요소가 스크롤 될때 콜백을 수행하기 위해서는 다음 설정이 되어야 한다.

1
2
[scrollWindow]="false"
set an explict css "height" value to the element

import 하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app';

@NgModule({
imports:[ BrowserModule, InfiniteScrollModule ],
declarations: [ AppComponent, ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

platformBrowserDynamic().bootstrapModule(AppModule);

아래 예제에서는 스크롤이 내려가면 onScroll 함수가 호출된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Component } from '@angular/core';

@Component({
selector: 'app',
template: `
<div class="search-results"
infiniteScroll
[infiniteScrollDistance]="2"
[infiniteScrollThrottle]="50"
(scrolled)="onScroll()">
</div>
`
})
export class AppComponent {
onScroll () {
console.log('scrolled!!')
}
}

Host Listener란?

호스트의 이벤트를 감지하는 라이브러리

HostListener Decorator Component 작성

아래와 같이 호스트의 이벤트를 감지한다.
여기서 window는

1
2
3
4
5
6
7
8
9
10
11
12
import { HostListener} from "@angular/core";
import { DOCUMENT } from "@angular/platform-browser";
import { Inject } from "@angular/core";

export class LayoutNavComponent implements OnInit {
constructor(@Inject(DOCUMENT) private document: Document) { }
}
@HostListener("window:scroll", [])
onWindowScroll() {
//we'll do some stuff here when the window is scrolled
let windowScrollPos = this.document.documentElement.scrollTop;
}

observable과 throttle을 활용하여 event 반응하기

throttle time이 200ms인 observable을 생성하고, subject를 통해 새로운 인자값을 전달한다.
생성한 observable을 subscribe 해 주고, subject를 통해 계속해서 새로운 인자값을 전달한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/throttleTime';

export class AppComponent implements OnInit {

private resizeSubject = new Subject<number>();
private resizeObservable = this.resizeSubject.asObservable().throttleTime(200);

@HostListener('window:resize', ['$event.target.innerWidth'])
onResize(width: number) {
this.resizeSubject.next(width);
}

ngOnInit() {
this.resizeObservable.subscribe(x => this.doSomethingWithThrottledEvent(x));
}

private doSomethingWithThrottledEvent(width: number) {
// . . .

}
}

참조

rgb를 이용하는 방법

제일 뒷자리가 투명도를 조절하는 부분이다.

1
rgba(0, 0, 0, 0.5)

hexo code를 이용하는 방식

숫자 앞에 투명도를 붙여준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for 50% white you'd use #80FFFFFF.

100% — FF
95% — F2
90% — E6
85% — D9
80% — CC
75% — BF
70% — B3
65% — A6
60% — 99
55% — 8C
50% — 80
45% — 73
40% — 66
35% — 59
30% — 4D
25% — 40
20% — 33
15% — 26
10% — 1A
5% — 0D
0% — 00

ngx-lazy-load-images 설치하기

1
npm i ngx-lazy-load-images --save

모듈 import 하기

1
2
3
4
5
6
7
8
9
import { NgModule } from '@angular/core';
import { LazyLoadImagesModule } from 'ngx-lazy-load-images';

@NgModule({
imports: [
LazyLoadImagesModule
]
})
export class AppComponent {}

사용하고자 하는 img에 lazy-load-images directive 사용하기

img 태그에 사용하는 것이 아니고 img의 상위 태그에 directive를 넣어야 한다.

1
2
3
4
5
6
7
8
9
<!-- Image tags -->
<div class="image-list" lazy-load-images>
<img *ngFor="let imageUrl in images" [attr.data-src]="imageUrl">
</div>

<!-- Background images -->
<div class="image-list" lazy-load-images>
<div *ngFor="let imageUrl in images" [attr.data-background-src]="imageUrl"></div>
</div>

img 에 data-src 속성 넣기

undefined

참조

angular application을 ie에서 사용할때

ie는 Object.assign()을 지원하지 않기 때문에 polyfill.ts를 사용하여야 한다.

polyfills.ts에는 이미 ie와 사파리 브라우저에서 사용하기 위한 다양한 import가 주석처리 되어 있으므로

이를 주석해제하면 해결할 수 있다.

파이프를 사용하기 위한 intl 설치

1
npm install --save intl

애니메이션 사용을 위한 web-animation설치

1
npm install --save web-animations-js

ngClass 사용을 위한 classlist설치

1
npm install --save classlist.js

transition을 활용한 사이즈 애니메이션

1
2
transition: height 2s;
-webkit-transition: height 2s;

현재 시장에서 기업의 위치를 명확하게 설정하라

다른 시각으로 비즈니스 세계를 들여다보고 공략할 시장의 범주를 정해서 기업을 운영해야 한다.

예를 들어 사우스웨스트 항공은 다른 항공사들이 시도하지 않던 방법으로 비행기 내의 기내식을 없애고 다른 기타의 불필요한 서비스도 없애 버렸는데, 이는 바로 특정 고객에 집중하여 성공한 예이다.

모든 고객을 만족시킬 필요는 없다.
나아가 모든 고객을 목표로 삼을 필요도 없다.

지배할 시장을 찾아라

비즈니스시장에서 시장을 지배하는 것은 큰 의미를 가진다.
내가 운영하는 기업이 중소기업이라서, 기업의 규모가 작아서라는 이유로 시장을 지배하지 못한다면 그 기업은 반드시 망한다.
시장 세분화가 중요한 이유는 바로 한 산업의 시장을 극도로 세분화 한다면, 그 세분화된 시장 안에서는 시장을 지배할 수 있기 때문이다.

시장을 바라보는 방식에 변화를 주고 지배할 수 있는 시장을 찾아 선점하라.

일용품 시장인가 특제품 시장인가?

사용자들은 크게 두 부류로 나누어 진다.
예를 들어 펜 시장의 경우 단순히 글씨만 잘 써지면 된다 하는 고객들이 있다. 이들이 바로 일용품 구매자 이다.
이 고객들은 아주 기본적인 기능에 집중하고 가격에 매우 민감하다.

다른 부류는 펜의 디자인, 그립감 등 가격 외의 것에 민감한 부류이다. 이 고객들은 가격을 넘어서 기본적인 펜 이상의 품질을 원한다. 이들이 바로 특제품 구매자 이다.

이렇게 가격에 따른 민감도에 따라 그래프를 그리면 U자 형태의 그래프를 보이게 되는데, 대부분의 경우 그래프의 양끝을 겨냥해야 성공 가능성이 높다.
하지만, 수많은 회사가 그 중간 고객을 겨냥하고 있다.
중간 고객은 충성도가 높지 않고, 이 시장을 지배할 방법을 찾기란 불가능에 가깝다.

시장 세분화의 법칙

여러가지 방법이 있으나 다음과 같은 기준에 따라 세분화 하는 것이 바람직하다.

  1. 고객의 니즈와 기호
  2. 일용품과 특제품
  3. 제품 유형
  4. 시장 유형
  5. 인구 통계적 유형
  6. 지리적 조건
  7. 고객 유형 또는 구매 경로

다음과 같은 질문이 시장 세분화에 도움이 된다.

  1. 고객들은 무엇을 구매하는가?
  2. 누가 구매하는가?
  3. 그들은 왜 구매하는가?
  4. 어떤 방법으로 구매하는가
  5. 구매한 제품을 어떻게 이용하는가?
  6. 어디에서 높은 수익을 올리고 있는가?
  7. 어디에서 낮은 수익을 올리고 있는가?

집중할 세준시장을 찾아내는 것은 매우 중요하다.

세분시장 분석서 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1. 세분 시장의 정의
지역: 오하이오, 인디애나, 일리노이,
특성: 대형 소매업체에서 연간 5천만 달러 이상의 캔디를 판매하는 제조업체

2. 고객의 니즈
캔디가 깨지지 않도록 잘 보호해야 하고, 내용물이 오염되지 않도록 위생 상태가 좋아야 하며, 납품 기일을 준수해야 한다.

3. 고객의 기호
색 배합이 바래지 않아야 한다.
가격이 저렴해야 한다.
공급이 안정적이어야 한다.

4. 세분시장의 총매출액: 5000만 달러

5. 회사의 현시장 점유율: 120만 달러(24%)

6. 특제품 또는 일용품의 구분
특제품 구매자 90%, 일용품 구매자는 극소수

7. 잠재고객의 수
5개 회사만으로 이루어진 집중화 시장

8. 경쟁사의 시장 점유율
브라운 사:33%
ABC 사: 10%

9. 시장의 5년 평균 연간 실질 성장률
5년 전 250만 달러, 지난해 460만 달러였으며 과거 5년간 이 시장의 매출총액 규모가 2배로 성장했다. 하지만 현재 연간 실질성장률은 8%에 불과한 것으로 추정된다.

10. 최근 시장의 주요 사건
최대 구매업체인 존스 사가 가장 가까운 경쟁사를 인수하려 하고 있다.

11. 간접 경쟁
열성형 플라스틱 용기
다이컷 종이 커버
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×