Khoảng giá
Từ: 0 triệu
Đến: Không giới hạn
Ống kính Tokina ATX-i 100mm f/2.8 FF Macro For Canon EF | Chính hãng
Giá giao động:
10,890,000đ
Ống kính Tokina ATX-i 100mm f/2.8 FF Macro For Nikon F | Chính hãng
Giá giao động:
10,890,000đ
ỐNG KÍNH TOKINA 17-35mm F4 AT-X PRO (IF) FOR CANON
HÀNG MỚI ĐÃ TẠM HẾT
Hàng cũ giá từ:
2,700,000đ
ỐNG KÍNH TOKINA 50mm F1.8 FF FOR CANON
HÀNG MỚI ĐÃ TẠM HẾT
Đơn giá hàng cũ
Vui lòng gọi
ỐNG KÍNH TOKINA OPERA 50mm F1.4 FF FOR CANON
HÀNG MỚI ĐÃ TẠM HẾT
Đơn giá hàng cũ
Vui lòng gọi
ỐNG KÍNH TOKINA 11-16mm F2.8 AT-X PRO (IF) DX II FOR NIKON
HÀNG MỚI ĐÃ TẠM HẾT
Đơn giá hàng cũ
Vui lòng gọi
ỐNG KÍNH TOKINA AF 28-70 F2.8 AT-X PRO FOR CANON
HÀNG MỚI ĐÃ TẠM HẾT
Hàng cũ giá từ:
1,290,000đ
ỐNG KÍNH TOKINA OPERA 50mm F1.4 FF FOR NIKON
HÀNG MỚI ĐÃ TẠM HẾT
Đơn giá hàng cũ
Vui lòng gọi
ỐNG KÍNH TOKINA 50mm F1.8 FF FOR NIKON
HÀNG MỚI ĐÃ TẠM HẾT
Đơn giá hàng cũ
Vui lòng gọi
ỐNG KÍNH TOKINA 16-28mm F2.8 AT-X PRO (IF) FOR NIKON
HÀNG MỚI ĐÃ TẠM HẾT
Đơn giá hàng cũ
Vui lòng gọi
TOKINA AF 20-35mm F3.5-4.5 FOR CANON
HÀNG MỚI ĐÃ TẠM HẾT
ỐNG KÍNH TOKINA 11-16mm F2.8 AT-X PRO (IF) DX II CANON
HÀNG MỚI ĐÃ TẠM HẾT
Hàng cũ giá từ:
3,290,000đ
(function () {
const requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
const hieuUngPhaoHoa = {
canvas: document.getElementById('hieuUngPhaoHoa__canvas'),
ctx: null,
cw: window.innerWidth,
ch: window.innerHeight,
fireworks: [],
particles: [],
colors: [0, 60, 300], // Mảng các màu
hue: 0,
timerTotal: 30, // Giảm thời gian giữa các lần bắn
timerTick: 0,
isActive: true, // Biến để kiểm soát trạng thái hoạt động
init: function () {
this.ctx = this.canvas.getContext('2d');
this.canvas.width = this.cw;
this.canvas.height = this.ch;
this.loop();
// Tự động dừng sau 5 giây
setTimeout(() => {
this.isActive = false;
}, 5000);
},
calculateDistance: function (p1x, p1y, p2x, p2y) {
const xDistance = p1x - p2x;
const yDistance = p1y - p2y;
return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
},
random: function (min, max) {
return Math.random() * (max - min) + min;
},
createParticles: function (x, y) {
let particleCount = 30;
// Chọn màu ngẫu nhiên từ mảng
this.hue = this.colors[Math.floor(Math.random() * this.colors.length)];
while (particleCount--) {
this.particles.push(new Particle(x, y, this));
}
},
// Main loop
loop: function () {
if (!this.isActive && this.fireworks.length === 0 && this.particles.length === 0) {
return; // Dừng animation khi hết pháo hoa
}
requestAnimFrame(this.loop.bind(this));
this.hue += 0.5;
this.ctx.globalCompositeOperation = 'destination-out';
this.ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
this.ctx.fillRect(0, 0, this.cw, this.ch);
this.ctx.globalCompositeOperation = 'lighter';
let i = this.fireworks.length;
while (i--) {
this.fireworks[i].draw();
this.fireworks[i].update(i);
}
i = this.particles.length;
while (i--) {
this.particles[i].draw();
this.particles[i].update(i);
}
// Tự động bắn pháo hoa nếu đang hoạt động
if (this.isActive && this.timerTick >= this.timerTotal) {
this.fireworks.push(new Firework(
this.cw / 2, this.ch,
this.random(0, this.cw),
this.random(0, this.ch / 2),
this
));
this.timerTick = 0;
} else {
this.timerTick++;
}
}
};
// Firework class
class Firework {
constructor(sx, sy, tx, ty, main) {
this.main = main;
this.x = sx;
this.y = sy;
this.sx = sx;
this.sy = sy;
this.tx = tx;
this.ty = ty;
this.distanceToTarget = main.calculateDistance(sx, sy, tx, ty);
this.distanceTraveled = 0;
this.coordinates = [];
this.coordinateCount = 3;
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
this.angle = Math.atan2(ty - sy, tx - sx);
this.speed = 2;
this.acceleration = 1.05;
this.brightness = main.random(50, 70);
this.targetRadius = 1;
}
update(index) {
this.coordinates.pop();
this.coordinates.unshift([this.x, this.y]);
if (this.targetRadius < 8) {
this.targetRadius += 0.3;
} else {
this.targetRadius = 1;
}
this.speed *= this.acceleration;
const vx = Math.cos(this.angle) * this.speed;
const vy = Math.sin(this.angle) * this.speed;
this.distanceTraveled = this.main.calculateDistance(
this.sx, this.sy, this.x + vx, this.y + vy
);
if (this.distanceTraveled >= this.distanceToTarget) {
this.main.createParticles(this.tx, this.ty);
this.main.fireworks.splice(index, 1);
} else {
this.x += vx;
this.y += vy;
}
}
draw() {
this.main.ctx.beginPath();
this.main.ctx.moveTo(
this.coordinates[this.coordinates.length - 1][0],
this.coordinates[this.coordinates.length - 1][1]
);
this.main.ctx.lineTo(this.x, this.y);
this.main.ctx.strokeStyle = `hsl(${this.main.hue}, 100%, ${this.brightness}%)`;
this.main.ctx.stroke();
}
}
// Particle class
class Particle {
constructor(x, y, main) {
this.main = main;
this.x = x;
this.y = y;
this.coordinates = [];
this.coordinateCount = 5;
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
this.angle = main.random(0, Math.PI * 2);
this.speed = main.random(1, 10);
this.friction = 0.95;
this.gravity = 1;
this.hue = main.random(main.hue - 20, main.hue + 20);
this.brightness = main.random(50, 80);
this.alpha = 1;
this.decay = main.random(0.015, 0.03);
}
update(index) {
this.coordinates.pop();
this.coordinates.unshift([this.x, this.y]);
this.speed *= this.friction;
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed + this.gravity;
this.alpha -= this.decay;
if (this.alpha <= this.decay) {
this.main.particles.splice(index, 1);
}
}
draw() {
this.main.ctx.beginPath();
this.main.ctx.moveTo(
this.coordinates[this.coordinates.length - 1][0],
this.coordinates[this.coordinates.length - 1][1]
);
this.main.ctx.lineTo(this.x, this.y);
this.main.ctx.strokeStyle = `hsla(${this.hue}, 100%, ${this.brightness}%, ${this.alpha})`;
this.main.ctx.stroke();
}
}
// Khởi chạy khi trang load xong
window.addEventListener('load', () => hieuUngPhaoHoa.init());
})();