JSFiddle - React, Tailwind, and code Playground

by subzey

HTML

<canvas id="a" width="600" height="600"></canvas>

JavaScript

// Получаем главнй канвас и его контекст
// Имена a и c - стандарт де-факто
var a = document.getElementById('a');
var c = a.getContext('2d');

// Создаём вспомогательный канвас для паттерна
// Можно было бы использовать существующий,
// но это усложнит понимание кода
var patternCanvas = document.createElement('canvas');
patternCanvas.width = 16;
patternCanvas.height = 16;
var patternCtx = patternCanvas.getContext('2d');
patternCtx.globalAlpha = 0.25;
patternCtx.beginPath();
patternCtx.arc(8,8,6,0,7);
patternCtx.fill();

// Собственно, паттерн.  С этого момента на вспомогательный канвас не пригодится
var pattern = c.createPattern(patternCanvas, 'repeat');
// Товсь - Ноль!
var demoStartTime = Date.now ? Date.now() : +new Date();

(function render(){
	var currentTime = Date.now ? Date.now() : +new Date();
	var timeDelta = currentTime - demoStartTime;
	var angle = timeDelta / 1e3;
	var scale = Math.cos(timeDelta / 2e3);
	// Очистка канваса
	a.width |= 0;
	c.lineWidth = 5;
	c.fillStyle = pattern;


	// Левый верхний эллипс
	c.save();
		c.translate(150, 150);
		c.rotate(angle);
		c.scale(scale, 1);
		c.beginPath();
		c.arc(0, 0, 100, 0, 7);
		// Заливаем сразу же
		c.stroke();
	c.restore();

	// Правый верхний эллипс
	c.save();
		c.translate(450, 150);
		c.rotate(angle);
		c.scale(scale, 1);
		c.beginPath();
		c.arc(0, 0, 100, 0, 7);
	c.restore();
	// На этот раз перед заливкой сбросим трансформации
	c.stroke();

	// Левый нижний эллипс
	c.save();
		c.translate(150, 450);
		c.rotate(angle);
		c.scale(scale, 1);
		c.beginPath();
		c.arc(0, 0, 100, 0, 7);
		// Заливаем сразу же
		c.fill();
	c.restore();

	// Правый нижний эллипс
	c.save();
		c.translate(450, 450);
		c.rotate(angle);
		c.scale(scale, 1);
		c.beginPath();
		c.arc(0, 0, 100, 0, 7);
	c.restore();
	// Заливаем после восстановления матрицы трансформации
	c.fill();


	requestAnimationFrame(render);
})();