Created
July 28, 2023 05:32
-
-
Save hkitago/aaa157555bf281faf08417e8b532860d to your computer and use it in GitHub Desktop.
put SVG file in Canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// キャンバスの取得 | |
const canvas = document.getElementById('canvas'); | |
const ctx = canvas.getContext('2d'); | |
// キャンバスを全画面に設定 | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
// SVGオブジェクトを保持する配列 | |
const svgObjects = []; | |
// イージング関数 | |
function easeInOutQuad(t) { | |
return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2; | |
} | |
// SVGファイルを読み込む関数 | |
function loadSVG(url, x, y, width, height) { | |
const svg = new Image(); | |
svg.src = url; | |
// タイムスタンプを記録 | |
const timestamp = Date.now(); | |
// アニメーションのフレーム数 | |
const duration = 30000; // 30秒間のアニメーション | |
const numFrames = 60; // 60フレームで30秒を表現 | |
// 1フレームごとの描画関数 | |
function drawFrame(currentFrame) { | |
// 時間の進行度合いを0から1の範囲に変換する | |
const time = currentFrame / numFrames; | |
// イージング関数を適用して透明度を計算 | |
const opacity = 1 - easeInOutQuad(time); | |
// キャンバスをクリア | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// すべてのSVGオブジェクトを描画 | |
svgObjects.forEach(svgObject => { | |
ctx.globalAlpha = svgObject.opacity; | |
ctx.drawImage(svgObject.svg, svgObject.x, svgObject.y, svgObject.width, svgObject.height); | |
}); | |
// 次のフレームを描画 | |
if (currentFrame < numFrames) { | |
requestAnimationFrame(() => drawFrame(currentFrame + 1)); | |
} else { | |
// 30秒後に透過処理アニメーションを開始 | |
const startTime = Date.now() - timestamp; | |
if (startTime >= 10000 && startTime <= 13000) { | |
const fadeOutTime = startTime - 10000; | |
const fadeOutFrames = (fadeOutTime / 3000) * 60; // 3秒間のアニメーション | |
requestAnimationFrame(() => drawFadeOutFrame(fadeOutFrames, svgObjects.length - 1)); | |
} | |
} | |
} | |
function drawFadeOutFrame(currentFrame, index) { | |
// 時間の進行度合いを0から1の範囲に変換する | |
const time = currentFrame / 60; | |
// イージング関数を適用して透明度を計算 | |
const opacity = 1 - easeInOutQuad(time); | |
// キャンバスをクリア | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// すべてのSVGオブジェクトを描画 | |
svgObjects.forEach((svgObject, i) => { | |
if (i === index) { | |
svgObject.opacity = opacity; // 透過処理アニメーションを適用 | |
} | |
ctx.globalAlpha = svgObject.opacity; | |
ctx.drawImage(svgObject.svg, svgObject.x, svgObject.y, svgObject.width, svgObject.height); | |
}); | |
// 次のフレームを描画 | |
if (currentFrame < 60) { | |
requestAnimationFrame(() => drawFadeOutFrame(currentFrame + 1, index)); | |
} else { | |
svgObjects.splice(index, 1); // アニメーションが終わったらSVGオブジェクトを配列から削除 | |
ctx.clearRect(0, 0, canvas.width, canvas.height); // キャンバスをクリア | |
svgObjects.forEach(svgObject => { | |
ctx.globalAlpha = svgObject.opacity; | |
ctx.drawImage(svgObject.svg, svgObject.x, svgObject.y, svgObject.width, svgObject.height); | |
}); | |
} | |
} | |
svg.onload = function() { | |
// アニメーションを開始 | |
requestAnimationFrame(() => drawFrame(0)); | |
}; | |
// SVGオブジェクトを配列に追加 | |
svgObjects.push({ svg, x, y, width, height, opacity: 1 }); | |
} | |
// タップとクリックの両方に対応した関数 | |
function placeSVGOnTapOrClick(event) { | |
let tapX, tapY; | |
if (event.touches && event.touches.length > 0) { | |
// タッチイベントの場合 | |
tapX = event.touches[0].clientX; | |
tapY = event.touches[0].clientY; | |
} else { | |
// クリックイベントの場合 | |
tapX = event.clientX; | |
tapY = event.clientY; | |
} | |
// SVGの幅と高さ | |
const svgWidth = 100; // ここにSVGの幅を指定します | |
const svgHeight = 100; // ここにSVGの高さを指定します | |
// SVGをタップやクリックの中心に配置するために、表示位置を計算 | |
const svgX = tapX - svgWidth / 2; | |
const svgY = tapY - svgHeight / 2; | |
// ここで、SVGファイルのURLと計算した表示位置を指定します。 | |
loadSVG('nanii.svg', svgX, svgY, svgWidth, svgHeight); | |
} | |
// タップイベントリスナーを追加 | |
canvas.addEventListener('click', placeSVGOnTapOrClick); | |
// クリックイベントリスナーを追加(タッチの場合も考慮) | |
canvas.addEventListener('touchend', placeSVGOnTapOrClick); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment