雪を降らせたので春夏秋冬を入れてみました
完全にネタ記事です
春=桜
夏=花火
秋=紅葉
冬=雪
やってみよう
いつも通り双子さんに聞きます
お願いしたこと
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秒くらいでピンク色の花火がひらくかんじ
①のあとに桜が画面全体に振るような感じ
花火が上がって桜が降るアニメーションを追加してもらいました
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();
}
その後紅葉した木と落ち葉を足してもらいました
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();
}
結果
生成AIってすごいですね
ハッピーかい?






