我正在開發一個使用畫布顯示視頻的 html5 視頻播放器。當視頻沒有準備好時,我需要顯示微調器(與MUI 中的CircularProgress相同)。
可以在畫布頂部覆寫一個 svg 微調器。但在我看來,既然我用的是畫布,最好在上面畫一個微調器。這就是我得到的。
window.addEventListener("load", () => {
let canvas = document.querySelector("canvas");
let context = canvas.getContext("2d");
let x = canvas.width / 2;
let y = canvas.height / 2;
let radius = 30;
let cycleNum = 0;
let startAngle = 0;
let endAngle = Math.PI / 64;
let totalCycles = 200;
let linearStep = ((2 * Math.PI) / totalCycles) * 2;
let quadroStep;
let totalSteps = totalCycles / 4;
const drawSpinner = () => {
if (cycleNum >= totalCycles) cycleNum = 0;
cycleNum = 1;
context.clearRect(0, 0, canvas.width, canvas.height);
let curStep = cycleNum % totalSteps;
if (
cycleNum <= totalCycles / 4 ||
(cycleNum > totalCycles / 2 && cycleNum <= (totalCycles * 3) / 4)
) {
// 1st and 3rd quarters of cycle
quadroStep = ((Math.PI * curStep) / totalSteps) ** 2 / 75;
} else if (
(cycleNum > totalCycles / 4 && cycleNum <= totalCycles / 2) ||
cycleNum > (totalCycles * 3) / 4
) {
// 2nd and 4rd quarters of cycle
quadroStep = ((Math.PI * (totalSteps - curStep)) / totalSteps) ** 2 / 75;
}
if (cycleNum <= totalCycles / 2) {
// 1st half-cycle we move endAngle
startAngle = linearStep;
endAngle = linearStep quadroStep;
} else {
// 2nd half-cycle we move startAngle
startAngle = linearStep quadroStep;
endAngle = linearStep;
}
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, 0);
context.lineWidth = 6;
context.strokeStyle = "rgba(0,0,0,0.3)";
context.stroke();
}
setInterval(drawSpinner, 10);
});
<html>
<head></head>
<body>
<canvas></canvas>
</body>
</html>
這作業正常,但quadroStep計算讓我感到困惑 - 雖然它提供加速/減速,但它是通過實驗選擇的(尤其是除以 75)。但是,我知道可以以某種方式更準確地計算該值-您需要以某種方式將 thestartAngle和 the之間的距離endAngle(考慮到它們之間的剩余差距)劃分為“二次步長”,但是這究竟是如何做到的呢?
如果有人能引導我朝著正確的方向前進,那就太好了。謝謝!
uj5u.com熱心網友回復:
為了將分段劃分為二次步驟,我舉了一個示例,其中有 3 個步驟:
x1 x2 x3 = sum
sum是我們需要分成二次步長的總距離,
xN是特定步長的段長度值N。
我們的函式是二次函式,因此我們將設定以下函式:
xN = N ** 2
讓我們計算一個例子:
1 ** 2 2 ** 2 3 ** 2 = sum
1 4 9 = sum
sum = 14
好的,這個例子很清楚,但是如果我們sum不等于 14 怎么辦?那么如何找到所有的xN呢?讓我們引入一個系數k,它將改變sum所有的xN:
k * x1 k * x2 k * x3 = sum
k * (x1 x2 x3) = sum
k = sum / (x1 x2 x3)
然后知道k我們可以計算 any 的值xN如下:
xN = N ** 2 * k
于是計算k出來的代碼如下:
let gap = Math.PI / 2;
let sum = (2 * Math.PI - gap) / 2;
let totalSteps = totalCycles / 4;
let calcSum = 0;
for (let i = 1; i <= totalSteps; i ) calcSum = i ** 2;
let k = sum / calcSum;
這gap是環的哪一部分將保持打開狀態。
這就是我得到的結果,也許它對某人有用:
window.addEventListener("load", () => {
let canvas = document.querySelector("canvas");
let context = canvas.getContext("2d");
let x = canvas.width / 2;
let y = canvas.height / 2;
let radius = 30;
let cycleNum = 0;
let startAngle = 0;
let endAngle = Math.PI / 64;
let totalCycles = 200;
let linearStep = ((2 * Math.PI) / totalCycles) * 2;
let quadroStep;
let gap = Math.PI / 2;
let sum = (2 * Math.PI - gap) / 2;
let totalSteps = totalCycles / 4;
let calcSum = 0;
for (let i = 1; i <= totalSteps; i ) calcSum = i ** 2;
let k = sum / calcSum;
const drawSpinner = () => {
if (cycleNum >= totalCycles) cycleNum = 0;
cycleNum = 1;
context.clearRect(0, 0, canvas.width, canvas.height);
let curStep = ((cycleNum - 1) % totalSteps) 1;
if (
cycleNum <= totalCycles / 4 ||
(cycleNum > totalCycles / 2 && cycleNum <= (totalCycles * 3) / 4)
) {
// 1st and 3rd quarters of cycle
quadroStep = curStep ** 2 * k;
} else if (
(cycleNum > totalCycles / 4 && cycleNum <= totalCycles / 2) ||
cycleNum > (totalCycles * 3) / 4
) {
// 2nd and 4rd quarters of cycle
quadroStep = (totalSteps - curStep) ** 2 * k;
}
if (cycleNum <= totalCycles / 2) {
// 1st half-cycle we move endAngle
startAngle = linearStep;
endAngle = linearStep quadroStep;
} else {
// 2nd half-cycle we move startAngle
startAngle = linearStep quadroStep;
endAngle = linearStep;
}
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, 0);
context.lineWidth = 6;
context.strokeStyle = "rgba(0,0,0,0.3)";
context.stroke();
}
setInterval(drawSpinner, 10);
});
<html>
<head></head>
<body>
<canvas></canvas>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/520225.html
上一篇:創建移位漢克爾矩陣
