Sunrise
جرب استخدام هذا الكود:
<?php
/**
* كود قصير لعرض تأثير الجسيمات لشعار الموقع (معدّل)
*/
function render_logo_particle_shortcode() {
ob_start();
?>
<div class="logo-particle-container">
<canvas id="logo-particle-canvas"></canvas>
</div>
<style>
.logo-particle-container {
position: relative;
width: 100%;
/* لجعل الحاوية مربّعة حساسًا للعرض */
padding-top: 100%;
background-color: #000;
overflow: hidden;
}
.logo-particle-container canvas {
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
display: block;
}
</style>
<script>
jQuery(document).ready(function($) {
var logoElement = $(".site-logo img, .custom-logo, img[alt*='logo'], .logo img").first();
if (!logoElement.length) {
console.error("لم يتم العثور على صورة الشعار في الصفحة");
return;
}
var logoSrc = logoElement.attr("src");
var canvas = document.getElementById("logo-particle-canvas");
class Particle {
constructor(x, y, size, baseX, baseY, ctx, color) {
this.x = x; this.y = y;
this.size = size;
this.baseX = baseX; this.baseY = baseY;
this.ctx = ctx; this.color = color;
this.density = Math.random() * 30 + 2;
}
draw() {
this.ctx.fillStyle = this.color;
this.ctx.beginPath();
this.ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
this.ctx.closePath();
this.ctx.fill();
}
update(mouse) {
if (mouse.x === null) {
this.x += (this.baseX - this.x) * 0.05;
this.y += (this.baseY - this.y) * 0.05;
} else {
let dx = mouse.x - this.x;
let dy = mouse.y - this.y;
let dist = Math.sqrt(dx*dx + dy*dy);
if (dist < mouse.radius) {
let force = (mouse.radius - dist) / mouse.radius;
let dirX = (dx / dist) * force * this.density;
let dirY = (dy / dist) * force * this.density;
this.x -= dirX;
this.y -= dirY;
} else {
this.x += (this.baseX - this.x) * 0.05;
this.y += (this.baseY - this.y) * 0.05;
}
}
}
}
class App {
constructor(canvas, imageSrc) {
this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this.image = new Image();
this.image.crossOrigin = "Anonymous";
this.image.src = imageSrc;
this.particles = [];
this.mouse = { x: null, y: null, radius: 150 };
this.image.onload = () => this.resize();
this.animate();
this.addEventListeners();
}
resize() {
// زيادة الدقة حسب جهاز المستخدم
const dpr = window.devicePixelRatio || 1;
const cssW = this.canvas.offsetWidth;
const cssH = this.canvas.offsetHeight;
this.canvas.width = cssW * dpr;
this.canvas.height = cssH * dpr;
this.ctx.scale(dpr, dpr);
this.particles = [];
this.initParticles(cssW, cssH);
}
initParticles(cssW, cssH) {
// نستخدم الأبعاد بوحدة CSS بكسل لحساب حجم الشعار ومسافات الجسيمات
const w = cssW;
const h = cssH;
const logoSize = Math.min(w, h) * 0.6;
const logoX = (w - logoSize) / 2;
const logoY = (h - logoSize) / 2;
// رسم الشعار على الكانڤاس (بنسبة dpi)
this.ctx.clearRect(0, 0, w, h);
this.ctx.drawImage(this.image, logoX, logoY, logoSize, logoSize);
// استخراج بيانات الصورة
const dpr = window.devicePixelRatio || 1;
const imgData = this.ctx.getImageData(logoX * dpr, logoY * dpr, logoSize * dpr, logoSize * dpr).data;
// ضبط المسافة بين الجسيمات ديناميكيًا
let spacing = 4;
if (logoSize < 200) spacing = 2;
else if (logoSize < 400) spacing = 3;
const cols = Math.floor(logoSize / spacing);
const rows = Math.floor(logoSize / spacing);
const particleW = logoSize / cols;
const particleH = logoSize / rows;
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const posX = x * particleW + logoX;
const posY = y * particleH + logoY;
const px = Math.floor(x * particleW * dpr);
const py = Math.floor(y * particleH * dpr);
const idx = (py * Math.floor(logoSize * dpr) + px) * 4;
const a = imgData[idx+3];
if (a > 0) {
const r = imgData[idx];
const g = imgData[idx+1];
const b = imgData[idx+2];
const color = `rgba(${r},${g},${b},${a/255})`;
const size = Math.random() * 0.7 + 0.3;
this.particles.push(new Particle(posX, posY, size, posX, posY, this.ctx, color));
}
}
}
}
animate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.particles.forEach(p => {
p.update(this.mouse);
p.draw();
});
requestAnimationFrame(() => this.animate());
}
addEventListeners() {
this.canvas.addEventListener("mousemove", e => {
const rect = this.canvas.getBoundingClientRect();
this.mouse.x = e.clientX - rect.left;
this.mouse.y = e.clientY - rect.top;
});
this.canvas.addEventListener("mouseleave", () => {
this.mouse.x = null;
this.mouse.y = null;
});
}
}
var app = new App(canvas, logoSrc);
$(window).on('resize', () => app.resize());
if (window.elementorFrontend) {
elementorFrontend.hooks.addAction(
'frontend/element_ready/shortcode.default',
function($scope) {
if ($scope.find('#logo-particle-canvas').length) {
app.resize();
}
}
);
}
});
</script>
<?php
return ob_get_clean();
}
add_shortcode('logo_particles', 'render_logo_particle_shortcode');