UNPKG

8.64 kBJavaScriptView Raw
1(function ($) {
2 $.fn.tooltip = function (options) {
3 var timeout = null,
4 margin = 5;
5
6 // Defaults
7 var defaults = {
8 delay: 350,
9 tooltip: '',
10 position: 'bottom',
11 html: false
12 };
13
14 // Remove tooltip from the activator
15 if (options === "remove") {
16 this.each(function() {
17 $('#' + $(this).attr('data-tooltip-id')).remove();
18 $(this).off('mouseenter.tooltip mouseleave.tooltip');
19 });
20 return false;
21 }
22
23 options = $.extend(defaults, options);
24
25 return this.each(function() {
26 var tooltipId = Materialize.guid();
27 var origin = $(this);
28
29 // Destroy old tooltip
30 if (origin.attr('data-tooltip-id')) {
31 $('#' + origin.attr('data-tooltip-id')).remove();
32 }
33
34 origin.attr('data-tooltip-id', tooltipId);
35
36 // Get attributes.
37 var allowHtml,
38 tooltipDelay,
39 tooltipPosition,
40 tooltipText,
41 tooltipEl,
42 backdrop;
43 var setAttributes = function() {
44 allowHtml = origin.attr('data-html') ? origin.attr('data-html') === 'true' : options.html;
45 tooltipDelay = origin.attr('data-delay');
46 tooltipDelay = (tooltipDelay === undefined || tooltipDelay === '') ?
47 options.delay : tooltipDelay;
48 tooltipPosition = origin.attr('data-position');
49 tooltipPosition = (tooltipPosition === undefined || tooltipPosition === '') ?
50 options.position : tooltipPosition;
51 tooltipText = origin.attr('data-tooltip');
52 tooltipText = (tooltipText === undefined || tooltipText === '') ?
53 options.tooltip : tooltipText;
54 };
55 setAttributes();
56
57 var renderTooltipEl = function() {
58 var tooltip = $('<div class="material-tooltip"></div>');
59
60 // Create Text span
61 if (allowHtml) {
62 tooltipText = $('<span></span>').html(tooltipText);
63 } else{
64 tooltipText = $('<span></span>').text(tooltipText);
65 }
66
67 // Create tooltip
68 tooltip.append(tooltipText)
69 .appendTo($('body'))
70 .attr('id', tooltipId);
71
72 // Create backdrop
73 backdrop = $('<div class="backdrop"></div>');
74 backdrop.appendTo(tooltip);
75 return tooltip;
76 };
77 tooltipEl = renderTooltipEl();
78
79 // Destroy previously binded events
80 origin.off('mouseenter.tooltip mouseleave.tooltip');
81 // Mouse In
82 var started = false, timeoutRef;
83 origin.on({'mouseenter.tooltip': function(e) {
84 var showTooltip = function() {
85 setAttributes();
86 started = true;
87 tooltipEl.velocity('stop');
88 backdrop.velocity('stop');
89 tooltipEl.css({ visibility: 'visible', left: '0px', top: '0px' });
90
91 // Tooltip positioning
92 var originWidth = origin.outerWidth();
93 var originHeight = origin.outerHeight();
94 var tooltipHeight = tooltipEl.outerHeight();
95 var tooltipWidth = tooltipEl.outerWidth();
96 var tooltipVerticalMovement = '0px';
97 var tooltipHorizontalMovement = '0px';
98 var backdropOffsetWidth = backdrop[0].offsetWidth;
99 var backdropOffsetHeight = backdrop[0].offsetHeight;
100 var scaleXFactor = 8;
101 var scaleYFactor = 8;
102 var scaleFactor = 0;
103 var targetTop, targetLeft, newCoordinates;
104
105 if (tooltipPosition === "top") {
106 // Top Position
107 targetTop = origin.offset().top - tooltipHeight - margin;
108 targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2;
109 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
110 tooltipVerticalMovement = '-10px';
111 backdrop.css({
112 bottom: 0,
113 left: 0,
114 borderRadius: '14px 14px 0 0',
115 transformOrigin: '50% 100%',
116 marginTop: tooltipHeight,
117 marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2)
118 });
119 }
120 // Left Position
121 else if (tooltipPosition === "left") {
122 targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2;
123 targetLeft = origin.offset().left - tooltipWidth - margin;
124 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
125
126 tooltipHorizontalMovement = '-10px';
127 backdrop.css({
128 top: '-7px',
129 right: 0,
130 width: '14px',
131 height: '14px',
132 borderRadius: '14px 0 0 14px',
133 transformOrigin: '95% 50%',
134 marginTop: tooltipHeight/2,
135 marginLeft: tooltipWidth
136 });
137 }
138 // Right Position
139 else if (tooltipPosition === "right") {
140 targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2;
141 targetLeft = origin.offset().left + originWidth + margin;
142 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
143
144 tooltipHorizontalMovement = '+10px';
145 backdrop.css({
146 top: '-7px',
147 left: 0,
148 width: '14px',
149 height: '14px',
150 borderRadius: '0 14px 14px 0',
151 transformOrigin: '5% 50%',
152 marginTop: tooltipHeight/2,
153 marginLeft: '0px'
154 });
155 }
156 else {
157 // Bottom Position
158 targetTop = origin.offset().top + origin.outerHeight() + margin;
159 targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2;
160 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
161 tooltipVerticalMovement = '+10px';
162 backdrop.css({
163 top: 0,
164 left: 0,
165 marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2)
166 });
167 }
168
169 // Set tooptip css placement
170 tooltipEl.css({
171 top: newCoordinates.y,
172 left: newCoordinates.x
173 });
174
175 // Calculate Scale to fill
176 scaleXFactor = Math.SQRT2 * tooltipWidth / parseInt(backdropOffsetWidth);
177 scaleYFactor = Math.SQRT2 * tooltipHeight / parseInt(backdropOffsetHeight);
178 scaleFactor = Math.max(scaleXFactor, scaleYFactor);
179
180 tooltipEl.velocity({ translateY: tooltipVerticalMovement, translateX: tooltipHorizontalMovement}, { duration: 350, queue: false })
181 .velocity({opacity: 1}, {duration: 300, delay: 50, queue: false});
182 backdrop.css({ visibility: 'visible' })
183 .velocity({opacity:1},{duration: 55, delay: 0, queue: false})
184 .velocity({scaleX: scaleFactor, scaleY: scaleFactor}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'});
185 };
186
187 timeoutRef = setTimeout(showTooltip, tooltipDelay); // End Interval
188
189 // Mouse Out
190 },
191 'mouseleave.tooltip': function(){
192 // Reset State
193 started = false;
194 clearTimeout(timeoutRef);
195
196 // Animate back
197 setTimeout(function() {
198 if (started !== true) {
199 tooltipEl.velocity({
200 opacity: 0, translateY: 0, translateX: 0}, { duration: 225, queue: false});
201 backdrop.velocity({opacity: 0, scaleX: 1, scaleY: 1}, {
202 duration:225,
203 queue: false,
204 complete: function(){
205 backdrop.css({ visibility: 'hidden' });
206 tooltipEl.css({ visibility: 'hidden' });
207 started = false;}
208 });
209 }
210 },225);
211 }
212 });
213 });
214 };
215
216 var repositionWithinScreen = function(x, y, width, height) {
217 var newX = x;
218 var newY = y;
219
220 if (newX < 0) {
221 newX = 4;
222 } else if (newX + width > window.innerWidth) {
223 newX -= newX + width - window.innerWidth;
224 }
225
226 if (newY < 0) {
227 newY = 4;
228 } else if (newY + height > window.innerHeight + $(window).scrollTop) {
229 newY -= newY + height - window.innerHeight;
230 }
231
232 return {x: newX, y: newY};
233 };
234
235 $(document).ready(function(){
236 $('.tooltipped').tooltip();
237 });
238}( jQuery ));