<div id="contents">
<canvas id="canvas">
Logo
</canvas>
</div>
body {
margin: 0;
padding: 0;
}
#contents {
position: relative;
width: 100vw;
height: 100vh;
}
// Canvas
const target = document.getElementById('contents') // canvasの親要素取得
const canvas = document.getElementById('canvas') // canvas取得
// 親のサイズ取得
let Cwidth = target.clientWidth
let Cheight = target.clientHeight
// Canvas サイズ設定
canvas.width = Cwidth
canvas.height = Cheight
// コンテキスト取得
const ctx = canvas.getContext('2d')
// Canvasの中央取得
let CenterW = Cwidth/2
let CenterH = Cheight/2
// 半径
const r = 100
// アニメーションID
let AnimateID
// Google fonts 読み込み後アニメーション実行
WebFont.load({
google: {
families: ['Amatic SC', 'cursive']
},
active: AnimateID = requestAnimationFrame(draw)
})
// 描画
function draw() {
// 描画リセット
ctx.clearRect(0, 0, Cwidth, Cheight)
// ドット
Dots()
// 顔の輪郭描画
faceLine()
// 顔のパーツ描画
faceParts()
// テキスト出力
outputText()
AnimateID = requestAnimationFrame(draw)
}
// ドット
let dots = []
for (let i=0; i<=9; i++) {
dots.push({
x: CenterW + getRandom(r, -r),
y: Cheight - getRandom(r, 0),
size: getRandom(15, 5),
xSpeed: getRandom(5, -5),
ySpeed: getRandom(5, 1),
flag: false,
counter: 0
})
}
function Dots() {
dots.forEach((value, index) => {
for (let i=index; i < dots.length; i++) {
let Xdiff = value['x'] - dots[i]['x']
let Ydiff = value['y'] - dots[i]['y']
if ( Math.floor(Math.sqrt(((Xdiff ** 2) + (Ydiff ** 2)))) <= 100 ) {
ctx.lineWidth = 0.5
ctx.strokeStyle = 'rgba(42, 54, 59, 1)'
ctx.shadowBlur = 15
ctx.shadowColor = 'rgba(42, 54, 59, 1)'
ctx.beginPath()
ctx.moveTo(value['x'], value['y'])
ctx.lineTo(dots[i]['x'], dots[i]['y'])
ctx.stroke()
}
}
if (getRandom(1000, 0) === 1) {
value['flag'] = true
}
if (value['flag'] === true) {
ctx.fillStyle = 'rgba(255,162,183,1)'
ctx.shadowColor = 'rgba(255,162,183,1)'
ctx.beginPath()
ctx.moveTo(value['x'] + getRandom(30, 20), value['y'] + getRandom(30, -30))
ctx.lineTo(value['x'] - getRandom(30, 20), value['y'] + getRandom(30, -30))
ctx.lineTo(value['x'] + getRandom(30, -30), value['y'] - getRandom(30, 20))
ctx.fill()
value['counter']++
if (value['counter'] >= 30) {
value['flag'] = false
value['counter'] = 0
}
} else {
ctx.fillStyle = 'rgba(42, 54, 59, 1)'
ctx.shadowBlur = 15
ctx.shadowColor = 'rgba(42, 54, 59, 1)'
ctx.beginPath()
ctx.arc(value['x'] + getRandom(2, -2), value['y'] + getRandom(2, -2), value['size'], 0, Math.PI * 2, true)
ctx.fill()
ctx.beginPath()
ctx.arc(value['x'] + getRandom(2, -2), value['y'] + getRandom(2, -2), value['size'], 0, Math.PI * 2, true)
ctx.fill()
ctx.beginPath()
ctx.arc(value['x'] + getRandom(2, -2), value['y'] + getRandom(2, -2), value['size'], 0, Math.PI * 2, true)
ctx.fill()
}
if (value['x'] >= (Cwidth + 20) || value['x'] <= -20 || value['y'] <= -20) {
value['x'] = CenterW + getRandom(r, -r)
value['y'] = Cheight - getRandom(r, 0)
value['xSpeed'] = getRandom(5, -5)
value['ySpeed'] = getRandom(5, 1)
value['size'] = getRandom(15, 5)
}
value['x'] += value['xSpeed']
value['y'] -= value['ySpeed']
})
}
// 顔の輪郭描画用関数
function faceLine() {
ctx.fillStyle = 'rgba(42, 54, 59, 1)'
ctx.shadowBlur = 20
ctx.shadowColor = 'rgba(42, 54, 59, 0.8)'
// 中心の円描画
ctx.beginPath()
ctx.arc(CenterW, Cheight, r, 0, Math.PI, true)
ctx.fill()
// 輪郭の円描画
for (let i=0; i <= 500; i++) {
let x = getRandom(r, -r)
let y = (Math.floor(Math.sqrt(((x * x) - (r * r)) * -1))) * -1
let size = Math.floor(Math.random() * 20) + 10
// 乱れさす
x += getRandom(10, -10)
y += getRandom(10, 0)
// 輪郭
ctx.beginPath()
ctx.arc(CenterW + x, Cheight + y, size, 0, Math.PI * 2, true)
ctx.fill()
}
}
// 目と口の描画用関数
function faceParts() {
ctx.fillStyle = 'rgba(255, 255, 255, 1)'
ctx.shadowColor = 'rgba(255, 255, 255, 1)'
ctx.shadowBlur = 10
for (let j=0; j <= 5; j ++) {
let x = getRandom(5, 0)
let y = getRandom(5, 0)
let size = getRandom(15, 10)
// 右目
ctx.beginPath()
ctx.arc(CenterW + (r/2 - x), Cheight - (r - 20 + y), size, 0, Math.PI * 2, true)
ctx.fill()
// 左目
ctx.beginPath()
ctx.arc(CenterW - (r/2 - x), Cheight - (r - 20 + y), size, 0, Math.PI * 2, true)
ctx.fill()
}
// 口
ctx.beginPath()
ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)'
ctx.lineWidth = 2
ctx.lineJoin = 'bevel'
for (let k=-20; k < 20; k++) {
let y = getRandom(10, 0)
if (k === -20) {
ctx.moveTo(CenterW + k, Cheight - (r - 30 + y))
} else {
ctx.lineTo(CenterW + k, Cheight - (r - 30 + y))
}
}
ctx.stroke()
}
// テキスト出力用関数
function outputText() {
ctx.fillStyle = 'rgba(42, 54, 59, 1)'
ctx.shadowColor = 'rgba(42, 54, 59, 1)'
ctx.shadowBlur = 15
let space
if (Cwidth <= 300) {
ctx.font = '80px Amatic SC'
space = 20
} else {
ctx.font = '120px Amatic SC'
space = 50
}
let NoobSize = ctx.measureText('Noob')
let FESize = ctx.measureText('FE')
let BlogSize = ctx.measureText('Blog')
ctx.fillText('Noob', CenterW - (NoobSize.width + (FESize.width / 2) + space), CenterH - space)
ctx.fillText('Blog', CenterW + ((FESize.width / 2) + space), CenterH - space)
ctx.fillStyle = 'rgba(255,162,183,1)'
ctx.fillText('FE', CenterW - (FESize.width / 2), CenterH - space)
}
// ランダム生成用関数
function getRandom(max, min) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
This Pen doesn't use any external CSS resources.