3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

雪を降らせたので春夏秋冬を入れてみました

完全にネタ記事です
春=桜
夏=花火
秋=紅葉
冬=雪

やってみよう

いつも通り双子さんに聞きます

お願いしたこと
function onLoad() {
	// ServiceNowに隠されていない"真のwindow"を特定する
	var realWindow = (function () {
		return this || (0, eval)('this');
	})();

	var realDoc = realWindow.document;

	if (!realDoc) {
		g_form.addErrorMessage("CRITICAL: DOM access is still blocked by ServiceNow security.");
		return;
	}

	try {
		// ここに雪のコードを記述
		startSnow(realDoc, realWindow);
	} catch (e) {
		g_form.addErrorMessage("DOM error: " + e.message);
	}
}

function startSnow(realDoc, realWindow) {


	// 2. もし realDoc 自体が null だった場合の最終手段
	if (!realDoc) {
		g_form.addErrorMessage("DOMへのアクセスが完全に遮断されています。Isolate Scriptの設定を再確認してください。");
		return;
	}

	// 二重実行防止
	if (realDoc.getElementById('snowCanvas')) return;

	// 3. Canvasの作成と設定
	var canvas = realDoc.createElement('canvas');

	canvas.id = 'snowCanvas';
	canvas.style.cssText = "position:fixed; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:99999; background-color: rgba(220, 220, 220, 0.4);";

	realDoc.body.appendChild(canvas);

	// --- 描画ロジック ---
	var ctx = canvas.getContext('2d');
	var W = realWindow.innerWidth;
	var H = realWindow.innerHeight;
	canvas.width = W;
	canvas.height = H;

	var mp = 50; // 雪の量
	var particles = [];
	for (var i = 0; i < mp; i++) {
		particles.push({
			x: Math.random() * W,
			y: Math.random() * H,
			r: Math.random() * 4 + 1,
			d: Math.random() * mp
		});
	}

	function draw() {
		ctx.clearRect(0, 0, W, H);
		ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
		ctx.beginPath();
		for (var i = 0; i < mp; i++) {
			var p = particles[i];
			ctx.moveTo(p.x, p.y);
			ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);
		}
		ctx.fill();
		update();
	}

	var angle = 0;
	function update() {
		angle += 0.01;
		for (var i = 0; i < mp; i++) {
			var p = particles[i];
			p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
			p.x += Math.sin(angle) * 2;
			if (p.x > W + 5 || p.x < -5 || p.y > H) {
				particles[i] = { x: Math.random() * W, y: -10, r: p.r, d: p.d };
			}
		}
	}

	setInterval(draw, 33);

}

この処理に以下を追加してほしい
①画面の真ん中から花火が上がって3秒くらいでピンク色の花火がひらくかんじ
①のあとに桜が画面全体に振るような感じ

花火が上がって桜が降るアニメーションを追加してもらいました

image.png

function onLoad() {
	var realWindow = (function () {
		return this || (0, eval)('this');
	})();

	var realDoc = realWindow.document;

	if (!realDoc) {
		g_form.addErrorMessage("CRITICAL: DOM access is still blocked.");
		return;
	}

	try {
		startVisualEffects(realDoc, realWindow);
	} catch (e) {
		g_form.addErrorMessage("DOM error: " + e.message);
	}
}

function startVisualEffects(realDoc, realWindow) {
	if (realDoc.getElementById('visualCanvas')) return;

	var canvas = realDoc.createElement('canvas');
	canvas.id = 'visualCanvas';
	// 背景色を少し暗くすると花火が綺麗に見えます(不要なら背景色を削除してください)
	canvas.style.cssText = "position:fixed; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:99999;";
	realDoc.body.appendChild(canvas);

	var ctx = canvas.getContext('2d');
	var W = realWindow.innerWidth;
	var H = realWindow.innerHeight;
	canvas.width = W;
	canvas.height = H;

	// --- 雪の設定 ---
	var mp = 50;
	var snowParticles = [];
	for (var i = 0; i < mp; i++) {
		snowParticles.push({
			x: Math.random() * W,
			y: Math.random() * H,
			r: Math.random() * 4 + 1,
			d: Math.random() * mp
		});
	}

	// --- 花火の設定 ---
	var firework = {
		x: W / 2,
		y: H,
		targetY: H * 0.3, // 画面の上部30%の位置で開く
		speed: (H - (H * 0.3)) / (3 * 60), // 約3秒(60fps想定)で到達
		state: 'launching', // launching(打ち上げ中) or exploded(爆発)
		particles: []
	};

	function createExplosion(x, y) {
		var count = 80;
		for (var i = 0; i < count; i++) {
			var angle = Math.random() * Math.PI * 2;
			var speed = Math.random() * 4 + 2;
			firework.particles.push({
				x: x,
				y: y,
				velX: Math.cos(angle) * speed,
				velY: Math.sin(angle) * speed,
				alpha: 1,
				decay: Math.random() * 0.015 + 0.01
			});
		}
	}

	var angle = 0;
	function mainLoop() {
		ctx.clearRect(0, 0, W, H);

		// 1. 雪の描画と更新
		angle += 0.01;
		ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
		ctx.beginPath();
		for (var i = 0; i < mp; i++) {
			var p = snowParticles[i];
			ctx.moveTo(p.x, p.y);
			ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);
			
			p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
			p.x += Math.sin(angle) * 2;
			if (p.x > W + 5 || p.x < -5 || p.y > H) {
				snowParticles[i] = { x: Math.random() * W, y: -10, r: p.r, d: p.d };
			}
		}
		ctx.fill();

		// 2. 花火の描画と更新
		if (firework.state === 'launching') {
			// 打ち上げの光
			ctx.fillStyle = "#FF69B4"; // ピンク
			ctx.beginPath();
			ctx.arc(firework.x, firework.y, 3, 0, Math.PI * 2);
			ctx.fill();

			firework.y -= firework.speed;
			if (firework.y <= firework.targetY) {
				firework.state = 'exploded';
				createExplosion(firework.x, firework.y);
			}
		} else if (firework.state === 'exploded') {
			// 爆発の火花
			for (var j = firework.particles.length - 1; j >= 0; j--) {
				var part = firework.particles[j];
				ctx.fillStyle = "rgba(255, 105, 180, " + part.alpha + ")"; // 鮮やかなピンク
				ctx.beginPath();
				ctx.arc(part.x, part.y, 2, 0, Math.PI * 2);
				ctx.fill();

				part.x += part.velX;
				part.y += part.velY;
				part.velY += 0.05; // 重力
				part.alpha -= part.decay;

				if (part.alpha <= 0) {
					firework.particles.splice(j, 1);
				}
			}
			// 全ての火花が消えたら、3秒後にまた打ち上げるならここをリセット
		}

		requestAnimationFrame(mainLoop);
	}

	mainLoop();
}

その後紅葉した木と落ち葉を足してもらいました

image.png

いろいろお願いしました
image.png

image.png

image.png

image.png

function onLoad() {
    var realWindow = (function () {
        return this || (0, eval)('this');
    })();
    var realDoc = realWindow.document;
    if (!realDoc) return;

    try {
        startFullEffect(realDoc, realWindow);
    } catch (e) {
        console.error("Effect error: " + e.message);
    }
}

function startFullEffect(realDoc, realWindow) {
    if (realDoc.getElementById('visualCanvas')) return;

    var canvas = realDoc.createElement('canvas');
    canvas.id = 'visualCanvas';
    canvas.style.cssText = "position:fixed; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:99999; background-color: rgba(0, 0, 0, 0.8);";
    realDoc.body.appendChild(canvas);

    var ctx = canvas.getContext('2d');
    var W = realWindow.innerWidth;
    var H = realWindow.innerHeight;
    canvas.width = W;
    canvas.height = H;

    // --- パーティクル設定 ---
    var snows = [];
    var sakura = [];
    var momiji = [];
    var firework = { x: W / 2, y: H, targetY: H * 0.3, speed: (H * 0.7) / 180, state: 'launching', particles: [] };

    // 木の設定
    var treeX = W - 120;
    var treeY = H - 10;
    var treeScale = 0.7;

    // 雪の初期化
    for (var i = 0; i < 50; i++) {
        snows.push({ x: Math.random() * W, y: Math.random() * H, r: Math.random() * 4 + 1, d: Math.random() * 50 });
    }

    // 桜生成関数
    function createSakura() {
        return {
            x: Math.random() * W,
            y: -20,
            r: Math.random() * 3 + 2,
            velX: Math.random() * 1 - 0.5,
            velY: Math.random() * 1 + 1,
            angle: Math.random() * Math.PI,
            swing: Math.random() * 0.02 + 0.01
        };
    }

    // 紅葉(とげとげ葉っぱ)生成関数
    function createMomiji() {
        return {
            x: treeX + (Math.random() * 40 - 20),
            y: treeY - (Math.random() * 110 * treeScale + 20),
            size: Math.random() * 5 + 4,
            velX: -(Math.random() * 2.5 + 1), // 左に飛ぶ
            velY: Math.random() * 1.5 - 0.5,
            angle: Math.random() * Math.PI,
            spin: Math.random() * 0.1 - 0.05,
            color: ['#D32F2F', '#FFEB3B', '#FBC02D', '#FF5722'][Math.floor(Math.random() * 4)] // 赤と黄色
        };
    }

    // とげとげしい木を描く関数
    function drawSpikyTree(ctx, x, y, scale) {
        ctx.save();
        ctx.translate(x, y);
        ctx.fillStyle = "#2D1B10";
        ctx.beginPath();
        ctx.moveTo(-5 * scale, 0); ctx.lineTo(-2 * scale, -100 * scale);
        ctx.lineTo(2 * scale, -100 * scale); ctx.lineTo(5 * scale, 0);
        ctx.fill();

        ctx.strokeStyle = "#2D1B10";
        ctx.lineWidth = 2 * scale;
        [[[0,-40],[-25,-70],[-40,-100]], [[0,-60],[30,-90],[50,-120]], [[0,-80],[5,-120],[-10,-150]]].forEach(pts => {
            ctx.beginPath(); ctx.moveTo(pts[0][0]*scale, pts[0][1]*scale);
            pts.slice(1).forEach(p => ctx.lineTo(p[0]*scale, p[1]*scale)); ctx.stroke();
        });

        function drawSpike(tx, ty, r, color) {
            ctx.fillStyle = color; ctx.beginPath();
            for(var i=0; i<10; i++) {
                var angle = (i * Math.PI * 2) / 10;
                var len = i % 2 === 0 ? r : r * 0.3;
                ctx.lineTo(tx + Math.cos(angle)*len, ty + Math.sin(angle)*len);
            }
            ctx.closePath(); ctx.fill();
        }

        [{x:0,y:-125,r:45,c:"#D32F2F"}, {x:-30,y:-85,r:35,c:"#FBC02D"}, {x:35,y:-95,r:30,c:"#FFEB3B"}, {x:10,y:-145,r:25,c:"#B71C1C"}]
        .forEach(s => drawSpike(s.x * scale, s.y * scale, s.r * scale, s.c));
        ctx.restore();
    }

    function mainLoop() {
        ctx.clearRect(0, 0, W, H);

        // 1. 雪の描画
        ctx.fillStyle = "rgba(255, 255, 255, 0.7)";
        ctx.beginPath();
        snows.forEach(function(p) {
            ctx.moveTo(p.x, p.y);
            ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
            p.y += 1 + p.r / 2;
            p.x += Math.sin(p.d) * 0.5;
            if (p.y > H) p.y = -10;
        });
        ctx.fill();

        // 2. 花火と桜の描画
        if (firework.state === 'launching') {
            ctx.fillStyle = "#FF69B4";
            ctx.beginPath();
            ctx.arc(firework.x, firework.y, 8, 0, Math.PI * 2);
            ctx.fill();
            firework.y -= firework.speed;
            if (firework.y <= firework.targetY) {
                firework.state = 'exploded';
                for (var j = 0; j < 60; j++) {
                    var ang = Math.random() * Math.PI * 2;
                    var spd = Math.random() * 5 + 2;
                    firework.particles.push({ x: firework.x, y: firework.y, vx: Math.cos(ang) * spd, vy: Math.sin(ang) * spd, a: 1 });
                }
            }
        } else if (firework.state === 'exploded') {
            firework.particles.forEach(function(p) {
                ctx.fillStyle = "rgba(255, 105, 180, " + p.a + ")";
                ctx.beginPath(); ctx.arc(p.x, p.y, 2, 0, Math.PI * 2); ctx.fill();
                p.x += p.vx; p.y += p.vy; p.vy += 0.05; p.a -= 0.01;
            });
            if (sakura.length < 40) sakura.push(createSakura());
        }

        ctx.fillStyle = "rgba(255, 183, 197, 0.8)";
        sakura.forEach(function(s) {
            ctx.save(); ctx.translate(s.x, s.y); ctx.rotate(s.angle);
            ctx.beginPath(); ctx.ellipse(0, 0, s.r * 1.5, s.r, 0, 0, Math.PI * 2); ctx.fill();
            ctx.restore();
            s.y += s.velY; s.x += Math.sin(s.angle) * 1.5; s.angle += s.swing;
            if (s.y > H) { s.y = -20; s.x = Math.random() * W; }
        });

        // 3. 木と紅葉の描画
        drawSpikyTree(ctx, treeX, treeY, treeScale);
        if (momiji.length < 30) momiji.push(createMomiji());
        momiji.forEach(function(m, idx) {
            ctx.save(); ctx.translate(m.x, m.y); ctx.rotate(m.angle);
            ctx.fillStyle = m.color;
            ctx.beginPath(); // とげ形葉っぱ
            ctx.moveTo(0, -m.size); ctx.lineTo(m.size/3, 0); ctx.lineTo(m.size, m.size/3); ctx.lineTo(0, m.size);
            ctx.lineTo(-m.size, m.size/3); ctx.lineTo(-m.size/3, 0); ctx.closePath(); ctx.fill();
            ctx.restore();
            m.x += m.velX; m.y += m.velY + Math.sin(m.x * 0.04) * 0.5; m.angle += m.spin;
            if (m.x < -20 || m.y > H) momiji.splice(idx, 1);
        });

        requestAnimationFrame(mainLoop);
    }
    mainLoop();
}

結果

30分くらいでそれっぽいものができました
レコーディング 2025-12-25 221015.gif

生成AIってすごいですね

ハッピーかい?

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?