Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как организовать паузу в выполнении кода? (https://javascript.ru/forum/dom-window/78865-kak-organizovat-pauzu-v-vypolnenii-koda.html)

Jimy 15.11.2019 13:31

Как организовать паузу в выполнении кода?
 
Пытаюсь сделать простой таймер для обратного отсчета. Не могу разобраться с setTimeout(). Все равно цифры бегут со страшной скоростью.
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var canvasW=c.width;
var canvasH=c.height;
var starttimer=90;
var color='blue';
//таймер
var timer=function(x,y){
    this.x=x;
    this.y=y;
    
    //рисование таймера
    this.draw=function(){
        ctx.font="40px Times New Roman";
        ctx.textAlign='center';
        ctx.textBaseline="middle";
        ctx.fillStyle=color;
        ctx.fillText(starttimer,this.x,this.y);
        ctx.strokeStyle=color;
        ctx.lineWidth=3;
        ctx.beginPath();
        ctx.arc(canvasW/2,canvasH/2,30,0,Math.PI*2,false);
        ctx.stroke();
        //изменение таймера
  setTimeout(starttimer -=1,1000);
    };
            };
    //конец таймера

var Timer=new timer(canvasW/2,canvasH/2);
function animate(){
     ctx.clearRect(0,0,canvasW,canvasH);
     ctx.fillStyle="black";
     ctx.fillRect(0,0,c.width,c.height);
     ctx.fill();
    Timer.draw();
    requestAnimationFrame(animate);
};
animate();

Как правильно сделать? Пробовал вместо Timeout setInterval - почти тоже самое, нет задержки....

рони 15.11.2019 14:26

canvas timer
 
Jimy,
делайте полноценный макет! а не кусок кода.
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">

</head>

<body>
<canvas id="canvas" width=300 height="300" ></canvas>
<script>
 var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var canvasW=c.width;
var canvasH=c.height;
var starttimer=90;
var color='blue';
//таймер
var timer=function(x,y){
    this.x=x;
    this.y=y;
    this.t = performance.now();
    //рисование таймера
    this.draw=function(txt){
        ctx.font="40px Times New Roman";
        ctx.textAlign='center';
        ctx.textBaseline="middle";
        ctx.fillStyle=color;
        ctx.fillText(txt,this.x,this.y);
        ctx.strokeStyle=color;
        ctx.lineWidth=3;
        ctx.beginPath();
        ctx.arc(canvasW/2,canvasH/2,30,0,Math.PI*2,false);
        ctx.stroke();

    };
            };
    //конец таймера

var Timer=new timer(canvasW/2,canvasH/2);
function animate(b){
     ctx.clearRect(0,0,canvasW,canvasH);
     ctx.fillStyle="black";
     ctx.fillRect(0,0,c.width,c.height);
     ctx.fill();
     var timer = starttimer - (b - Timer.t)/1000;
     timer = Math.max(0, timer|0);
     Timer.draw(timer);
     timer && requestAnimationFrame(animate);
};
requestAnimationFrame(animate);

</script>
</body>
</html>

Jimy 15.11.2019 14:34

Большое спасибо!

Malleys 15.11.2019 15:04

Цитата:

Сообщение от рони
var Timer=new timer(canvasW/2,canvasH/2);

Это где так учат?!

рони, Jimy, а если разные таймеры?

<canvas id="canvas" width=300 height="300"></canvas>
<script>
	function Timer(canvas) {
		this.canvas = canvas;
		this.context = canvas.getContext("2d");
		this.x = canvas.width / 2;
		this.y = canvas.height / 2;
		this.counter = 90;
		this.lastTime = performance.now();
		this.animate();
	}

	Timer.prototype.draw = function draw() {
		var color = "blue";
		var ctx = this.context;
		ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
		ctx.fillStyle = "black";
		ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
		ctx.fill();
		ctx.font = "40px Times New Roman";
		ctx.textAlign = 'center';
		ctx.textBaseline = "middle";
		ctx.fillStyle = color;
		ctx.fillText(this.counter, this.x, this.y);
		ctx.strokeStyle = color;
		ctx.lineWidth = 3;
		ctx.beginPath();
		ctx.arc(this.canvas.width / 2, this.canvas.height / 2, 30, 0, Math.PI * 2, false);
		ctx.stroke();
	};

	Timer.prototype.animate = function animate(time) {
		requestAnimationFrame(this.animate.bind(this));
		
		if(time - this.lastTime >= 1000 && this.counter > 0) {
			this.counter--;
			this.lastTime = time;
			
			if(this.counter === 0 && "counterendCallback" in this)
				requestAnimationFrame(this.counterendCallback.bind(this));
		}
		
		this.draw();
	};
	
	var timer = new Timer(document.getElementById("canvas"));
</script>

рони 15.11.2019 15:18

Malleys,
this.counter а если не изменять этот параметр, чтоб можно было повторно использовать?

Malleys 15.11.2019 15:21

рони, вы можете работать как с обычным объектом, никакой магии!
var timer2 = new Timer(document.getElementById("canvas-2"));
timer2.counter = 10;
timer2.counterendCallback = () => alert("Время истекло!");

рони 15.11.2019 15:28

Malleys,
и почему нет остановки animate после this.counter === 0?

Malleys 15.11.2019 15:29

Цитата:

Сообщение от рони
this.counter а если не изменять этот параметр, чтоб можно было повторно использовать?

Вы в плане того, чтобы запомнить изначальное значение? Я думаю, что counter должен хранить оставшееся время, так и так вам может понадобиться это значение из другого места. А если нужно начально значение, то я думаю, что можно добавить метод setTimer...

Timer.prototype.setTimer = function(value) {
    this.counter = value;
    this.initialCounter = value;
};

Malleys 15.11.2019 15:31

Цитата:

Сообщение от рони
и почему нет остановки animate после this.counter === 0?

Потому что можно менять counter извне класса, особенно после добавления setTimer

рони 15.11.2019 15:41

Malleys,
не особо понимаю зачем нужен setTimer и безостановочная долбёжка animate когда эта функция работает в холостую.


Часовой пояс GMT +3, время: 19:48.