Canvasを使用したフロントループの作成
31531 ワード
Persentage-Circle
私がやりたいのは、ぐるぐる回って、私の要求通りに1万ウォンの色を塗ることです.
他の資料を調べずに作りました.
(書くために探したとき、svgを使っているのを見ましたが、試していないので、最初から作成すべきだと思います.)
canvas
canvasを使用する場合、canvasのウィンドウサイズを指定して円の位置を取得し、円の半径で画像を描くかどうかを考慮する必要があります.
canvasは円のサブノードとして、各円がcanvasに入るべきかどうか分からないので、まず後者を選択します.
(位置決めが便利だと思います)
エラー
canvasの幅と高さを円の幅と高さと同じにして、canvasのlineWidthが大きくなるにつれてcanvasサイズを超えた部分が消えることを確認します.
解決策
まず、円にcssを指定して、サブノードを水平に中央に揃えます.
cavnas
ソースコード
私がやりたいのは、ぐるぐる回って、私の要求通りに1万ウォンの色を塗ることです.
他の資料を調べずに作りました.
(書くために探したとき、svgを使っているのを見ましたが、試していないので、最初から作成すべきだと思います.)
canvas
canvasを使用する場合、canvasのウィンドウサイズを指定して円の位置を取得し、円の半径で画像を描くかどうかを考慮する必要があります.
canvasは円のサブノードとして、各円がcanvasに入るべきかどうか分からないので、まず後者を選択します.
(位置決めが便利だと思います)
エラー
canvasの幅と高さを円の幅と高さと同じにして、canvasのlineWidthが大きくなるにつれてcanvasサイズを超えた部分が消えることを確認します.
解決策
まず、円にcssを指定して、サブノードを水平に中央に揃えます.
cavnas
arc(x, y, radius, from, to)
関数のx,y値は、私がcanvasサイズを増やしたのと同じように1/2
増加しました.ソースコード
type styleType = {
[key in keyof CSSStyleDeclaration]?: string | null;
};
function sleep(ms: number = 500) {
return new Promise<void>(resolve => {
setTimeout(() => {
resolve();
}, (ms));
})
}
function settingCssProperty(ref: HTMLElement, cssProperty?: styleType) {
if (cssProperty !== null && cssProperty !== undefined) {
const keys = Object.keys(cssProperty);
const values = Object.values(cssProperty);
for (let i = 0; i < keys.length; i++) {
const index = keys[i]
.split("")
.findIndex((value) => value.toLocaleLowerCase() !== value);
if (index > -1) {
const upperWord = keys[i][index];
const key = keys[i].replace(
upperWord,
`-${upperWord.toLocaleLowerCase()}`
);
const value = values[i];
if(value) {
ref.style.setProperty(key, value);
}
} else {
const value = values[i];
if(value) {
ref.style.setProperty(keys[i], value);
}
}
}
}
}
class NewElement {
element: HTMLElement;
constructor(elem: keyof HTMLElementTagNameMap) {
this.element = document.createElement(elem);
}
}
class CircleElement extends NewElement{
constructor(elem: keyof HTMLElementTagNameMap = "div") {
super(elem);
}
create(ref: HTMLElement, styleOptions: styleType) {
settingCssProperty(this.element, styleOptions);
ref.appendChild(this.element);
return this.element;
}
}
class CircleCanvas {
canvas: HTMLCanvasElement;
context: CanvasRenderingContext2D | null;
width: number;
heigth: number;
ref: HTMLElement;
radius: number;
position: {x: number, y: number};
ARCfrom: number = (1.5 * Math.PI);
addedWidth: number = 20;
constructor(ref: HTMLElement) {
this.ref = ref;
const clinetRect = this.ref.getBoundingClientRect();
this.width = clinetRect.width;
this.heigth = clinetRect.height;
this.position = {
x: (this.width / 2) + this.addedWidth / 2,
y: (this.heigth / 2) + this.addedWidth / 2,
}
this.radius = this.width / 2;
this.canvas = document.createElement('canvas');
this.canvas.width = this.width + this.addedWidth;
this.canvas.height = this.heigth + this.addedWidth;
this.canvas.style.position = "absolute";
this.context = this.canvas.getContext('2d');
this.ref.appendChild(this.canvas);
}
create() {
return this.canvas;
}
update(to: number) {
this.context?.clearRect(0, 0, this.canvas.width, this.canvas.height);
if(this.context) {
this.context?.beginPath();
this.context.lineCap = "round";
this.context.strokeStyle = "rgba(250, 50, 44)";
this.context.lineWidth = 5.5;
this.context?.arc(this.position.x, this.position.y, this.radius, this.ARCfrom, (1.5 + to / 50) * Math.PI);
this.context?.stroke();
}
}
}
const createElement = async () => {
const parentStyleOptions: styleType = {
width: "100vw",
height: "100vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
position: "relative",
}
const parentElement = new CircleElement().create(document.body, parentStyleOptions);
const styleOptions: styleType = {
width: "150px",
height: "150px",
borderRadius: "50%",
display: "flex",
justifyContent: "center",
alignItems: "center",
position: "relative",
backgroundColor: "white"
}
const circleElement = new CircleElement().create(parentElement, styleOptions);
const circleLine = new CircleCanvas(circleElement);
circleLine.create();
/** update / 10ms */
const per = 75;
for(let i = 0; i <= per; i++ ) {
await sleep(10);
circleLine.update(i);
}
/** 숫자 표시 */
const span = new NewElement("span").element;
span.innerText = `${per}%`;
circleElement.appendChild(span);
}
createElement();
Reference
この問題について(Canvasを使用したフロントループの作成), 我々は、より多くの情報をここで見つけました https://velog.io/@jwisgenius/Canvas를-이용한-persentage-Circle-만들기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol