const lerp = (a, b, t) => a * (1 - t) + b * t;
// from: https://easings.net
const easeOutQuad = (x) => 1 - (1 - x) * (1 - x);
function tween(from, to, duration, onUpdate, easeFn) {
let rafId = null;
let begin;
const loop = (now) => {
begin ??= now;
const progress = Math.min(1, (now - begin) / duration);
const ease = easeFn ? easeFn(progress) : progress;
const val = lerp(from, to, ease);
onUpdate(val);
if (progress === 1) {
rafId = null;
return;
}
rafId = requestAnimationFrame(loop);
};
rafId = requestAnimationFrame(loop);
return () => rafId ?? cancelAnimationFrame(rafId);
}
const progressBar = document.querySelector(".progressbar");
const progressBarValue = document.querySelector(".progressbar__value");
const progressBarStartValue = 0;
const progressBarEndValue = 100;
const progressBarStep = 10;
const animationDuration = 1000;
let progressBarCurrentValue = progressBarStartValue;
let killTween = null;
function onUpdate(val) {
progressBarValue.textContent = `${val.toFixed(1)}%`;
progressBar.style.background = `conic-gradient(#FFF ${val * 3.6}deg, #262623 ${val * 3.6}deg)`;
if (val === progressBarEndValue) {
alert("you have completed all the tasks");
}
}
document.body.addEventListener("click", (e) => {
if (progressBarCurrentValue === progressBarEndValue) {
alert("you have completed all the tasks");
} else {
const fromValue = progressBarCurrentValue;
progressBarCurrentValue = Math.min(
progressBarEndValue,
progressBarCurrentValue + progressBarStep
);
killTween?.();
killTween = tween(
fromValue,
progressBarCurrentValue,
animationDuration,
onUpdate,
easeOutQuad
);
}
});
const container = document.querySelector('.container');
const line = document.querySelector('.invisibility');
const marginBottom = line.getBoundingClientRect().top - container.getBoundingClientRect().bottom;
const options = {
root: document.querySelector('.container'),
rootMargin: `0px 0px ${marginBottom}px 0px`,
threshold: 0
}
const callback = function(entries, observer) {
entries.forEach((entry) => {
entry.target.style.background = entry.isIntersecting ? 'green' : 'red';
});
};
const observer = new IntersectionObserver(callback, options);
container.querySelectorAll('.item').forEach(item => {
observer.observe(item);
});
- var searchSite = /((https:\/\/[a-z0-9]+\.[a-z-.]+)|(^[a-z0-9.-]+\.[a-z]+))/gi;
+ var searchSite = /((https:\/\/[a-z0-9]+\.[a-z-.]+)|([a-z0-9.-]+\.[a-z]+))/gi;
const obj = {
_sayHi() {
console.log(`Hello, my name is ${this.name}!`);
}
};
class Person {
constructor(name, age, methods) {
this.name = name;
this.age = age;
this.methods = methods;
if (this.age < 0) {
this.age = 0;
}
}
sayMyName() {
this.methods._sayHi.call(this);
}
}
new Person('Heisenberg', 52, obj);
const saveImage = () => {
const image = document.querySelector("img");
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 300;
canvas.height = 200;
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.strokeRect(0, 0, canvas.width, canvas.height);
document.body.appendChild(canvas);
};
saveImage();
const saveImage = () => {
const image = document.querySelector("img");
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 300;
canvas.height = 200;
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.drawImage(
image,
-canvas.width / 2,
-canvas.height / 2,
canvas.width,
canvas.height
);
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.strokeRect(
-canvas.width / 2,
-canvas.height / 2,
canvas.width,
canvas.height
);
document.body.appendChild(canvas);
};
saveImage();
.clouds:nth-child(2) {
--scale: 2;
top: 180px;
left: 28px;
z-index: 2;
}
.cloud {
animation: scale 3s infinite alternate;
}
@keyframes scale {
from {
transform: scale(var(--scale));
}
to {
transform: scale(calc(var(--scale) / 2));
}
}
а если они касаются друг друга, они приобретают цвет другого элемента
- return aDist < bDist;
+ return aDist - bDist;
aDist < bDist
всегда будет либо true, либо false, что в данном контексте будет трактоваться как 1 и 0, т.е. aDist всегда больше или равен bDist и никогда не меньше него. Из-за разных используемых алгоритмов сортировки, разные движки сходят с ума по разному.