Как правильно сверстать глаз?
Подскажите, пожалуйста, как сверстать такой глаз:
пробовал использовать border-radius, но что- то не получилось.
const pup = document.querySelector('#pup');
const container = document.querySelector('.lien');
let cursor = {x: 0, y: 0};
let position = {x: 0, y: 0};
let width=500, height=500;
let radius = 20;
let speedMultiplier = 1e-3;
let lastTime;
let frames = 5e5;
function onMouseMove(event){
const bounds = container.getBoundingClientRect();
cursor.x = event.clientX - bounds.left - bounds.width / 2;
cursor.y = event.clientY - bounds.top - bounds.height / 2;
cursor.length = Math.sqrt(cursor.x * cursor.x + cursor.y * cursor.y);
cursor.x *= radius / cursor.length;
cursor.y *= radius / cursor.length;
}
document.addEventListener("mousemove", onMouseMove);
function loop(timestamp) {
const deltaTime = lastTime ? timestamp - lastTime : 0;
lastTime = timestamp;
if (0 === deltaTime) {
if (--frames > 0) return requestAnimationFrame(loop);
else return;
}
const multiplier = speedMultiplier * deltaTime;
const vector = {
x: cursor.x - position.x,
y: cursor.y - position.y,
};
position.x += vector.x * multiplier;
position.y += vector.y * multiplier;
// if(position.x<0) position.x = 0;
// if(position.x>width-radius*2) position.x = width-radius*2;
// if(position.y<0) position.y = 0;
// if(position.y>height-radius*2) position.y = height-radius*2;
pup.setAttribute('transform', `translate(${position.x}, ${position.y})`);
if (--frames > 0) requestAnimationFrame(loop);
else console.log("Out of frames");
}
requestAnimationFrame(loop);
.conatiner {
width: 800px;
}
.lien {
margin: auto;
width: 20%;
position: relative;
}
.bottom-line {
width: 100%;
height: 10px;
background: black;
border-radius: 0 0 50% 50% / 0 0 100% 100%;
}
<div class="container">
<div class="lien anim">
<svg version="1.1" id="oeil" viewBox="0 0 62 36">
<style type="text/css">
.st0 {
fill: none;
stroke: #000000;
stroke-width: 2;
stroke-miterlimit: 10;
}
.st1 {
fill: none;
stroke: #000000;
stroke-miterlimit: 10;
}
</style>
<mask id="eyemask">
<rect fill="black" x="0" y="0" width="62" height="36" />
<path stroke="black" fill="white" d="M59,18c0,0-12.5,16-28,16S3,18,3,18S15.5,2,31,2S59,18,59,18z" />
</mask>
<path id="contour" class="st0 circle" d="M59,18c0,0-12.5,16-28,16S3,18,3,18S15.5,2,31,2S59,18,59,18z" />
<g mask="url(#eyemask)">
<g id="pup" class="anim eye">
<circle class="st1" cx="31" cy="18" r="11" />
<circle id="rondpup"fill="#FFB703" cx="31" cy="18" r="7" />
</g>
</g>
</svg>
</a>
<div class="bottom-line">
</div>
</div>
</div>
Ответы (2 шт):
Автор решения: UserTest013
→ Ссылка
Конечно не pixel perfect, но поигравшись в цифрами можно приблизится.
:root {
--size: 200px;
--border: 20px;
}
.eye {
position: relative;
left: 70px;
height: var(--size);
width: var(--size);
border: var(--border) solid black;
border-radius: 80% 0;
transform: rotate(45deg);
overflow: hidden;
}
.eyeball {
position: absolute;
border: var(--border) solid black;
border-radius: 50%;
height: var(--size);
width: var(--size);
top: -35%;
left: -35%;
}
.pupil {
position: absolute;
border-radius: 50%;
height: calc(var(--size) / 2);
width: calc(var(--size) / 2);
background: #feb702;
top: 35%;
left: 35%;
}
<div class="eye">
<div class="eyeball">
<div class="pupil"></div>
</div>
</div>
Upd:
const eyeball = document.querySelector('#eyeball');
const container = document.querySelector('.container');
let cursor = {
x: 0,
y: 0
};
let position = {
x: 0,
y: 0
};
let width = 500;
let height = 500;
let radius = 40;
let speedMultiplier = 1e-3;
let lastTime;
let frames = 5e5;
function onMouseMove(event) {
const bounds = container.getBoundingClientRect();
cursor.x = event.clientX - bounds.left - bounds.width / 2;
cursor.y = event.clientY - bounds.top - bounds.height / 2;
cursor.length = Math.sqrt(cursor.x * cursor.x + cursor.y * cursor.y);
cursor.x *= radius / cursor.length;
cursor.y *= radius / cursor.length;
}
document.addEventListener("mousemove", onMouseMove);
function loop(timestamp) {
const deltaTime = lastTime ? timestamp - lastTime : 0;
lastTime = timestamp;
if (deltaTime === 0 && --frames > 0) {
return requestAnimationFrame(loop);
}
if (deltaTime === 0) {
return;
}
const multiplier = speedMultiplier * deltaTime;
const vector = {
x: cursor.x - position.x,
y: cursor.y - position.y,
};
position.x += vector.x * multiplier;
position.y += vector.y * multiplier;
eyeball.setAttribute('transform', `translate(${position.x}, ${position.y})`);
if (--frames > 0) {
requestAnimationFrame(loop);
}
}
requestAnimationFrame(loop);
.container {
width: 200px;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100">
<style type="text/css">
.st0 {
fill: none;
stroke: #000000;
stroke-width: 5;
}
.st1 {
fill: #feb702;
stroke: none;
}
</style>
<mask id="eyemask">
<rect fill="black" x="0" y="0" width="100" height="100" />
<path stroke="black" fill="white" d="m 14,50 c 28,27 43,28 72,0 -28,-27 -44,-27 -72,0 z" />
</mask>
<path class="st0" d="m 10,50 c 30,30 50,30 80,0 -30,-30 -50,-30 -80,0 z" />
<g mask="url(#eyemask)">
<g id="eyeball">
<circle class="st0" cx="50" cy="40" r="23" />
<circle class="st1" cx="50" cy="40" r="10" />
</g>
</g>
</svg>
</div>
Автор решения: Alexandr_TT
→ Ссылка
Вариант SVG
Как-то так:
const pupil = document.getElementById("pup");
document.addEventListener("mousemove", function(e){
let x = e.clientX;
let y = e.clientY;
const pupilRect = pupil.getBoundingClientRect();
const radius = 24;
const angle = Math.atan2(y-pupilRect.top,x-pupilRect.left)+Math.PI;
pupil.setAttribute('transform', `translate(${-radius*Math.cos(angle)},${-radius*Math.sin(angle)})`);
});
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="svg4" width="300" height="240" viewBox="0 0 600 480">
<defs>
<radialGradient id="Rg" fx="25%" fy="25%">
<stop offset="10%" stop-color="white" />
<stop offset="95%" stop-color="#FEB703" />
</radialGradient>
</defs>
<g id="pup" class="anim eye" fill="url(#Rg)" >
<circle cx="294" cy="220" r="50" />
<circle cx="294" cy="220" r="70" fill="none" stroke="black" stroke-width="4" />
</g>
<path d="M106.3 193.2s50.5 149 187.6 147.3c135.5-1.7 185-147.3 185-147.3" id="path829" fill="none"
stroke="#3B3838" stroke-width="28" stroke-linecap="butt" stroke-linejoin="miter" />
<path d="M40.3 261.4c73.6-89 158-134.2 253.6-133.8 94 .5 204.8 61.4 248.3 133.8-47.1 75.1-152.3 145.5-248.3 146-97.5.4-187.8-70-253.6-146z" id="path827" fill="none" stroke="#3B3838" stroke-width="26" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" />
<ellipse cx="294" cy="460" rx="270" ry="25" fill="#3B3838" />
</svg>
