ыыыыы
Ля-ля-ля Новое
Сообщений 1 страница 3 из 3
Поделиться22025-10-26 03:10:17
[html]<div id="watch">
<div class="frame-face"></div>
<ul class="minute-marks">
<!-- li элементы для минутных меток остаются по 48 штук, как в оригинале -->
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="digits">
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>
<li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li>
</ul>
<div class="hours-hand"></div>
<div class="minutes-hand"></div>
<div class="seconds-hand"></div>
</div>
<style>
body { font-size:62.5%; margin:1em; background:#232425 }
ul { list-style:none; margin:0; padding:0 }
#watch { font-size:1em; position:relative }
#watch .frame-face {
position:relative;
width:30em;
height:30em;
margin:2em auto;
border-radius:15em;
background:-webkit-linear-gradient(top, #f9f9f9,#666);
background:-moz-linear-gradient(top, #f9f9f9,#666);
background:linear-gradient(to bottom, #f9f9f9,#666);
box-shadow:rgba(0,0,0,.8) .5em .5em 4em;
}
#watch .frame-face:before {
content:'';
width:29.4em;
height:29.4em;
border-radius:14.7em;
position:absolute;
top:.3em; left:.3em;
background:
-webkit-linear-gradient(135deg, rgba(246,248,249,0) 0%,rgba(229,235,238,1) 50%,rgba(205,212,217,1) 51%,rgba(245,247,249,0) 100%),
-webkit-radial-gradient(center, ellipse cover, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 65%,rgba(205,212,217,1) 66%,rgba(245,247,249,1) 100%);
background:
-moz-linear-gradient(135deg, rgba(246,248,249,0) 0%,rgba(229,235,238,1) 50%,rgba(205,212,217,1) 51%,rgba(245,247,249,0) 100%),
-moz-radial-gradient(center, ellipse cover, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 65%,rgba(205,212,217,1) 66%,rgba(245,247,249,1) 100%);
background:
linear-gradient(135deg, rgba(246,248,249,0) 0%,rgba(229,235,238,1) 50%,rgba(205,212,217,1) 51%,rgba(245,247,249,0) 100%),
radial-gradient(ellipse at center, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 65%,rgba(205,212,217,1) 66%,rgba(245,247,249,1) 100%);
}
#watch .frame-face:after {
content:'';
width:28em;
height:28em;
border-radius:14.2em;
position:absolute;
top:.9em; left:.9em;
box-shadow:inset rgba(0,0,0,.2) .2em .2em 1em;
border:.1em solid rgba(0,0,0,.2);
background:-webkit-linear-gradient(top, #fff, #ccc);
background:-moz-linear-gradient(top, #fff, #ccc);
background:linear-gradient(to bottom, #fff, #ccc);
}
#watch .minute-marks li {
display:block;
width:.2em;
height:.6em;
background:#929394;
position:absolute;
top:50%; left:50%;
margin:-.4em 0 0 -.1em;
}
/* Остальные стили для минутных меток остаются без изменений */
#watch .minute-marks li:first-child {transform:rotate(6deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(2) {transform:rotate(12deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(3) {transform:rotate(18deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(4) {transform:rotate(24deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(5) {transform:rotate(36deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(6) {transform:rotate(42deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(7) {transform:rotate(48deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(8) {transform:rotate(54deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(9) {transform:rotate(66deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(10) {transform:rotate(72deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(11) {transform:rotate(78deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(12) {transform:rotate(84deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(13) {transform:rotate(96deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(14) {transform:rotate(102deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(15) {transform:rotate(108deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(16) {transform:rotate(114deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(17) {transform:rotate(126deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(18) {transform:rotate(132deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(19) {transform:rotate(138deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(20) {transform:rotate(144deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(21) {transform:rotate(156deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(22) {transform:rotate(162deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(23) {transform:rotate(168deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(24) {transform:rotate(174deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(25) {transform:rotate(186deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(26) {transform:rotate(192deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(27) {transform:rotate(198deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(28) {transform:rotate(204deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(29) {transform:rotate(216deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(30) {transform:rotate(222deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(31) {transform:rotate(228deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(32) {transform:rotate(234deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(33) {transform:rotate(246deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(34) {transform:rotate(252deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(35) {transform:rotate(258deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(36) {transform:rotate(264deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(37) {transform:rotate(276deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(38) {transform:rotate(282deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(39) {transform:rotate(288deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(40) {transform:rotate(294deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(41) {transform:rotate(306deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(42) {transform:rotate(312deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(43) {transform:rotate(318deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(44) {transform:rotate(324deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(45) {transform:rotate(336deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(46) {transform:rotate(342deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(47) {transform:rotate(348deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(48) {transform:rotate(354deg) translateY(-12.7em)}
#watch .digits {
width:30em;
height:30em;
border-radius:15em;
position:absolute;
top:0; left:50%;
margin-left:-15em;
}
#watch .digits li {
font-size:1.6em;
display:block;
width:1.6em;
height:1.6em;
position:absolute;
top:50%; left:50%;
line-height:1.6em;
text-align:center;
margin:-.8em 0 0 -.8em;
font-weight:bold;
}
#watch .digits li:nth-child(1) { transform:translate(3.9em, -6.9em) }
#watch .digits li:nth-child(2) { transform:translate(6.9em, -4em) }
#watch .digits li:nth-child(3) { transform:translate(8em, 0) }
#watch .digits li:nth-child(4) { transform:translate(6.8em, 4em) }
#watch .digits li:nth-child(5) { transform:translate(3.9em, 6.9em) }
#watch .digits li:nth-child(6) { transform:translate(0, 8em) }
#watch .digits li:nth-child(7) { transform:translate(-3.9em, 6.9em) }
#watch .digits li:nth-child(8) { transform:translate(-6.8em, 4em) }
#watch .digits li:nth-child(9) { transform:translate(-8em, 0) }
#watch .digits li:nth-child(10) { transform:translate(-6.9em, -4em) }
#watch .digits li:nth-child(11) { transform:translate(-3.9em, -6.9em) }
#watch .digits li:nth-child(12) { transform:translate(0, -8em) }
#watch .digits:before {
content:'';
width:1.6em;
height:1.6em;
border-radius:.8em;
position:absolute;
top:50%; left:50%;
margin:-.8em 0 0 -.8em;
background:#121314;
}
#watch .digits:after {
content:'';
width:4em;
height:4em;
border-radius:2.2em;
position:absolute;
top:50%; left:50%;
margin:-2.1em 0 0 -2.1em;
border:.1em solid #c6c6c6;
background:-webkit-radial-gradient(center, ellipse cover, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%);
background:-moz-radial-gradient(center, ellipse cover, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%);
background:radial-gradient(ellipse at center, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%);
}
/* Убираем анимации из CSS */
/* @keyframes hours { to {transform:rotate(335deg)} } */
#watch .hours-hand {
width:.8em;
height:7em;
border-radius:0 0 .9em .9em;
background:#232425;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -.8em -.4em;
box-shadow:#232425 0 0 2px;
transform-origin:0.4em 6.2em;
/* transform:rotate(-25deg); Убираем начальный поворот */
/* animation:hours 43200s linear 0s infinite; Убираем анимацию */
}
#watch .hours-hand:before {
content:'';
background:inherit;
width:1.8em;
height:.8em;
border-radius:0 0 .8em .8em;
box-shadow:#232425 0 0 1px;
position:absolute;
top:-.7em; left:-.5em;
}
#watch .hours-hand:after {
content:'';
width:0; height:0;
border:.9em solid #232425;
border-width:0 .9em 2.4em .9em;
border-left-color:transparent;
border-right-color:transparent;
position:absolute;
top:-3.1em; left:-.5em;
}
/* @keyframes minutes { to {transform:rotate(422deg)} } */
#watch .minutes-hand {
width:.8em;
height:12.5em;
border-radius:.5em;
background:#343536;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -1.5em -.4em;
box-shadow:#343536 0 0 2px;
transform-origin:0.4em 11em;
/* transform:rotate(62deg); Убираем начальный поворот */
/* animation:minutes 3600s linear 0s infinite; Убираем анимацию */
}
/* @keyframes seconds { to {transform:rotate(480deg)} } */
#watch .seconds-hand {
width:.2em;
height:14em;
border-radius:.1em .1em 0 0/10em 10em 0 0;
background:#c00;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -2em -.1em;
box-shadow:rgba(0,0,0,.8) 0 0 .2em;
transform-origin:0.1em 12em;
/* transform:rotate(120deg); Убираем начальный поворот */
/* animation:seconds 60s steps(60, end) 0s infinite; Убираем анимацию */
}
#watch .seconds-hand:after {
content:'';
width:1.4em;
height:1.4em;
border-radius:.7em;
background:inherit;
position:absolute;
left:-.65em; bottom:1.35em;
}
#watch .seconds-hand:before {
content:'';
width:.8em;
height:3em;
border-radius:.2em .2em .4em .4em/.2em .2em 2em 2em;
box-shadow:rgba(0,0,0,.8) 0 0 .2em;
background:inherit;
position:absolute;
left:-.35em; bottom:-3em;
}
</style>
<script>
function updateWatch() {
const now = new Date();
const hours = now.getHours() % 12;
const minutes = now.getMinutes();
const seconds = now.getSeconds();
// 360 градусов / 12 часов = 30 градусов на час
const hoursRotation = (hours + minutes / 60) * 30;
// 360 градусов / 60 минут = 6 градусов на минуту
const minutesRotation = (minutes + seconds / 60) * 6;
// 360 градусов / 60 секунд = 6 градусов на секунду
const secondsRotation = seconds * 6;
document.querySelector('.hours-hand').style.transform = `rotate(${hoursRotation}deg)`;
document.querySelector('.minutes-hand').style.transform = `rotate(${minutesRotation}deg)`;
document.querySelector('.seconds-hand').style.transform = `rotate(${secondsRotation}deg)`;
}
// Обновляем раз в секунду
setInterval(updateWatch, 1000);
// Обновляем сразу при загрузке
updateWatch();
</script>[/html]
Поделиться32025-10-29 15:59:21
Туман на фотографии, который убирается курсором мыши
[html]<div class="fog-container">
<canvas id="fog"></canvas>
<canvas id="fog-bg"></canvas>
<canvas id="brush"></canvas>
</div>
<style>
.fog-container {
aspect-ratio: 16 / 9;
position: relative;
overflow: hidden;
margin: 20px 0;
border-radius: 6px;
touch-action: none; /* ← блокирует стандартные жесты (важно для мобильных) */
}
.fog-container canvas {
display: block;
width: 100%;
height: 100%;
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
}
#brush {
opacity: 0;
}
/* Мобильные устройства: оставляем на всю ширину */
.fog-container {
aspect-ratio: 16 / 9;
position: relative;
overflow: hidden;
margin: 20px 0;
border-radius: 6px;
touch-action: none;
width: 100%;
}
/* Десктоп: ограничиваем максимальную ширину */
@media (min-width: 768px) {
.fog-container {
max-width: 60rem; /* ≈960px при базовом шрифте 16px */
/* Или, например: max-width: 80vw; — 80% ширины окна */
margin-left: auto;
margin-right: auto;
}
}
</style>
<script>
class FogParticle {
constructor(ctx, canvasWidth, canvasHeight) {
this.ctx = ctx;
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
this.x = 0;
this.y = 0;
}
setPosition(x, y) {
this.x = x;
this.y = y;
}
setVelocity(x, y) {
this.xVelocity = x;
this.yVelocity = y;
}
setImage(image) {
this.image = image;
}
render() {
if (!this.image) return;
this.ctx.drawImage(
this.image,
this.x - this.image.width / 2,
this.y - this.image.height / 2,
400,
400
);
this.x += this.xVelocity;
this.y += this.yVelocity;
if (this.x >= this.canvasWidth) {
this.xVelocity = -this.xVelocity;
this.x = this.canvasWidth;
} else if (this.x <= 0) {
this.xVelocity = -this.xVelocity;
this.x = 0;
}
if (this.y >= this.canvasHeight) {
this.yVelocity = -this.yVelocity;
this.y = this.canvasHeight;
} else if (this.y <= 0) {
this.yVelocity = -this.yVelocity;
this.y = 0;
}
}
}
class Fog {
constructor({ selector, density = 50, velocity = 2, particle, bgi } = {}) {
const canvas = document.querySelector(selector);
const bcr = canvas.parentElement.getBoundingClientRect();
this.ctx = canvas.getContext('2d');
this.canvasWidth = canvas.width = bcr.width;
this.canvasHeight = canvas.height = bcr.height;
this.particleCount = density;
this.maxVelocity = velocity;
this.particle = particle;
this.bgi = bgi;
this._createParticles();
this._setImage();
if (!this.bgi) return;
const img = new Image();
img.onload = () => {
const size = coverImg(img, this.canvasWidth, this.canvasHeight);
this.bgi = { img, w: size.w, h: size.h };
this._render();
};
img.src = this.bgi;
}
_createParticles() {
this.particles = [];
const random = (min, max) => Math.random() * (max - min) + min;
for (let i = 0; i < this.particleCount; i++) {
const particle = new FogParticle(this.ctx, this.canvasWidth, this.canvasHeight);
particle.setPosition(
random(0, this.canvasWidth),
random(0, this.canvasHeight)
);
particle.setVelocity(
random(-this.maxVelocity, this.maxVelocity),
random(-this.maxVelocity, this.maxVelocity)
);
this.particles.push(particle);
}
}
_setImage() {
if (!this.particle) return;
const img = new Image();
img.onload = () => this.particles.forEach(p => p.setImage(img));
img.src = this.particle;
}
_render() {
if (this.bgi) {
this.ctx.drawImage(this.bgi.img, 0, 0, this.bgi.w, this.bgi.h);
} else {
this.ctx.fillStyle = "rgba(0, 0, 0, 1)";
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
}
this.particles.forEach(p => p.render());
requestAnimationFrame(this._render.bind(this));
}
}
class Eraser {
constructor({ bgCanvas, brushCanvas, bgi, radius = 120 } = {}) {
this.bgCanvas = document.querySelector(bgCanvas);
this.brushCanvas = document.querySelector(brushCanvas);
this.bgCtx = this.bgCanvas.getContext('2d');
this.brushCtx = this.brushCanvas.getContext('2d');
this.parentElement = this.bgCanvas.parentElement;
const bcr = this.parentElement.getBoundingClientRect();
this.canvasWidth = this.bgCanvas.width = this.brushCanvas.width = bcr.width;
this.canvasHeight = this.bgCanvas.height = this.brushCanvas.height = bcr.height;
this.brushRadius = radius;
this.bgi = new Image();
this.bgi.src = bgi;
this.bgi.onload = this._attachEvents.bind(this);
const bgCanvasEl = this.bgCanvas;
this.utils = {
distanceBetween(point1, point2) {
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
},
angleBetween(point1, point2) {
return Math.atan2(point2.x - point1.x, point2.y - point1.y);
},
getMousePos(e) {
const bcr = bgCanvasEl.getBoundingClientRect();
return { x: e.clientX - bcr.left, y: e.clientY - bcr.top };
},
getTouchPos(touch) {
const bcr = bgCanvasEl.getBoundingClientRect();
return { x: touch.clientX - bcr.left, y: touch.clientY - bcr.top };
}
};
}
_attachEvents() {
const parent = this.parentElement;
// Мышь
parent.addEventListener('mousemove', this._onMouseMove.bind(this));
parent.addEventListener('mouseleave', this._onMouseLeave.bind(this));
// Касания
parent.addEventListener('touchstart', this._onTouchStart.bind(this), { passive: false });
parent.addEventListener('touchmove', this._onTouchMove.bind(this), { passive: false });
parent.addEventListener('touchend', this._onTouchEnd.bind(this), { passive: false });
}
_onMouseMove(e) {
const currentPoint = this.utils.getMousePos(e);
this._drawStroke(currentPoint);
}
_onMouseLeave() {
this.lastPoint = null;
}
_onTouchStart(e) {
e.preventDefault();
const touch = e.touches[0];
const pos = this.utils.getTouchPos(touch);
this.lastPoint = pos;
}
_onTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
const currentPoint = this.utils.getTouchPos(touch);
this._drawStroke(currentPoint);
}
_onTouchEnd(e) {
e.preventDefault();
this.lastPoint = null;
}
_drawStroke(currentPoint) {
this.lastPoint = this.lastPoint || currentPoint;
const dist = this.utils.distanceBetween(this.lastPoint, currentPoint);
const angle = this.utils.angleBetween(this.lastPoint, currentPoint);
for (let ii = 0; ii < dist; ii += 5) {
const x = this.lastPoint.x + (Math.sin(angle) * ii);
const y = this.lastPoint.y + (Math.cos(angle) * ii);
const brush = this.brushCtx.createRadialGradient(x, y, 0, x, y, this.brushRadius);
brush.addColorStop(0, 'rgba(0, 0, 0, 1)');
brush.addColorStop(0.3, 'rgba(0, 0, 0, 0.1)');
brush.addColorStop(1, 'rgba(0, 0, 0, 0)');
this.brushCtx.fillStyle = brush;
this.brushCtx.fillRect(
x - this.brushRadius,
y - this.brushRadius,
this.brushRadius * 2,
this.brushRadius * 2
);
}
this.lastPoint = currentPoint;
// Перерисовка фона с маской
this.bgCtx.globalCompositeOperation = 'source-over';
const size = coverImg(this.bgi, this.canvasWidth, this.canvasHeight);
this.bgCtx.drawImage(this.bgi, 0, 0, size.w, size.h);
this.bgCtx.globalCompositeOperation = 'destination-in';
this.bgCtx.drawImage(this.brushCanvas, 0, 0);
}
}
const coverImg = (img, width, height) => {
const ratio = img.width / img.height;
let w = width;
let h = w / ratio;
if (h < height) {
h = height;
w = h * ratio;
}
return { w, h };
};
// ⚠️ Убраны лишние пробелы в URL!
const bgi = 'https://atuin.ru/demo/i/fog-bg.webp';
function resize() {
// Очистим старые экземпляры при resize (опционально, но полезно)
new Fog({
selector: '#fog',
particle: 'https://atuin.ru/demo/i/fog-particle.png',
density: 60,
bgi,
});
new Eraser({
bgCanvas: '#fog-bg',
brushCanvas: '#brush',
radius: 80,
bgi,
});
}
resize();
window.addEventListener("resize", resize);
</script>[/html]
Быстрый ответ
Похожие темы
| Это новая тема с описанием:)))‡очень интересное содержание& | Тестовый форум | 2025-11-24 |
| 12345 | Новый форум | 2025-10-29 |
| фаыфыафыа | Новый форум | 2025-11-05 |
