Страницы

вторник, 21 мая 2013 г.

HTML5 Canvas. Clip.

Пара примеров использования метода двухмерного контекста холста clip(): "Упражнение с циркулем" - имитация начертания циркулем цветка (наверняка каждый хотя бы один раз пробовал в школе) и "Солнечное затмение" - имитация солнечного затмения (+ музыкальное сопровождение с использованием тэга <audio>).


Исходный код "Упражнения с циркулем":
<!DOCTYPE HTML>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>HTML5 Canvas Clip</title>
  <style type="text/css">   
   #sign {font: normal 20px Segoe Script, sans-serif; display: block; color: #000; text-decoration: none;}
  </style>
  <script type="text/javascript">
   window.onload = function() {
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    var c = 260; // координата центра окружности
    var r = 240; // радиус окружности
    var t = 20; // отступ окружности от края холста
    // отступ для нахождения координаты края лепестка
    var off = Math.round(((r*3)/Math.sqrt(3))/2);
    
    context.save(); // сохраним контекст перед обрезкой    
    context.beginPath(); // первая окружность - маска обрезки
    context.arc(c, c, r, 0, 2 * Math.PI, false);
    context.clip();
    
    context.lineWidth = 3;
    context.strokeStyle = 'red';
    
    // массив значений координат
    var arr = [[c, t], [c + off, t + r/2], [c + off, t + r/2 + r], [c, t + r*2], [c - off, t + r/2 + r], [c - off, t + r/2]];
    var i=0;
    
    setTimeout(function() {setSign("Поехали!");}, 1);
    setTimeout(function() {setSign("Рисовал такой цветок в школе? Циркулем?");}, 2500);
    setTimeout(start, 1);
    
    function start() {     
     canvas.style.border = '3px solid blue';
     setTimeout(nextStep, 1000);
    }    
    
    function nextStep() {
     if (i > 5) {
      finish();
      return;     
     }
     context.beginPath();
     context.arc(arr[i][0], arr[i][1], r, 0, 2 * Math.PI, false);   
     context.stroke();
     i++;
     setTimeout(nextStep, 1000);
    }    
    
    function finish() {
     context.restore(); // восстановим сохраненный контекст
     context.beginPath();
     context.arc(c, c, r, 0, 2 * Math.PI, false);
     context.lineWidth = 3;
     context.strokeStyle = 'blue';
     context.stroke();
     setTimeout(function() {setSign("© Designed by Anatoly Demidovich");}, 1000);
     
    }
   }
   function setSign(txt) {
    var sign = document.getElementById('sign');
    while ( sign.firstChild ) sign.removeChild( sign.firstChild );
    var i=0;      
    function setText() {
     if (i == txt.length) return;    
     sign.appendChild(document.createTextNode(txt.charAt(i)));     
     i++;
     setTimeout(setText, 100);
    }
    setTimeout(setText, 100);
   }
  </script>
 </head>
 <body>
  <canvas id="myCanvas" width="520" height="520"></canvas>
  <a id="sign" href="http://www.daspot.ru"></a>  
 </body>
</html>

Результат:

Исходный код "Солнечного затмения":
<!DOCTYPE HTML>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>HTML5 Canvas Clip</title>
  <style type="text/css">   
   #sign {font: normal 20px Segoe Script, sans-serif; display: block; color: #000; text-decoration: none; height: 30px}
  </style>
  <script type="text/javascript">
   window.onload = function() {
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    var c = 260; // координата центра окружности
    var r = 240; // радиус окружности      
    
    context.save(); // сохраним контекст перед обрезкой    
    context.beginPath(); // первая окружность - маска обрезки
    context.arc(c, c, r, 0, 2 * Math.PI, false);
    context.clip();
    
    context.beginPath();
    context.arc(c, c, r, 0, 2 * Math.PI, false);
    context.fillStyle = 'red';
    context.fill();   
    
    i = -r;    
    setTimeout(nextStep, 100);
    setTimeout(function() {setSign("Солнечное затмение вручную . . .");}, 1000);
    setTimeout(function() {setSign("Солнце - красная окружность . . .");}, 6000);
    setTimeout(function() {setSign("Луна - синяя окружность . . .");}, 12000);
    
    function nextStep() {
     if (i > c) {
      finish();
      return;
     }
     i += 3;
     context.beginPath();
     context.arc(i, c, r, 0, 2 * Math.PI, false);
     context.fillStyle = 'blue';
     context.fill();
     setTimeout(nextStep, 100);
    }
    
    function finish() {
     context.restore(); // восстановим сохраненный контекст
     context.beginPath();
     context.arc(c, c, r, 0, 2 * Math.PI, false);
     context.lineWidth = 3;
     context.strokeStyle = 'yellow';
     context.stroke();
     setTimeout(function() {setSign("© Designed by Anatoly Demidovich");}, 1000);
    }
   }
   function setSign(txt) {
    var sign = document.getElementById('sign');
    while ( sign.firstChild ) sign.removeChild( sign.firstChild );
    var i=0;      
    function setText() {
     if (i == txt.length) return;    
     sign.appendChild(document.createTextNode(txt.charAt(i)));     
     i++;
     setTimeout(setText, 100);
    }
    setTimeout(setText, 100);
   }
  </script>
 </head>
 <body>
  <canvas id="myCanvas" width="520" height="520"></canvas>
  <a id="sign" href="http://www.daspot.ru"></a>
  <audio controls autoplay>   
   <source src="nikogda.mp3" type="audio/mpeg">
   Тег audio не поддерживается вашим браузером.
  </audio>
 </body>
</html>

Результат (в процессе):