-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathEyes.html
127 lines (108 loc) · 4.26 KB
/
Eyes.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<!DOCTYPE html>
<html>
<head>
<title>View</title>
<style>
body {
margin: 0;
box-sizing: border-box;
width: 100%;
height: 100%;
}
svg {
width: 100px;
height: 80px;
position: absolute;
}
#leftEye {
top: 100px;
left: 100px;
}
#rightEye {
top: 100px;
left: 250px;
}
</style>
</head>
<body>
<h1 style="margin-left: 3em;">I see where you go...</h1>
<script>
const eyeView = id => `
<svg id="${id}" viewBox="0 0 120 120">
<filter id="shadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
<feOffset dx="0" dy="8" />
<feColorMatrix type="matrix"
values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 .5 0"/>
<feBlend in="SourceGraphic" mode="normal"/>
</filter>
<radialGradient id="gradient1" gradientUnits="objectBoundingBox" cx="50%" cy="50%" r="50%">
<stop offset= "38%" stop-color="#000000" stop-opacity="1" />
<stop offset= "46%" stop-color="#073F80" stop-opacity="1" />
<stop offset= "90%" stop-color="#8EC0DD" stop-opacity="1" />
<stop offset="100%" stop-color="#2F3A46" stop-opacity="1" />
</radialGradient>
<g id="${id}_iris">
<ellipse cx="60" cy="60" rx="30" ry="30" opacity="1" fill="url(#gradient1)" />
<ellipse cx="50" cy="50" rx="7" ry="7" opacity="1" fill="#FFFFFF" fill-opacity="0.8"/>
</g>
<g id="${id}_openLids">
<path d="M0 60 A60,60 0 0,1 120,60 A60,30 0 0,0 0,60 Z" opacity="1" fill="#FDDC99" fill-opacity="1" filter="url(#shadow)" />
<path d="M0 60 A60,60 0 0,0 120,60 A60,40 0 0,1 0,60 Z" opacity="1" fill="#F4CB76" fill-opacity="1" />
</g>
<g id="${id}_closeLid">
<path d="M0 60 A60,60 0 0,1 120,60 A60,40 0 0,1 0,60 Z" opacity="1" fill="#FDDC99" fill-opacity="1" />
</g>
</svg>
`;
document.writeln(eyeView('leftEye'));
document.writeln(eyeView('rightEye'));
const v = 14; // versatz - Abstand des Pupillenzentrums vom Augenzentrum in SVG units
const eyeBinding = eyeId => {
const rect = document.querySelectorAll(eyeId + "_iris ellipse")[0].getBoundingClientRect();
const iris = document.querySelector(eyeId + "_iris");
const closeLidLayer = document.querySelector(eyeId + "_closeLid");
closeLidLayer.style.opacity = 0;
setInterval( evt => {
if (closeLidLayer.style.opacity === '1') return; // do not close and then open if already closed
closeLidLayer.style.opacity = '1';
setTimeout(evt => closeLidLayer.style.opacity = '0', 300)
}, 7 * 1000);
const xo = rect.x + rect.width/2; // x-origin
const yo = rect.y + rect.height/2; // y-origin
document.querySelector(eyeId).onclick = evt =>
closeLidLayer.style.opacity = (closeLidLayer.style.opacity === '1') ? '0' : '1';
return evt => {
const xm = evt.clientX - xo; // the normalized x/y coords to work with
const ym = evt.clientY - yo;
const xmax = rect.width/1.5;
const ymax = rect.height/2;
const widestFocus = 400; // when x is so far away, the eye is maximal extended
const scaledX = xm * (xmax / widestFocus );
let xe = xm > 0
? Math.min( xmax, scaledX)
: Math.max(-xmax, scaledX);
const scaledY = ym * (ymax / widestFocus );
let ye = ym > 0
? Math.min( ymax, scaledY)
: Math.max(-ymax, scaledY);
if (xe*xe + ye*ye > xmax * ymax) {
xe *= 0.9;
ye *= 0.9;
}
iris.style.transform = `translateX(${xe}px) translateY(${ye}px)`;
}
};
const leftListener = eyeBinding('#leftEye');
const rightListener = eyeBinding('#rightEye');
document.onmousemove = evt => { // highlander pattern
leftListener(evt);
rightListener(evt);
}
</script>
<div id="out"></div>
</body>
</html>