キャンバス要素を使用して、角度2で円形の進行状況バーを作成します。私はAngular 1で複数のプロジェクトを行ってきましたが、Angular 2とTypeScriptはまったく新しいものなので、私はちょっと頭を上げています...角2:キャンバスと変更の検出
私はProgressCircle
コンポーネントを作成しました。他のコンポーネントの内部で使用してください。このプログレスコンポーネントは、親コンポーネントから、プログレスサークルの外観とその塗り方を決定する2つの属性を受け取ります。
注:このコードを古いES5プロジェクトから取り出しました。これが表示されることがあります。
import { Component, Input, Injectable, ElementRef, AfterViewInit } from '@angular/core';
@Injectable()
@Component({
selector: 'progress-circle',
template: `
<div class="progress-indicator" [style.width]="size + 'px'" [style.height]="size + 'px'">
<canvas [attr.width]="size" [attr.height]="size"></canvas>
<span class="progress-text-container">
<span class="progress-text">{{ progress }}</span>
</span>
</div>
`
})
export class ProgressCircle implements AfterViewInit {
@Input() size:number;
@Input() progress:number;
@Input() lineWidth:number;
@Input() rotate:number;
@Input() color:string;
@Input() trackColor:string;
@Input() bgColor:string;
@Input() borderWidth:number;
@Input() animate:boolean;
constructor(private el:ElementRef) {}
ngAfterViewInit() {
this.draw();
}
draw() {
let canvas = this.el.nativeElement.getElementsByTagName('canvas')[0],
ctx = canvas.getContext('2d'),
options = {
percent: this.progress || 0,
size: this.size || 90,
lineWidth: this.lineWidth || (this.size/10) || 10,
rotate: this.rotate || 0,
color: this.color || '#000',
trackColor: this.trackColor || '#e6e6e6',
bgColor: this.bgColor || 'transparent',
borderWidth: this.borderWidth || 0,
doAnimate: this.animate
},
radius = (options.size - options.lineWidth)/2,
progress = 0,
fillColor:string = undefined,
animFrame:number, bg:ImageData;
let drawCircle = (strokeColor:string, fillColor:string, percent:number, hasBorder:boolean = false) => {
// logic to draw circle goes here
}
let animateProgess =() => {
if (++progress <= options.percent) { // we need to animate
// draw circle
animFrame = window.requestAnimationFrame(animateProgess);
}
}
ctx.translate(options.size/2, options.size/2);
ctx.rotate((-.5 + (options.rotate/180)) * Math.PI);
if (options.doAnimate) {
bg = ctx.getImageData(0, 0, canvas.width, canvas.height);
animFrame = window.requestAnimationFrame(animateProgess);
} else {
drawCircle(options.color, fillColor, options.percent);
this.progress = Math.floor(options.percent);
}
}
}
これで正常です。しかし、親コンポーネントの入力変数progress
はいつでも変更される可能性があります。適切なタイミングで進行状況バーの再描画をトリガーするにはどうすればよいですか?
ビューがロードされた後(つまりngAfterViewInitが呼び出される)までプログレスバーを初期化できません。そうしないと、canvas要素がまだ完全に初期化されていないため、すべてファンキーに見えます。 ngOnChangesのライフサイクルフックを調べましたが、ビューがロードされる前に最初に起動するため、無用です。
progress
入力変数を観測可能にしてから、ngAfterViewInit
フックでそれを購読することが考えられましたが、それがどのように機能するかは完全にはわかりません。私はngOnChanges
にフックして、最初の変更(実際にはSimpleChangeクラスにはドキュメントに準拠したメソッドがあるかどうか)をチェックすることもできますが、それは私にはハックのようです。
任意のポインタをありがとう! Angular 2は私の上で成長していますが、Angular 1/ES5から来るのに慣れているのは間違いありません。
プロのヒント:draw()コードのほとんどはあなたの質問にはあまり関係しません。小さな質問は、しばしば、SOにもっと注意を引く。したがって、draw()コードのほとんどを含まない方がよいでしょう。 –