2021・05・31
*HTMLのcanvas要素にJavaScriptで矢印と文字のアニメーションを描写*
今回のサンプルコードの特徴は、描写に関してはCSSを一切使用していないという点です。
CSSでもアニメーションの設定はできますが、「あるアニメーションが完了したタイミングで、次のアニメーションを発火させる」というストーリー性のあるアニメーションはCSSだけではやや難しくなります。(できないことはないですが、アニメーションに要する秒数を完璧に計算・設定する必要があります)
また、CSSでは要素自体を動かすことになるので、特にレスポンシブでは要素の配置の関係上アニメーションの付加がしにくかったりなどのデメリットもあります。
そこで、canvas要素にJavaScriptで描写して画像として扱うことで、配置崩れなどを起こすことなく、他の要素に影響を及ぼさずにアニメーションをつけることが可能となります。
使用機能:HTML(canvas)・JavaScript
上記のサンプルコードを掲載しています。学習用としてご自由にコピペしてお使い下さい。(※スクロールできます)
HTML・CSS・JavaScript
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
<title></title>
<style>
canvas {
background-color: aliceblue;
display: block;
width: fit-content;
background-color: aliceblue;
margin: 0 auto;
}
@media screen and (max-width:600px) {
canvas { width : 70vw; }
}
</style>
</head>
<body>
<div class="canvasbox">
<canvas id="canvas" width="500" height="300"></canvas>
</div>
<script type="text/javascript">
{
const canvas = document.getElementById('canvas');
const animation = function () {
const context = canvas.getContext('2d');
let line1 = 0;
let line2 = 0;
let line3 = 0;
let line4 = 0;
let line5 = 0;
const text1 = 'お問い合わせは';
const text2 = 'こちら!!';
context.fillStyle = 'white';
context.strokeStyle = 'blue';
context.lineWidth = 14;
context.lineJoin = 'round';
context.lineCap = 'round';
context.beginPath();
context.moveTo(40,150);
line1 = 40;
start();
async function start() {
await new Promise((resolve) =>{
const intId = setInterval( () => {
line1 += 3;
context.lineTo(line1,150);
context.stroke();
if (line1 > 150) {
clearInterval(intId);
resolve();
}
},20);
});
await new Promise((resolve) =>{
line2 = 150;
line3 = 153;
context.moveTo(153,150);
const intId2 = setInterval( () => {
line2 -= 2;
line3 -= 3;
context.lineTo(line3,line2);
context.stroke();
if (line2 < 130) {
clearInterval(intId2);
resolve();
}
},30);
});
await new Promise((resolve) =>{
line4 = 153;
line5 = 150;
context.moveTo(153,150);
const intId3 = setInterval( () => {
line4 -= 3;
line5 += 2;
context.lineTo(line4,line5);
context.stroke();
if (line5 > 170) {
clearInterval(intId3);
resolve();
}
},30);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.fillStyle = 'white';
context.lineWidth = 6;
context.strokeStyle = 'darkblue';
context.font = 'bold 38px sans-serif';
context.strokeText(text1, 180, 150);
context.fillText(text1, 180, 150);
resolve();
},400);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.strokeText(text2, 180, 190);
context.fillText(text2, 180, 190);
resolve();
},400);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.fillStyle = 'rgb(255, 226, 77)';
context.lineWidth = 6;
context.strokeStyle = 'black';
context.font = 'bold 38px sans-serif';
context.strokeText(text1, 180, 150);
context.fillText(text1, 180, 150);
context.strokeText(text2, 180, 190);
context.fillText(text2, 180, 190);
resolve();
},400);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.fillStyle = 'white';
context.lineWidth = 6;
context.strokeStyle = 'darkblue';
context.font = 'bold 38px sans-serif';
context.strokeText(text1, 180, 150);
context.fillText(text1, 180, 150);
context.strokeText(text2, 180, 190);
context.fillText(text2, 180, 190);
resolve();
},400);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.fillStyle = 'rgb(255, 226, 77)';
context.lineWidth = 6;
context.strokeStyle = 'black';
context.font = 'bold 38px sans-serif';
context.strokeText(text1, 180, 150);
context.fillText(text1, 180, 150);
context.strokeText(text2, 180, 190);
context.fillText(text2, 180, 190);
resolve();
},400);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.fillStyle = 'white';
context.lineWidth = 6;
context.strokeStyle = 'darkblue';
context.font = 'bold 38px sans-serif';
context.strokeText(text1, 180, 150);
context.fillText(text1, 180, 150);
context.strokeText(text2, 180, 190);
context.fillText(text2, 180, 190);
resolve();
},400);
});
await new Promise((resolve) =>{
setTimeout( ()=>{
context.clearRect(0,0,500,300);
requestAnimationFrame(animation);
resolve();
},1400);
});
}
}
requestAnimationFrame(animation);
}
</script>
</body>
</html>