‘Bắt trend’ code trái tim của thủ khoa Lý để tặng người yêu dịp Noel 2022

Trong thời gian gần đây, việc tỏ tình bằng hình ảnh trái tim được làm bằng code đã trở thành một trào lưu siêu hot với giới trẻ. Nhân dịp lễ Noel này, hãy “bắt trend” code trái tim của thủ khoa Lý để gửi tặng đến người yêu một món quà Giáng sinh độc đáo, ấn tượng và đáng nhớ nhất.

7 cách làm code hình trái tim ấn tượng tặng người yêu dịp Giáng sinh 2022

Ngoài những món quà tặng Giáng sinh thông thường, các chàng trai có thể tự làm ra một trái tim độc đáo từ những đoạn code đơn giản để gửi tặng nàng vào đúng đêm Giáng sinh và khiến nàng phải bất ngờ vì món quà “hot trend” đẹp, độc, lạ này.

Để có thể “bắt trend” tỏ tình ngọt ngào của thủ khoa Lý và tạo ra một món quà Giáng sinh lãng mạn để tặng cho người yêu, hãy cùng điểm qua những cách làm code trái tim độc đáo và ấn tượng sau đây:

Cách 1: Làm code trái tim cơ bản

Đây là một trong những mẫu trái tim cơ bản được sử dụng phổ biến nhất ngay từ lúc trào lưu làm code trái tim trở nên thịnh hành trên các trang mạng xã hội.

Theo đó, hình trái tim đơn giản này được lập trình bởi code HTML để tạo ra hiệu ứng chuyển động của các trái tim nhỏ màu hồng thành phần viền của một trái tim lớn. Cách làm này rất dễ thực hiện mà vẫn có thể tạo ra một thành quả không kém phần đẹp mắt, ấn tượng để dành tặng người yêu trong dịp Noel.

Ảnh: codingground

Chi tiết cách làm code trái tim cơ bản:

Bước 1: Sao chép nguồn code trái tim cơ bản sau đây:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE> Heart </TITLE>

<META NAME="Generator" CONTENT="EditPlus">

<META NAME="Author" CONTENT="">

<META NAME="Keywords" CONTENT="">

<META NAME="Description" CONTENT="">

<style>

html, body {

height: 100%;

padding: 0;

margin: 0;

background: black;

}

canvas {

position: absolute;

width: 100%;

height: 100%;

}

</style>

</HEAD>

 

<BODY>

<canvas id="pinkboard"></canvas>

<script>

/*

* Settings

*/

var settings = {

particles: {

length: 500, // maximum amount of particles

duration: 2, // particle duration in sec

velocity: 100, // particle velocity in pixels/sec

effect: -0.75, // play with this for a nice effect

size: 30, // particle size in pixels

},

};

 

/*

* RequestAnimationFrame polyfill by Erik Möller

*/

(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

 

/*

* Point class

*/

var Point = (function() {

function Point(x, y) {

this.x = (typeof x !== 'undefined') ? x : 0;

this.y = (typeof y !== 'undefined') ? y : 0;

}

Point.prototype.clone = function() {

return new Point(this.x, this.y);

};

Point.prototype.length = function(length) {

if (typeof length == 'undefined')

return Math.sqrt(this.x * this.x + this.y * this.y);

this.normalize();

this.x *= length;

this.y *= length;

return this;

};

Point.prototype.normalize = function() {

var length = this.length();

this.x /= length;

this.y /= length;

return this;

};

return Point;

})();

 

/*

* Particle class

*/

var Particle = (function() {

function Particle() {

this.position = new Point();

this.velocity = new Point();

this.acceleration = new Point();

this.age = 0;

}

Particle.prototype.initialize = function(x, y, dx, dy) {

this.position.x = x;

this.position.y = y;

this.velocity.x = dx;

this.velocity.y = dy;

this.acceleration.x = dx * settings.particles.effect;

this.acceleration.y = dy * settings.particles.effect;

this.age = 0;

};

Particle.prototype.update = function(deltaTime) {

this.position.x += this.velocity.x * deltaTime;

this.position.y += this.velocity.y * deltaTime;

this.velocity.x += this.acceleration.x * deltaTime;

this.velocity.y += this.acceleration.y * deltaTime;

this.age += deltaTime;

};

Particle.prototype.draw = function(context, image) {

function ease(t) {

return (--t) * t * t + 1;

}

var size = image.width * ease(this.age / settings.particles.duration);

context.globalAlpha = 1 - this.age / settings.particles.duration;

context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);

};

return Particle;

})();

 

/*

* ParticlePool class

*/

var ParticlePool = (function() {

var particles,

firstActive = 0,

firstFree = 0,

duration = settings.particles.duration;

 

function ParticlePool(length) {

// create and populate particle pool

particles = new Array(length);

for (var i = 0; i < particles.length; i++)

particles[i] = new Particle();

}

ParticlePool.prototype.add = function(x, y, dx, dy) {

particles[firstFree].initialize(x, y, dx, dy);

 

// handle circular queue

firstFree++;

if (firstFree == particles.length) firstFree = 0;

if (firstActive == firstFree ) firstActive++;

if (firstActive == particles.length) firstActive = 0;

};

ParticlePool.prototype.update = function(deltaTime) {

var i;

 

// update active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].update(deltaTime);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].update(deltaTime);

for (i = 0; i < firstFree; i++)

particles[i].update(deltaTime);

}

 

// remove inactive particles

while (particles[firstActive].age >= duration && firstActive != firstFree) {

firstActive++;

if (firstActive == particles.length) firstActive = 0;

}

 

 

};

ParticlePool.prototype.draw = function(context, image) {

// draw active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].draw(context, image);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].draw(context, image);

for (i = 0; i < firstFree; i++)

particles[i].draw(context, image);

}

};

return ParticlePool;

})();

 

/*

* Putting it all together

*/

(function(canvas) {

var context = canvas.getContext('2d'),

particles = new ParticlePool(settings.particles.length),

particleRate = settings.particles.length / settings.particles.duration, // particles/sec

time;

 

// get point on heart with -PI <= t <= PI

function pointOnHeart(t) {

return new Point(

160 * Math.pow(Math.sin(t), 3),

130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25

);

}

 

// creating the particle image using a dummy canvas

var image = (function() {

var canvas = document.createElement('canvas'),

context = canvas.getContext('2d');

canvas.width = settings.particles.size;

canvas.height = settings.particles.size;

// helper function to create the path

function to(t) {

var point = pointOnHeart(t);

point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;

point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;

return point;

}

// create the path

context.beginPath();

var t = -Math.PI;

var point = to(t);

context.moveTo(point.x, point.y);

while (t < Math.PI) {

t += 0.01; // baby steps!

point = to(t);

context.lineTo(point.x, point.y);

}

context.closePath();

// create the fill

context.fillStyle = '#ea80b0';

context.fill();

// create the image

var image = new Image();

image.src = canvas.toDataURL();

return image;

})();

 

// render that thing!

function render() {

// next animation frame

requestAnimationFrame(render);

 

// update time

var newTime = new Date().getTime() / 1000,

deltaTime = newTime - (time || newTime);

time = newTime;

 

// clear canvas

context.clearRect(0, 0, canvas.width, canvas.height);

 

// create new particles

var amount = particleRate * deltaTime;

for (var i = 0; i < amount; i++) {

var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());

var dir = pos.clone().length(settings.particles.velocity);

particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);

}

 

// update and draw particles

particles.update(deltaTime);

particles.draw(context, image);

}

 

// handle (re-)sizing of the canvas

function onResize() {

canvas.width = canvas.clientWidth;

canvas.height = canvas.clientHeight;

}

window.onresize = onResize;

 

// delay rendering bootstrap

setTimeout(function() {

onResize();

render();

}, 10);

})(document.getElementById('pinkboard'));

 

 

 

var colours=new Array('#f00', '#f06', '#f0f', '#f6f', '#f39', '#f9c'); // colours of the hearts

var minisize=10; // smallest size of hearts in pixels

var maxisize=20; // biggest size of hearts in pixels

var hearts=100; // maximum number of hearts on screen

var over_or_under="over"; // set to "over" for hearts to always be on top, or "under" to allow them to float behind other objects

 

/*****************************

*JavaScript Love Heart Cursor*

* (c)2013+ mf2fm web-design *

* http://www.mf2fm.com/rv *

* DON'T EDIT BELOW THIS BOX *

*****************************/

var x=ox=400;

var y=oy=300;

var swide=800;

var shigh=600;

var sleft=sdown=0;

var herz=new Array();

var herzx=new Array();

var herzy=new Array();

var herzs=new Array();

var kiss=false;

 

if (typeof('addRVLoadEvent')!='function') function addRVLoadEvent(funky) {

var oldonload=window.onload;

if (typeof(oldonload)!='function') window.onload=funky;

else window.onload=function() {

if (oldonload) oldonload();

funky();

}

}

 

addRVLoadEvent(mwah);

 

function mwah() { if (document.getElementById) {

var i, heart;

for (i=0; i<hearts; i++) {

heart=createDiv("auto", "auto");

heart.style.visibility="hidden";

heart.style.zIndex=(over_or_under=="over")?"1001":"0";

heart.style.color=colours[i%colours.length];

heart.style.pointerEvents="none";

if (navigator.appName=="Microsoft Internet Explorer") heart.style.filter="alpha(opacity=75)";

else heart.style.opacity=0.45;

heart.appendChild(document.createTextNode(String.fromCharCode(9829)));

document.body.appendChild(heart);

herz[i]=heart;

herzy[i]=false;

}

set_scroll();

set_width();

herzle();

}}

 

function herzle() {

var c;

if (Math.abs(x-ox)>1 || Math.abs(y-oy)>1) {

ox=x;

oy=y;

for (c=0; c<hearts; c++) if (herzy[c]===false) {

herz[c].firstChild.nodeValue=String.fromCharCode(9829);

herz[c].style.left=(herzx[c]=x-minisize/2)+"px";

herz[c].style.top=(herzy[c]=y-minisize)+"px";

herz[c].style.fontSize=minisize+"px";

herz[c].style.fontWeight='normal';

herz[c].style.visibility='visible';

herzs[c]=minisize;

break;

}

}

for (c=0; c<hearts; c++) if (herzy[c]!==false) blow_me_a_kiss(c);

setTimeout("herzle()", 30);

}

 

document.onmousedown=pucker;

document.onmouseup=function(){clearTimeout(kiss);};

 

function pucker() {

ox=-1;

oy=-1;

kiss=setTimeout('pucker()', 100);

}

 

function blow_me_a_kiss(i) {

herzy[i]-=herzs[i]/minisize+i%2;

herzx[i]+=(i%5-2)/5;

if (herzy[i]<sdown-herzs[i] || herzx[i]<sleft-herzs[i] || herzx[i]>sleft+swide-herzs[i]) {

herz[i].style.visibility="hidden";

herzy[i]=false;

}

else if (herzs[i]>minisize+1 && Math.random()<2.5/hearts) break_my_heart(i);

else {

if (Math.random()<maxisize/herzy[i] && herzs[i]<maxisize) herz[i].style.fontSize=(++herzs[i])+"px";

herz[i].style.top=herzy[i]+"px";

herz[i].style.left=herzx[i]+"px";

}

}

 

function break_my_heart(i) {

var t;

herz[i].firstChild.nodeValue=String.fromCharCode(9676);

herz[i].style.fontWeight='bold';

herzy[i]=false;

for (t=herzs[i]; t<=maxisize; t++) setTimeout('herz['+i+'].style.fontSize="'+t+'px"', 60*(t-herzs[i]));

setTimeout('herz['+i+'].style.visibility="hidden";', 60*(t-herzs[i]));

}

 

document.onmousemove=mouse;

function mouse(e) {

if (e) {

y=e.pageY;

x=e.pageX;

}

else {

set_scroll();

y=event.y+sdown;

x=event.x+sleft;

}

}

 

window.onresize=set_width;

function set_width() {

var sw_min=999999;

var sh_min=999999;

if (document.documentElement && document.documentElement.clientWidth) {

if (document.documentElement.clientWidth>0) sw_min=document.documentElement.clientWidth;

if (document.documentElement.clientHeight>0) sh_min=document.documentElement.clientHeight;

}

if (typeof(self.innerWidth)=='number' && self.innerWidth) {

if (self.innerWidth>0 && self.innerWidth<sw_min) sw_min=self.innerWidth;

if (self.innerHeight>0 && self.innerHeight<sh_min) sh_min=self.innerHeight;

}

if (document.body.clientWidth) {

if (document.body.clientWidth>0 && document.body.clientWidth<sw_min) sw_min=document.body.clientWidth;

if (document.body.clientHeight>0 && document.body.clientHeight<sh_min) sh_min=document.body.clientHeight;

}

if (sw_min==999999 || sh_min==999999) {

sw_min=800;

sh_min=600;

}

swide=sw_min;

shigh=sh_min;

}

 

window.onscroll=set_scroll;

function set_scroll() {

if (typeof(self.pageYOffset)=='number') {

sdown=self.pageYOffset;

sleft=self.pageXOffset;

}

else if (document.body && (document.body.scrollTop || document.body.scrollLeft)) {

sdown=document.body.scrollTop;

sleft=document.body.scrollLeft;

}

else if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {

sleft=document.documentElement.scrollLeft;

sdown=document.documentElement.scrollTop;

}

else {

sdown=0;

sleft=0;

}

}

 

function createDiv(height, width) {

var div=document.createElement("div");

div.style.position="absolute";

div.style.height=height;

div.style.width=width;

div.style.overflow="hidden";

div.style.backgroundColor="transparent";

return (div);

}

// ]]>

</script>

</BODY>

</HTML>

Bước 2: Truy cập vào đường link https://www.tutorialspoint.com/online_html_editor.php và dán mã nguồn vào khung “Source Code” phía bên trái.

Thành quả hình trái tim được tạo ra từ phần mã nguồn sẽ được hiển thị ở khung phía bên phải màn hình.

Chỉ với hai bước đơn giản là bạn đã có thể tạo ra một món quà Giáng sinh đậm chất “ngôn tình” khiến cho nàng phải “rung rinh” vì sự lãng mạn của mình.

Ảnh: codingground

Cách 2: Làm code trái tim đập màu đỏ

Một cách cách làm khác mà bạn có thể tham khảo chính là sử dụng đoạn mã nguồn HTML để tạo ra một trái tim màu đỏ với hiệu ứng chuyển động theo nhịp đập chân thật.

Khác với mẫu trái tim trước, điểm nhấn của hình trái tim màu đỏ này chính là phần hiệu ứng động của hàng loạt trái tim nhỏ lan tỏa xung quanh tạo nên một trái tim màu đỏ rực rỡ vô cùng “xịn sò” và dễ thương. Chắc hẳn các nàng sẽ rất bất ngờ và hạnh phúc khi nhận được món quà Giáng sinh độc đáo này.

Ảnh: codingground

Về cơ bản, các trái tim bằng code đều có cách làm giống nhau, vì vậy để làm code trái tim đập màu đỏ bạn cũng sẽ thực hiện các bước tương tự như sau:

Chi tiết cách làm code trái tim đập màu đỏ:

Bước 1: Sao chép nguồn code trái tim đập màu đỏ sau đây:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE> MINH IT </TITLE>

<META NAME="Generator" CONTENT="EditPlus">

<META NAME="Author" CONTENT="">

<META NAME="Keywords" CONTENT="">

<META NAME="Description" CONTENT="">

<link rel="stylesheet" href="style.css">

<style>

html, body {

height: 100%;

padding: 0;

margin: 0;

background: rgba(0, 0, 0, 0.851);

}

canvas {

position: absolute;

width: 100%;

height: 100%;

}

</style>

</HEAD>

<BODY>

<div class="box">

<canvas id="pinkboard"></canvas>

</div>

<script>

var settings = {

particles: {

length: 10000, // maximum amount of particles

duration: 4, // particle duration in sec

velocity: 80, // particle velocity in pixels/sec

effect: -1.3, // play with this for a nice effect

size: 8, // particle size in pixels

},

};

/*

*/

(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

/*

* Point class

*/

var Point = (function() {

function Point(x, y) {

this.x = (typeof x !== 'undefined') ? x : 0;

this.y = (typeof y !== 'undefined') ? y : 0;

}

Point.prototype.clone = function() {

return new Point(this.x, this.y);

};

Point.prototype.length = function(length) {

if (typeof length == 'undefined')

return Math.sqrt(this.x * this.x + this.y * this.y);

this.normalize();

this.x *= length;

this.y *= length;

return this;

};

Point.prototype.normalize = function() {

var length = this.length();

this.x /= length;

this.y /= length;

return this;

};

return Point;

})();

/*

* Particle class

*/

var Particle = (function() {

function Particle() {

this.position = new Point();

this.velocity = new Point();

this.acceleration = new Point();

this.age = 0;

}

Particle.prototype.initialize = function(x, y, dx, dy) {

this.position.x = x;

this.position.y = y;

this.velocity.x = dx;

this.velocity.y = dy;

this.acceleration.x = dx * settings.particles.effect;

this.acceleration.y = dy * settings.particles.effect;

this.age = 0;

};

Particle.prototype.update = function(deltaTime) {

this.position.x += this.velocity.x * deltaTime;

this.position.y += this.velocity.y * deltaTime;

this.velocity.x += this.acceleration.x * deltaTime;

this.velocity.y += this.acceleration.y * deltaTime;

this.age += deltaTime;

};

Particle.prototype.draw = function(context, image) {

function ease(t) {

return (--t) * t * t + 1;

}

var size = image.width * ease(this.age / settings.particles.duration);

context.globalAlpha = 1 - this.age / settings.particles.duration;

context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);

};

return Particle;

})();

/*

* ParticlePool class

*/

var ParticlePool = (function() {

var particles,

firstActive = 0,

firstFree = 0,

duration = settings.particles.duration;

 

function ParticlePool(length) {

// create and populate particle pool

particles = new Array(length);

for (var i = 0; i < particles.length; i++)

particles[i] = new Particle();

}

ParticlePool.prototype.add = function(x, y, dx, dy) {

particles[firstFree].initialize(x, y, dx, dy);

 

// handle circular queue

firstFree++;

if (firstFree == particles.length) firstFree = 0;

if (firstActive == firstFree ) firstActive++;

if (firstActive == particles.length) firstActive = 0;

};

ParticlePool.prototype.update = function(deltaTime) {

var i;

 

// update active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].update(deltaTime);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].update(deltaTime);

for (i = 0; i < firstFree; i++)

particles[i].update(deltaTime);

}

 

// remove inactive particles

while (particles[firstActive].age >= duration && firstActive != firstFree) {

firstActive++;

if (firstActive == particles.length) firstActive = 0;

}

 

 

};

ParticlePool.prototype.draw = function(context, image) {

// draw active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].draw(context, image);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].draw(context, image);

for (i = 0; i < firstFree; i++)

particles[i].draw(context, image);

}

};

return ParticlePool;

})();

/*

* Putting it all together

*/

(function(canvas) {

var context = canvas.getContext('2d'),

particles = new ParticlePool(settings.particles.length),

particleRate = settings.particles.length / settings.particles.duration, // particles/sec

time;

 

// get point on heart with -PI <= t <= PI

function pointOnHeart(t) {

return new Point(

160 * Math.pow(Math.sin(t), 3),

130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25

);

}

 

// creating the particle image using a dummy canvas

var image = (function() {

var canvas = document.createElement('canvas'),

context = canvas.getContext('2d');

canvas.width = settings.particles.size;

canvas.height = settings.particles.size;

// helper function to create the path

function to(t) {

var point = pointOnHeart(t);

point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;

point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;

return point;

}

// create the path

context.beginPath();

var t = -Math.PI;

var point = to(t);

context.moveTo(point.x, point.y);

while (t < Math.PI) {

t += 0.01; // baby steps!

point = to(t);

context.lineTo(point.x, point.y);

}

context.closePath();

// create the fill

context.fillStyle = '#f50b02';

context.fill();

// create the image

var image = new Image();

image.src = canvas.toDataURL();

return image;

})();

 

// render that thing!

function render() {

// next animation frame

requestAnimationFrame(render);

 

// update time

var newTime = new Date().getTime() / 1000,

deltaTime = newTime - (time || newTime);

time = newTime;

 

// clear canvas

context.clearRect(0, 0, canvas.width, canvas.height);

 

// create new particles

var amount = particleRate * deltaTime;

for (var i = 0; i < amount; i++) {

var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());

var dir = pos.clone().length(settings.particles.velocity);

particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);

}

 

// update and draw particles

particles.update(deltaTime);

particles.draw(context, image);

}

 

// handle (re-)sizing of the canvas

function onResize() {

canvas.width = canvas.clientWidth;

canvas.height = canvas.clientHeight;

}

window.onresize = onResize;

 

// delay rendering bootstrap

setTimeout(function() {

onResize();

render();

}, 10);

})(document.getElementById('pinkboard'));

</script>

</BODY>

</HTML>

Bước 2: Truy cập vào liên kết https://www.tutorialspoint.com/online_html_editor.php

Sau đó dán mã nguồn vào khung “Source Code” phía bên trái. Tiếp theo, hình trái tim chuyển động màu đỏ sẽ được hiển thị ở khung kết quả nằm ở phía bên phải màn hình.

Bạn có thể phóng to hoặc thu nhỏ phần khung kết quả này để có thể chiêm ngưỡng thành quả sắc nét và đẹp mắt hơn.

 

Ảnh: codingground

 

Cách 3: Làm code trái tim huyền bí

Nếu như bạn đang tìm kiếm một trái tim sáng tạo và ấn tượng để tặng cho người yêu trong ngày Giáng sinh, ắt hẳn mẫu trái tim huyền bí này sẽ là sự lựa chọn hoàn hảo dành cho bạn.

Đây là một mẫu code được các “cao thủ” IT tại Việt Nam sáng tạo theo sở thích của mình, do đó hình ảnh trái tim này không được lập trình dựa trên bản gốc mà sở hữu một giao diện rất đặc biệt với hiệu ứng in-out “ảo diệu”.

Điểm nổi bật của mẫu trái tim này chính là phần hiệu ứng những vệt sáng lấp lánh, lung linh được kết nối lại thành hình trái tim chuyển động độc đáo, mới lạ.

 

 

Ảnh: codingground

Dưới đây là các bước để làm code trái tim huyền bí mà bạn có thể tham khảo:

Chi tiết cách làm code trái tim huyền bí:

Bước 1: Sao chép nguồn code trái tim màu đỏ huyền bí sau đây:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<style>

canvas {

position: absolute;

left: 0;

top: 0;

width: 100%;

height: 100%;

background-color: rgba(0, 0, 0, .2);

}

</style>

</head>

<body>

 

<canvas id="heart"></canvas>

 

<script>

window.requestAnimationFrame =

window.__requestAnimationFrame ||

window.requestAnimationFrame ||

window.webkitRequestAnimationFrame ||

window.mozRequestAnimationFrame ||

window.oRequestAnimationFrame ||

window.msRequestAnimationFrame ||

(function () {

return function (callback, element) {

var lastTime = element.__lastTime;

if (lastTime === undefined) {

lastTime = 0;

}

var currTime = Date.now();

var timeToCall = Math.max(1, 33 - (currTime - lastTime));

window.setTimeout(callback, timeToCall);

element.__lastTime = currTime + timeToCall;

};

})();

window.isDevice = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(((navigator.userAgent || navigator.vendor || window.opera)).toLowerCase()));

var loaded = false;

var init = function () {

if (loaded) return;

loaded = true;

var mobile = window.isDevice;

var koef = mobile ? 0.5 : 1;

var canvas = document.getElementById('heart');

var ctx = canvas.getContext('2d');

var width = canvas.width = koef * innerWidth;

var height = canvas.height = koef * innerHeight;

var rand = Math.random;

ctx.fillStyle = "rgba(0,0,0,1)";

ctx.fillRect(0, 0, width, height);

 

var heartPosition = function (rad) {

//return [Math.sin(rad), Math.cos(rad)];

return [Math.pow(Math.sin(rad), 3), -(15 * Math.cos(rad) - 5 * Math.cos(2 * rad) - 2 * Math.cos(3 * rad) - Math.cos(4 * rad))];

};

var scaleAndTranslate = function (pos, sx, sy, dx, dy) {

return [dx + pos[0] * sx, dy + pos[1] * sy];

};

 

window.addEventListener('resize', function () {

width = canvas.width = koef * innerWidth;

height = canvas.height = koef * innerHeight;

ctx.fillStyle = "rgba(0,0,0,1)";

ctx.fillRect(0, 0, width, height);

});

 

var traceCount = mobile ? 20 : 50;

var pointsOrigin = [];

var i;

var dr = mobile ? 0.3 : 0.1;

for (i = 0; i < Math.PI * 2; i += dr) pointsOrigin.push(scaleAndTranslate(heartPosition(i), 210, 13, 0, 0));

for (i = 0; i < Math.PI * 2; i += dr) pointsOrigin.push(scaleAndTranslate(heartPosition(i), 150, 9, 0, 0));

for (i = 0; i < Math.PI * 2; i += dr) pointsOrigin.push(scaleAndTranslate(heartPosition(i), 90, 5, 0, 0));

var heartPointsCount = pointsOrigin.length;

 

var targetPoints = [];

var pulse = function (kx, ky) {

for (i = 0; i < pointsOrigin.length; i++) {

targetPoints[i] = [];

targetPoints[i][0] = kx * pointsOrigin[i][0] + width / 2;

targetPoints[i][1] = ky * pointsOrigin[i][1] + height / 2;

}

};

 

var e = [];

for (i = 0; i < heartPointsCount; i++) {

var x = rand() * width;

var y = rand() * height;

e[i] = {

vx: 0,

vy: 0,

R: 2,

speed: rand() + 5,

q: ~~(rand() * heartPointsCount),

D: 2 * (i % 2) - 1,

force: 0.2 * rand() + 0.7,

f: "hsla(0," + ~~(40 * rand() + 60) + "%," + ~~(60 * rand() + 20) + "%,.3)",

trace: []

};

for (var k = 0; k < traceCount; k++) e[i].trace[k] = { x: x, y: y };

}

 

var config = {

traceK: 0.4,

timeDelta: 0.01

};

 

var time = 0;

var loop = function () {

var n = -Math.cos(time);

pulse((1 + n) * .5, (1 + n) * .5);

time += ((Math.sin(time)) < 0 ? 9 : (n > 0.8) ? .2 : 1) * config.timeDelta;

ctx.fillStyle = "rgba(0,0,0,.1)";

ctx.fillRect(0, 0, width, height);

for (i = e.length; i--;) {

var u = e[i];

var q = targetPoints[u.q];

var dx = u.trace[0].x - q[0];

var dy = u.trace[0].y - q[1];

var length = Math.sqrt(dx * dx + dy * dy);

if (10 > length) {

if (0.95 < rand()) {

u.q = ~~(rand() * heartPointsCount);

}

else {

if (0.99 < rand()) {

u.D *= -1;

}

u.q += u.D;

u.q %= heartPointsCount;

if (0 > u.q) {

u.q += heartPointsCount;

}

}

}

u.vx += -dx / length * u.speed;

u.vy += -dy / length * u.speed;

u.trace[0].x += u.vx;

u.trace[0].y += u.vy;

u.vx *= u.force;

u.vy *= u.force;

for (k = 0; k < u.trace.length - 1;) {

var T = u.trace[k];

var N = u.trace[++k];

N.x -= config.traceK * (N.x - T.x);

N.y -= config.traceK * (N.y - T.y);

}

ctx.fillStyle = u.f;

for (k = 0; k < u.trace.length; k++) {

ctx.fillRect(u.trace[k].x, u.trace[k].y, 1, 1);

}

}

//ctx.fillStyle = "rgba(255,255,255,1)";

//for (i = u.trace.length; i--;) ctx.fillRect(targetPoints[i][0], targetPoints[i][1], 2, 2);

 

window.requestAnimationFrame(loop, canvas);

};

loop();

};

 

var s = document.readyState;

if (s === 'complete' || s === 'loaded' || s === 'interactive') init();

else document.addEventListener('DOMContentLoaded', init, false);

</script>

</body>

</html>

Bước 2: Truy cập vào liên kết https://www.tutorialspoint.com/online_html_editor.php

Kế đến, dán phần mã nguồn vừa sao chép vào khung “Source Code” phía bên trái. Cuối cùng, ở phía bên phải màn hình sẽ cho ra kết quả là một hình trái tim chuyển động màu đỏ vô cùng ấn tượng.

Ảnh: codingground

Cách 4: Làm code trái tim đập chèn chữ

Trong trường hợp bạn muốn chèn thêm những lời chúc Giáng sinh ý nghĩa hoặc những tâm tư, tình cảm ngọt ngào đến nửa kia, bạn cũng có thể sử dụng mẫu trái tim chèn chữ làm bằng code này.

Xét về phần hiệu ứng, hình trái tim này độc đáo hơn các mẫu code khác do phần khung trái tim có thể chuyển động phóng to và thu nhỏ theo nhịp đập của trái tim. Bên cạnh đó, phần nội dung mà người gửi muốn truyền tải sẽ được hiển thị ngay chính giữa khiến cho mẫu trái tim này trở nên đặc biệt hơn.

Ảnh: codingground

Để tạo ra hình trái tim đập có chèn chữ này, bạn có thể tham khảo các bước thực hiện cụ thể sau đây:

Chi tiết cách làm code trái tim đập chèn chữ:

Bước 1: Sao chép nguồn code trái tim có hiệu ứng chèn chữ sau đây:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE> Heart </TITLE>

<META NAME="Generator" CONTENT="EditPlus">

<META NAME="Author" CONTENT="">

<META NAME="Keywords" CONTENT="">

<META NAME="Description" CONTENT="">

 

 

<style>

html, body {

height: 100%;

padding: 0;

margin: 0;

background: #000;

display: flex;

justify-content: center;

align-items: center;

 

}

 

.box {

width: 100%;

position: absolute;

top: 50%;

left: 50%;

transform: translate(-50%, -50%);

display: flex;

flex-direction: column;

}

 

canvas {

position: absolute;

width: 100%;

height: 100%;

}

#pinkboard {

position: relative;

margin: auto;

height: 500px;

width: 500px;

animation: animate 1.3s infinite;

}

 

#pinkboard:before, #pinkboard:after {

content: '';

position: absolute;

background: #FF5CA4;

width: 100px;

height: 160px;

border-top-left-radius: 50px;

border-top-right-radius: 50px;

}

 

#pinkboard:before {

left: 100px;

transform: rotate(-45deg);

transform-origin: 0 100%;

box-shadow: 0 14px 28px rgba(0,0,0,0.25),

0 10px 10px rgba(0,0,0,0.22);

}

 

#pinkboard:after {

left: 0;

transform: rotate(45deg);

transform-origin: 100% 100%;

}

 

@keyframes animate {

0% {

transform: scale(1);

}

30% {

transform: scale(.8);

}

60% {

transform: scale(1.2);

}

100% {

transform: scale(1);

}

}

</style>

</HEAD>

 

<BODY>

<div class="box">

<canvas id="pinkboard"></canvas>

</div>

<script>

/*

* Settings

*/

var settings = {

particles: {

length: 2000, // maximum amount of particles

duration: 2, // particle duration in sec

velocity: 100, // particle velocity in pixels/sec

effect: -1.3, // play with this for a nice effect

size: 13, // particle size in pixels

},

};

/*

* RequestAnimationFrame polyfill by Erik Möller

*/

(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

/*

* Point class

*/

var Point = (function() {

function Point(x, y) {

this.x = (typeof x !== 'undefined') ? x : 0;

this.y = (typeof y !== 'undefined') ? y : 0;

}

Point.prototype.clone = function() {

return new Point(this.x, this.y);

};

Point.prototype.length = function(length) {

if (typeof length == 'undefined')

return Math.sqrt(this.x * this.x + this.y * this.y);

this.normalize();

this.x *= length;

this.y *= length;

return this;

};

Point.prototype.normalize = function() {

var length = this.length();

this.x /= length;

this.y /= length;

return this;

};

return Point;

})();

/*

* Particle class

*/

var Particle = (function() {

function Particle() {

this.position = new Point();

this.velocity = new Point();

this.acceleration = new Point();

this.age = 0;

}

Particle.prototype.initialize = function(x, y, dx, dy) {

this.position.x = x;

this.position.y = y;

this.velocity.x = dx;

this.velocity.y = dy;

this.acceleration.x = dx * settings.particles.effect;

this.acceleration.y = dy * settings.particles.effect;

this.age = 0;

};

Particle.prototype.update = function(deltaTime) {

this.position.x += this.velocity.x * deltaTime;

this.position.y += this.velocity.y * deltaTime;

this.velocity.x += this.acceleration.x * deltaTime;

this.velocity.y += this.acceleration.y * deltaTime;

this.age += deltaTime;

};

Particle.prototype.draw = function(context, image) {

function ease(t) {

return (--t) * t * t + 1;

}

var size = image.width * ease(this.age / settings.particles.duration);

context.globalAlpha = 1 - this.age / settings.particles.duration;

context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);

};

return Particle;

})();

/*

* ParticlePool class

*/

var ParticlePool = (function() {

var particles,

firstActive = 0,

firstFree = 0,

duration = settings.particles.duration;

 

function ParticlePool(length) {

// create and populate particle pool

particles = new Array(length);

for (var i = 0; i < particles.length; i++)

particles[i] = new Particle();

}

ParticlePool.prototype.add = function(x, y, dx, dy) {

particles[firstFree].initialize(x, y, dx, dy);

 

// handle circular queue

firstFree++;

if (firstFree == particles.length) firstFree = 0;

if (firstActive == firstFree ) firstActive++;

if (firstActive == particles.length) firstActive = 0;

};

ParticlePool.prototype.update = function(deltaTime) {

var i;

 

// update active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].update(deltaTime);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].update(deltaTime);

for (i = 0; i < firstFree; i++)

particles[i].update(deltaTime);

}

 

// remove inactive particles

while (particles[firstActive].age >= duration && firstActive != firstFree) {

firstActive++;

if (firstActive == particles.length) firstActive = 0;

}

 

 

};

ParticlePool.prototype.draw = function(context, image) {

// draw active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].draw(context, image);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].draw(context, image);

for (i = 0; i < firstFree; i++)

particles[i].draw(context, image);

}

};

return ParticlePool;

})();

/*

* Putting it all together

*/

(function(canvas) {

var context = canvas.getContext('2d'),

particles = new ParticlePool(settings.particles.length),

particleRate = settings.particles.length / settings.particles.duration, // particles/sec

time;

 

// get point on heart with -PI <= t <= PI

function pointOnHeart(t) {

return new Point(

160 * Math.pow(Math.sin(t), 3),

130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25

);

}

 

// creating the particle image using a dummy canvas

var image = (function() {

var canvas = document.createElement('canvas'),

context = canvas.getContext('2d');

canvas.width = settings.particles.size;

canvas.height = settings.particles.size;

// helper function to create the path

function to(t) {

var point = pointOnHeart(t);

point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;

point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;

return point;

}

// create the path

context.beginPath();

var t = -Math.PI;

var point = to(t);

context.moveTo(point.x, point.y);

while (t < Math.PI) {

t += 0.01; // baby steps!

point = to(t);

context.lineTo(point.x, point.y);

}

context.closePath();

// create the fill

context.fillStyle = '#FF5CA4';

context.fill();

// create the image

var image = new Image();

image.src = canvas.toDataURL();

return image;

})();

 

// render that thing!

function render() {

// next animation frame

requestAnimationFrame(render);

 

// update time

var newTime = new Date().getTime() / 1000,

deltaTime = newTime - (time || newTime);

time = newTime;

 

// clear canvas

context.clearRect(0, 0, canvas.width, canvas.height);

 

// create new particles

var amount = particleRate * deltaTime;

for (var i = 0; i < amount; i++) {

var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());

var dir = pos.clone().length(settings.particles.velocity);

particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);

}

 

// update and draw particles

particles.update(deltaTime);

particles.draw(context, image);

}

 

// handle (re-)sizing of the canvas

function onResize() {

canvas.width = canvas.clientWidth;

canvas.height = canvas.clientHeight;

}

window.onresize = onResize;

 

// delay rendering bootstrap

setTimeout(function() {

onResize();

render();

}, 10);

})(document.getElementById('pinkboard'));

</script>

<div class="center-text",

style="background-color:rgb(0, 0, 0);

width: 100%;

color: rgb(225, 12, 168);

height:100%;

font-size: 31px;

font-style: italic;

display: flex;

align-items: center;

justify-content: center;

margin-bottom: 5px;

text-align: center;">I Love You</div>

</BODY>

</HTML>

Bước 2: Truy cập vào đường link https://www.tutorialspoint.com/online_html_editor.php và dán mã nguồn vào khung “Source Code” nằm ở phía bên trái. Sau đó, thành quả hình trái tim sẽ được hiển thị ở khung phía bên phải màn hình.

Đặc biệt, bạn hoàn toàn có thể điều chỉnh nội dung tùy theo ý muốn bằng cách nhập phần nội dung thay thế vào đoạn code được in đậm phía trên.

Còn món quà Giáng sinh nào ý nghĩa hơn một trái tim chân thành chứa đựng những lời nhắn nhủ ngọt ngào từ người yêu. Cách làm code trái tim chèn chữ này chắc chắn sẽ khiến các nàng đắm chìm trong hạnh phúc khi nhìn thấy.

Ảnh: codingground

Cách 5: Làm code trái tim đập chèn hình ảnh

Bên cạnh các mã nguồn hình trái tim thông thường hoặc có thêm chữ bên trong, nguồn code trái tim có chèn hình ảnh này cũng là một sự lựa chọn ấn tượng mà bạn không nên bỏ qua.

Bằng cách chèn thêm hình ảnh của mình và nửa kia vào trái tim kết hợp với hiệu ứng chuyển động theo nhịp đập và các tia sáng lấp lánh xung quanh, mẫu code trái tim này sẽ giúp bạn tạo nên một “tác phẩm nghệ thuật” mang tính cá nhân và là một món quà Giáng sinh đặc biệt dành riêng cho người ấy.

Ảnh: didongviet.vn

Cùng tham khảo từng bước thực hiện code trái tim đập chèn hình ảnh chi tiết để có thể tự mình làm ra một trái tim “độc nhất vô nhị” dành tặng cho người yêu trong dịp Giáng sinh này.

Chi tiết cách làm code trái tim có chèn hình ảnh:

Bước 1: Truy cập vào đường link Google Drive này để tải file lập trình code trái tim đập có hình ảnh về máy:

https://drive.google.com/file/d/1sOWvnQvfElynPpPWoqrDXTyoKW4m1RB9/view?usp=sharing

Sau khi thư mục đã được tải xuống thì tiến hành giải nén file.

Ảnh: didongviet.vn

Bước 2: Di chuyển file hình ảnh cần chèn vào chung thư mục có chứa code trái tim để có thể điều chỉnh code và chèn ảnh vào phần mã nguồn.

Ảnh: didongviet.vn

Bước 3: Tiếp theo, click chọn chuột phải và chọn “Properties” để xem định dạng file ảnh là JPG hay PNG, sau đó sao chép tên file và loại file ảnh để chèn vào code.

Ảnh: didongviet.vn

Bước 4: Click chuột phải vào file index.html, chọn Notepad để mở file.

Bạn cũng có thể sử dụng công cụ đọc file HTML đã cài sẵn trên máy tính nếu có.

Ảnh: didongviet.vn

Bước 5: Trong mục EDIT Here, tiến hành điều chỉnh nội dung xuất hiện trong trái tim, cụ thể như sau:

- Tại dòng STARDUST1, bạn có thể thay đổi nội dung “2022” tùy theo ý thích.

- Tại dòng STARDUST2, hãy điền tên của mình cùng với nửa kia.

- Ở dòng STARDUST3, bạn có thể điều chỉnh dòng chữ “Love You” thành nội dung mà mình muốn truyền tải.

- Kế đến, ở phần img, điền vào tên và định dạng của hình ảnh mà bạn muốn chèn vào trái tim như hình bên dưới.

Ảnh: didongviet.vn

Bước 6: Nhấn vào File và chọn nút Save để lưu lại thành phẩm.

Để ngắm nhìn thành quả của mình, bạn chỉ cần click chọn và mở file HTML lên như bình thường.

Ảnh: didongviet.vn

Ảnh: didongviet.vn

Cách 6: Làm code trái tim thật có nhịp đập

Có thể thấy, đoạn code trái tim này có phần khác biệt, độc lạ nhất so với các mẫu trái tim làm bằng code khác.

Thay vì tạo thành phần khung trái tim hay một trái tim hoàn chỉnh, mẫu code này sẽ bao gồm các đường viền hình trái tim xếp nối tiếp nhau, kết hợp với hiệu ứng chuyển động nhịp nhàng, chân thật.

Nếu như bạn vẫn chưa tìm được món quà lý tưởng cho người yêu trong dịp Giáng sinh 2022, mẫu code trái tim có nhịp đập chân thật này sẽ là một sự lựa chọn không tồi dành cho bạn.

Ảnh: codingground

Để làm ra mẫu trái tim này, bạn sẽ không phải mất quá nhiều thời gian và công sức chỉnh sửa, mà chỉ cần thực hiện theo các bước như sau:

Chi tiết cách làm code trái tim chuyển động theo nhịp đập:

Bước 1: Sao chép nguồn code trái tim có hiệu ứng nhịp đập sau đây:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE> MINH IT </TITLE>

<META NAME="Generator" CONTENT="EditPlus">

<META NAME="Author" CONTENT="">

<META NAME="Keywords" CONTENT="">

<META NAME="Description" CONTENT="">

<link rel="stylesheet" href="style.css">

<style>

html, body {

height: 100%;

padding: 0;

margin: 0;

background: rgba(0, 0, 0, 0.851);

}

canvas {

position: absolute;

width: 100%;

height: 100%;

}

</style>

</HEAD>

<BODY>

<div class="box">

<canvas id="pinkboard"></canvas>

</div>

<script>

var settings = {

particles: {

length: 10000, // maximum amount of particles

duration: 4, // particle duration in sec

velocity: 80, // particle velocity in pixels/sec

effect: -1.3, // play with this for a nice effect

size: 8, // particle size in pixels

},

};

/*

*/

(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

/*

* Point class

*/

var Point = (function() {

function Point(x, y) {

this.x = (typeof x !== 'undefined') ? x : 0;

this.y = (typeof y !== 'undefined') ? y : 0;

}

Point.prototype.clone = function() {

return new Point(this.x, this.y);

};

Point.prototype.length = function(length) {

if (typeof length == 'undefined')

return Math.sqrt(this.x * this.x + this.y * this.y);

this.normalize();

this.x *= length;

this.y *= length;

return this;

};

Point.prototype.normalize = function() {

var length = this.length();

this.x /= length;

this.y /= length;

return this;

};

return Point;

})();

/*

* Particle class

*/

var Particle = (function() {

function Particle() {

this.position = new Point();

this.velocity = new Point();

this.acceleration = new Point();

this.age = 0;

}

Particle.prototype.initialize = function(x, y, dx, dy) {

this.position.x = x;

this.position.y = y;

this.velocity.x = dx;

this.velocity.y = dy;

this.acceleration.x = dx * settings.particles.effect;

this.acceleration.y = dy * settings.particles.effect;

this.age = 0;

};

Particle.prototype.update = function(deltaTime) {

this.position.x += this.velocity.x * deltaTime;

this.position.y += this.velocity.y * deltaTime;

this.velocity.x += this.acceleration.x * deltaTime;

this.velocity.y += this.acceleration.y * deltaTime;

this.age += deltaTime;

};

Particle.prototype.draw = function(context, image) {

function ease(t) {

return (--t) * t * t + 1;

}

var size = image.width * ease(this.age / settings.particles.duration);

context.globalAlpha = 1 - this.age / settings.particles.duration;

context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);

};

return Particle;

})();

/*

* ParticlePool class

*/

var ParticlePool = (function() {

var particles,

firstActive = 0,

firstFree = 0,

duration = settings.particles.duration;

 

function ParticlePool(length) {

// create and populate particle pool

particles = new Array(length);

for (var i = 0; i < particles.length; i++)

particles[i] = new Particle();

}

ParticlePool.prototype.add = function(x, y, dx, dy) {

particles[firstFree].initialize(x, y, dx, dy);

 

// handle circular queue

firstFree++;

if (firstFree == particles.length) firstFree = 0;

if (firstActive == firstFree ) firstActive++;

if (firstActive == particles.length) firstActive = 0;

};

ParticlePool.prototype.update = function(deltaTime) {

var i;

 

// update active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].update(deltaTime);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].update(deltaTime);

for (i = 0; i < firstFree; i++)

particles[i].update(deltaTime);

}

 

// remove inactive particles

while (particles[firstActive].age >= duration && firstActive != firstFree) {

firstActive++;

if (firstActive == particles.length) firstActive = 0;

}

 

 

};

ParticlePool.prototype.draw = function(context, image) {

// draw active particles

if (firstActive < firstFree) {

for (i = firstActive; i < firstFree; i++)

particles[i].draw(context, image);

}

if (firstFree < firstActive) {

for (i = firstActive; i < particles.length; i++)

particles[i].draw(context, image);

for (i = 0; i < firstFree; i++)

particles[i].draw(context, image);

}

};

return ParticlePool;

})();

/*

* Putting it all together

*/

(function(canvas) {

var context = canvas.getContext('2d'),

particles = new ParticlePool(settings.particles.length),

particleRate = settings.particles.length / settings.particles.duration, // particles/sec

time;

 

// get point on heart with -PI <= t <= PI

function pointOnHeart(t) {

return new Point(

160 * Math.pow(Math.sin(t), 3),

130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25

);

}

 

// creating the particle image using a dummy canvas

var image = (function() {

var canvas = document.createElement('canvas'),

context = canvas.getContext('2d');

canvas.width = settings.particles.size;

canvas.height = settings.particles.size;

// helper function to create the path

function to(t) {

var point = pointOnHeart(t);

point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;

point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;

return point;

}

// create the path

context.beginPath();

var t = -Math.PI;

var point = to(t);

context.moveTo(point.x, point.y);

while (t < Math.PI) {

t += 0.01; // baby steps!

point = to(t);

context.lineTo(point.x, point.y);

}

context.closePath();

// create the fill

context.fillStyle = '#f50b02';

context.fill();

// create the image

var image = new Image();

image.src = canvas.toDataURL();

return image;

})();

 

// render that thing!

function render() {

// next animation frame

requestAnimationFrame(render);

 

// update time

var newTime = new Date().getTime() / 1000,

deltaTime = newTime - (time || newTime);

time = newTime;

 

// clear canvas

context.clearRect(0, 0, canvas.width, canvas.height);

 

// create new particles

var amount = particleRate * deltaTime;

for (var i = 0; i < amount; i++) {

var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());

var dir = pos.clone().length(settings.particles.velocity);

particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);

}

 

// update and draw particles

particles.update(deltaTime);

particles.draw(context, image);

}

 

// handle (re-)sizing of the canvas

function onResize() {

canvas.width = canvas.clientWidth;

canvas.height = canvas.clientHeight;

}

window.onresize = onResize;

 

// delay rendering bootstrap

setTimeout(function() {

onResize();

render();

}, 10);

})(document.getElementById('pinkboard'));

</script>

</BODY>

</HTML>

 

Bước 2: Truy cập vào đường link https://www.tutorialspoint.com/online_html_editor.php

Sau đó dán mã nguồn vào khung “Source Code” phía bên trái. Mẫu hình trái tim này sẽ được hiển thị trong khung kết quả phía bên phải màn hình.

Ảnh: codingground

Cách 7: Làm code trái tim kim cương có hiệu ứng màu sắc rực rỡ

Đối với những người yêu thích sự sáng tạo và mới lạ, chắc chắn mẫu code trái tim kim cương rực rỡ sắc màu này sẽ là một sự lựa chọn thú vị mang đến cho bạn và nửa kia một kỉ niệm đáng nhớ trong mùa Giáng sinh này.

Có thể thấy, mẫu trái tim này hoàn toàn khác biệt từ thiết kế đến hiệu ứng. Điểm nhấn đặc biệt nhất chính là hình trái tim kim cương 3D chuyển động xoay vòng ở chính giữa và phần viền trái tim được tạo thành từ những đốm sáng lung linh, huyền ảo xung quanh.

Ngoài ra, phần phông nền cũng được thiết kế thêm các trái tim nhỏ nhỏ xinh xinh với nhiều màu sắc khác nhau khiến cho hình trái tim làm bằng code này thêm phần ấn tượng, độc đáo.

Ảnh: codingground

Dưới đây là cách tạo ra hình trái tim kim cương lung linh sắc màu từ code HTML mà bạn có thể tham khảo để dành tặng cho cô gái của mình trong mùa lễ Noel năm nay:

Chi tiết cách làm code trái tim kim cương có hiệu ứng màu sắc rực rỡ:

Bước 1: Sao chép nguồn code trái tim kim cương nhiều màu sắc sau đây:

<!DOCTYPE html>

<html lang="en"><head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>I Love You</title>

<style>

*{

margin: 0;

padding: 0;

box-sizing: border-box;

}

 

html,

body {

overflow: hidden;

background-color: #000 !important;

}

 

body {

-webkit-font-soothing: antialiased;

}

 

.webgl {

position: fixed;

width: 100vw;

height: 100vw;

top: 0;

left: 0;

outline: none;

}

 

h1{

position: absolute;

top: 10vh;

left: 2.5rem;

right: 1rem;

text-align: center;

font-size: max(1rem, 3vh);

}

 

button {

position: absolute;

left: 0;

top: 0;

bottom: 0;

height: 12vh;

width: 12vh;

transform: translateY(2vh);

right: 0;

margin: auto;

-webkit-appearance: none;

background: transparent;

color: inherit;

border: none;

cursor: pointer;

}

 

svg{

width: 3.5vh;

}

</style>

 

<script>

window.console = window.console || function(t) {};

</script>

 

 

 

<script>

if (document.location.search.match(/type=embed/gi)) {

window.parent.postMessage("resize", "*");

}

</script>

 

 

</head>

 

<body translate="no">

 

 

<canvas class="webgl" data-engine="three.js r135" width="682" height="157" style="width: 682px; height: 157px;"></canvas>

 

<button id="play-music" type="button" aria-label="Play music" style="opacity: 1;"><svg fill="currentColor" viewBox="0 0 512 512" width="100" title="music">

<!-- <path d="M470.38 1.51L150.41 96A32 32 0 0 0 128 126.51v261.41A139 139 0 0 0 96 384c-53 0-96 28.66-96 64s43 64 96 64 96-28.66 96-64V214.32l256-75v184.61a138.4 138.4 0 0 0-32-3.93c-53 0-96 28.66-96 64s43 64 96 64 96-28.65 96-64V32a32 32 0 0 0-41.62-30.49z" /> -->

</svg></button>

<script type="x-shader/x-vertex" id="vertexShader">

#define M_PI 3.1415926535897932384626433832795

uniform float uTime;

uniform float uSize;

attribute float aScale;

attribute vec3 aColor;

attribute float random;

attribute float random1;

attribute float aSpeed;

varying vec3 vColor;

varying vec2 vUv;

 

void main() {

float sign = 2.0* (step(random, 0.5) -.5);

float t = sign*mod(-uTime * aSpeed* 0.005 + 10.0*aSpeed*aSpeed, M_PI);

float a = pow(t, 2.0) * pow((t - sign * M_PI), 2.0);

float radius = 0.14;

vec3 myOffset =

vec3(t, 1.0, 0.0);

myOffset = vec3(radius *16.0 * pow(sin(t), 2.0) * sin(t), radius * (13.0 * cos(t) - 5.0 * cos(2.0 * t) - 2.0 * cos(3.0 * t) - cos(4.0 * t)), .15*(a*(random1 - .5))*sin(abs(10.0*(sin(.2*uTime + .2*random)))*t));

vec3 displacedPosition = myOffset;

vec4 modelPosition = modelMatrix * vec4(displacedPosition.xyz, 1.0);

 

vec4 viewPosition = viewMatrix * modelPosition;

viewPosition.xyz += position * aScale * uSize * pow(a, .5) * .5;

gl_Position = projectionMatrix * viewPosition;

 

vColor = aColor;

vUv = uv;

}

</script>

 

<script type="x-shader/x-fragment" id="fragmentShader">

varying vec3 vColor;

varying vec2 vUv;

 

void main() {

vec2 uv = vUv;

vec3 color = vColor;

float strength = distance(uv, vec2(0.5));

strength *= 2.0;

strength = 1.0 - strength;

gl_FragColor = vec4(strength * color, 1.0);

}

</script>

<script type="x-shader/x-vertex" id="vertexShader1">

#define M_PI 3.1415926535897932384626433832795

 

 

uniform float uTime;

uniform float uSize;

attribute float aScale;

attribute vec3 aColor;

attribute float phi;

attribute float random;

attribute float random1;

varying vec3 vColor;

varying vec2 vUv;

 

void main() {

float t = 0.01 * uTime + 12.0;

float angle = phi;

 

t = mod((-uTime + 100.0) * 0.06* random1 + random *2.0 * M_PI , 2.0 * M_PI);

vec3 myOffset = vec3(5.85*cos(angle * (t )), 2.0*(t - M_PI), 3.0*sin(angle * (t )/t));

vec4 modelPosition = modelMatrix * vec4(myOffset, 1.0);

vec4 viewPosition = viewMatrix * modelPosition;

viewPosition.xyz += position * aScale * uSize;

gl_Position = projectionMatrix * viewPosition;

 

vColor = aColor;

vUv = uv;

}

</script>

 

<script type="x-shader/x-fragment" id="fragmentShader1">

uniform sampler2D uTex;

varying vec3 vColor;

varying vec2 vUv;

 

void main() {

vec2 uv = vUv;

vec3 color = vColor;

float strength = distance(uv, vec2(0.5, .65));

strength *= 2.0;

strength = 1.0 - strength;

vec3 texture = texture2D(uTex, uv).rgb;

gl_FragColor = vec4(texture * color * (strength + .3), 1.);

}

</script>

 

<script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-2c7831bb44f98c1391d6a4ffda0e1fd302503391ca806e7fcc7b9b87197aec26.js"></script>

 

 

<script id="rendered-js" type="module">

/* Poly Heart model by Quaternius [CC0] (https://creativecommons.org/publicdomain/zero/1.0/) via Poly Pizza (https://poly.pizza/m/1yCRUwFnwX)

*/

 

import * as THREE from "https://cdn.skypack.dev/three@0.135.0";

import { gsap } from "https://cdn.skypack.dev/gsap@3.8.0";

import { GLTFLoader } from "https://cdn.skypack.dev/three@0.135.0/examples/jsm/loaders/GLTFLoader";

class World {

constructor({

canvas,

width,

height,

cameraPosition,

fieldOfView = 75,

nearPlane = 0.1,

farPlane = 100 })

{

this.parameters = {

count: 1500,

max: 12.5 * Math.PI,

a: 2,

c: 4.5 };

 

this.textureLoader = new THREE.TextureLoader();

this.scene = new THREE.Scene();

this.scene.background = new THREE.Color(0x16000a);

this.clock = new THREE.Clock();

this.data = 0;

this.time = { current: 0, t0: 0, t1: 0, t: 0, frequency: 0.0005 };

this.angle = { x: 0, z: 0 };

this.width = width || window.innerWidth;

this.height = height || window.innerHeight;

this.aspectRatio = this.width / this.height;

this.fieldOfView = fieldOfView;

this.camera = new THREE.PerspectiveCamera(

fieldOfView,

this.aspectRatio,

nearPlane,

farPlane);

 

this.camera.position.set(

cameraPosition.x,

cameraPosition.y,

cameraPosition.z);

 

this.scene.add(this.camera);

this.renderer = new THREE.WebGLRenderer({

canvas,

antialias: true });

 

this.pixelRatio = Math.min(window.devicePixelRatio, 2);

this.renderer.setPixelRatio(this.pixelRatio);

this.renderer.setSize(this.width, this.height);

this.timer = 0;

this.addToScene();

this.addButton();

 

this.render();

this.listenToResize();

this.listenToMouseMove();

}

start() {}

render() {

this.renderer.render(this.scene, this.camera);

this.composer && this.composer.render();

}

loop() {

this.time.elapsed = this.clock.getElapsedTime();

this.time.delta = Math.min(

60,

(this.time.current - this.time.elapsed) * 1000);

 

if (this.analyser && this.isRunning) {

this.time.t = this.time.elapsed - this.time.t0 + this.time.t1;

this.data = this.analyser.getAverageFrequency();

this.data *= this.data / 2000;

this.angle.x += this.time.delta * 0.001 * 0.63;

this.angle.z += this.time.delta * 0.001 * 0.39;

const justFinished = this.isRunning && !this.sound.isPlaying;

if (justFinished) {

this.time.t1 = this.time.t;

this.audioBtn.disabled = false;

this.isRunning = false;

const tl = gsap.timeline();

this.angle.x = 0;

this.angle.z = 0;

tl.to(this.camera.position, {

x: 0,

z: 4.5,

duration: 4,

ease: "expo.in" });

 

tl.to(this.audioBtn, {

opacity: () => 1,

duration: 1,

ease: "power1.out" });

 

} else {

this.camera.position.x = Math.sin(this.angle.x) * this.parameters.a;

this.camera.position.z = Math.min(

Math.max(Math.cos(this.angle.z) * this.parameters.c, 1.75),

6.5);

 

}

}

this.camera.lookAt(this.scene.position);

if (this.heartMaterial) {

this.heartMaterial.uniforms.uTime.value +=

this.time.delta * this.time.frequency * (1 + this.data * 0.2);

}

if (this.model) {

this.model.rotation.y -= 0.0005 * this.time.delta * (1 + this.data);

}

if (this.snowMaterial) {

this.snowMaterial.uniforms.uTime.value +=

this.time.delta * 0.0004 * (1 + this.data);

}

this.render();

 

this.time.current = this.time.elapsed;

requestAnimationFrame(this.loop.bind(this));

}

listenToResize() {

window.addEventListener("resize", () => {

// Update sizes

this.width = window.innerWidth;

this.height = window.innerHeight;

 

// Update camera

this.camera.aspect = this.width / this.height;

this.camera.updateProjectionMatrix();

this.renderer.setSize(this.width, this.height);

});

}

listenToMouseMove() {

window.addEventListener("mousemove", e => {

const x = e.clientX;

const y = e.clientY;

gsap.to(this.camera.position, {

x: gsap.utils.mapRange(0, window.innerWidth, 0.2, -0.2, x),

y: gsap.utils.mapRange(0, window.innerHeight, 0.2, -0.2, -y) });

 

});

}

addHeart() {

this.heartMaterial = new THREE.ShaderMaterial({

fragmentShader: document.getElementById("fragmentShader").textContent,

vertexShader: document.getElementById("vertexShader").textContent,

uniforms: {

uTime: { value: 0 },

uSize: { value: 0.2 },

uTex: {

value: new THREE.TextureLoader().load(

"https://assets.codepen.io/74321/heart.png") } },

 

 

 

depthWrite: false,

blending: THREE.AdditiveBlending,

transparent: true });

 

const count = this.parameters.count; //2000

const scales = new Float32Array(count * 1);

const colors = new Float32Array(count * 3);

const speeds = new Float32Array(count);

const randoms = new Float32Array(count);

const randoms1 = new Float32Array(count);

const colorChoices = [

"white",

"red",

"pink",

"crimson",

"hotpink",

"green",

"aquamarine",

"blue"];

 

 

const squareGeometry = new THREE.PlaneGeometry(1, 1);

this.instancedGeometry = new THREE.InstancedBufferGeometry();

Object.keys(squareGeometry.attributes).forEach(attr => {

this.instancedGeometry.attributes[attr] = squareGeometry.attributes[attr];

});

this.instancedGeometry.index = squareGeometry.index;

this.instancedGeometry.maxInstancedCount = count;

 

for (let i = 0; i < count; i++) {

const phi = Math.random() * Math.PI * 2;

const i3 = 3 * i;

randoms[i] = Math.random();

randoms1[i] = Math.random();

scales[i] = Math.random() * 0.35;

const colorIndex = Math.floor(Math.random() * colorChoices.length);

const color = new THREE.Color(colorChoices[colorIndex]);

colors[i3 + 0] = color.r;

colors[i3 + 1] = color.g;

colors[i3 + 2] = color.b;

speeds[i] = Math.random() * this.parameters.max;

}

this.instancedGeometry.setAttribute(

"random",

new THREE.InstancedBufferAttribute(randoms, 1, false));

 

this.instancedGeometry.setAttribute(

"random1",

new THREE.InstancedBufferAttribute(randoms1, 1, false));

 

this.instancedGeometry.setAttribute(

"aScale",

new THREE.InstancedBufferAttribute(scales, 1, false));

 

this.instancedGeometry.setAttribute(

"aSpeed",

new THREE.InstancedBufferAttribute(speeds, 1, false));

 

this.instancedGeometry.setAttribute(

"aColor",

new THREE.InstancedBufferAttribute(colors, 3, false));

 

this.heart = new THREE.Mesh(this.instancedGeometry, this.heartMaterial);

console.log(this.heart);

this.scene.add(this.heart);

}

addToScene() {

this.addModel();

this.addHeart();

this.addSnow();

}

async addModel() {

this.model = await this.loadObj(

"https://assets.codepen.io/74321/heart.glb");

 

this.model.scale.set(0.01, 0.01, 0.01);

this.model.material = new THREE.MeshMatcapMaterial({

matcap: this.textureLoader.load(

"https://assets.codepen.io/74321/3.png",

() => {

gsap.to(this.model.scale, {

x: 0.35,

y: 0.35,

z: 0.35,

duration: 1.5,

ease: "Elastic.easeOut" });

 

}),

 

color: "#fff" });

 

this.scene.add(this.model);

}

addButton() {

this.audioBtn = document.querySelector("button");

this.audioBtn.addEventListener("click", () => {

this.audioBtn.disabled = true;

if (this.analyser) {

this.sound.play();

this.time.t0 = this.time.elapsed;

this.data = 0;

this.isRunning = true;

gsap.to(this.audioBtn, {

opacity: 0,

duration: 1,

ease: "power1.out" });

 

} else {

this.loadMusic().then(() => {

console.log("music loaded");

});

}

});

}

loadObj(path) {

const loader = new GLTFLoader();

return new Promise(resolve => {

loader.load(

path,

response => {

resolve(response.scene.children[0]);

},

xhr => {},

err => {

console.log(err);

});

 

});

}

loadMusic() {

return new Promise(resolve => {

const listener = new THREE.AudioListener();

this.camera.add(listener);

// create a global audio source

this.sound = new THREE.Audio(listener);

const audioLoader = new THREE.AudioLoader();

audioLoader.load(

"https://res.cloudinary.com/dmnxeusyw/video/upload/v1668310333/sharecs.net/music_ji3iak.mp3",

buffer => {

this.sound.setBuffer(buffer);

this.sound.setLoop(false);

this.sound.setVolume(0.5);

this.sound.play();

this.analyser = new THREE.AudioAnalyser(this.sound, 32);

// get the average frequency of the sound

const data = this.analyser.getAverageFrequency();

this.isRunning = true;

this.t0 = this.time.elapsed;

resolve(data);

},

progress => {

gsap.to(this.audioBtn, {

opacity: () => 1 - progress.loaded / progress.total,

duration: 1,

ease: "power1.out" });

 

},

 

error => {

console.log(error);

});

 

});

}

addSnow() {

this.snowMaterial = new THREE.ShaderMaterial({

fragmentShader: document.getElementById("fragmentShader1").textContent,

vertexShader: document.getElementById("vertexShader1").textContent,

uniforms: {

uTime: { value: 0 },

uSize: { value: 0.3 },

uTex: {

value: new THREE.TextureLoader().load(

"https://assets.codepen.io/74321/heart.png") } },

 

 

 

depthWrite: false,

blending: THREE.AdditiveBlending,

transparent: true });

 

const count = 550;

const scales = new Float32Array(count * 1);

const colors = new Float32Array(count * 3);

const phis = new Float32Array(count);

const randoms = new Float32Array(count);

const randoms1 = new Float32Array(count);

const colorChoices = ["red", "pink", "hotpink", "green", "aquamarine", "blue"];

 

const squareGeometry = new THREE.PlaneGeometry(1, 1);

this.instancedGeometry = new THREE.InstancedBufferGeometry();

Object.keys(squareGeometry.attributes).forEach(attr => {

this.instancedGeometry.attributes[attr] = squareGeometry.attributes[attr];

});

this.instancedGeometry.index = squareGeometry.index;

this.instancedGeometry.maxInstancedCount = count;

 

for (let i = 0; i < count; i++) {

const phi = (Math.random() - 0.5) * 10;

const i3 = 3 * i;

phis[i] = phi;

randoms[i] = Math.random();

randoms1[i] = Math.random();

scales[i] = Math.random() * 0.35;

const colorIndex = Math.floor(Math.random() * colorChoices.length);

const color = new THREE.Color(colorChoices[colorIndex]);

colors[i3 + 0] = color.r;

colors[i3 + 1] = color.g;

colors[i3 + 2] = color.b;

}

this.instancedGeometry.setAttribute(

"phi",

new THREE.InstancedBufferAttribute(phis, 1, false));

 

this.instancedGeometry.setAttribute(

"random",

new THREE.InstancedBufferAttribute(randoms, 1, false));

 

this.instancedGeometry.setAttribute(

"random1",

new THREE.InstancedBufferAttribute(randoms1, 1, false));

 

this.instancedGeometry.setAttribute(

"aScale",

new THREE.InstancedBufferAttribute(scales, 1, false));

 

this.instancedGeometry.setAttribute(

"aColor",

new THREE.InstancedBufferAttribute(colors, 3, false));

 

this.snow = new THREE.Mesh(this.instancedGeometry, this.snowMaterial);

this.scene.add(this.snow);

}}

 

 

const world = new World({

canvas: document.querySelector("canvas.webgl"),

cameraPosition: { x: 0, y: 0, z: 4.5 } });

 

 

world.loop();

//# sourceURL=pen.js

</script>

</body>

</html>

 

Bước 2: Truy cập vào đường link https://www.tutorialspoint.com/online_html_editor.php

Tiếp đến, dán mã nguồn vào khung “Source Code” phía bên trái để thu được thành quả xinh lung linh ở khung kết quả hiển thị phía bên phải màn hình.

Ảnh: codingground

chọn
'Quy hoạch NOXH ở những khu vực quá xa trung tâm như Củ Chi là không khả thi'
Theo đại diện Ban Quản lý các Khu chế xuất và công nghiệp TP HCM, so với các dự án nhà ở thông thường, việc xây dựng NOXH phức tạp hơn. Chẳng hạn như việc chọn địa điểm xây dựng, nếu NOXH được quy hoạch ở những khu vực quá xa trung tâm như Củ Chi thì sẽ không khả thi do di chuyển hàng ngày bất tiện.