jquery实现标签悬浮标注效果代码
代码语言:html
所属分类:其他
代码描述:jquery实现标签悬浮标注效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> html,body { width:100%; height:100%; overflow:hidden; margin:0; padding:0; font-family:NotoSansJP,Slack-Lato,appleLogo,sans-serif } .wrapper { width:100%; height:100%; background-color:#808080 } .wrapper::after { content:"."; display:block; height:0; font-size:0; clear:both; visibility:hidden } .menu-wrapper { box-sizing:border-box; float:left; width:18vw; height:100%; overflow-y:scroll } .menu { box-sizing:border-box; list-style:none; width:100%; margin:0; padding:10px; font-size:1.1vw } .menu>li { box-sizing:border-box; width:100%; height:100%; margin:0; padding:0 } .menu>li+li { margin-top:10px } .menu>li>a { box-sizing:border-box; display:inline-block; width:100%; height:100%; line-height:1.5em; padding:5px 10px; text-decoration:none; background-color:#40AAEF; color:#FFF; border-radius:4px; box-shadow:0 4px 0 rgba(0,0,0,0.7); transition:.2s all ease 0s } .menu>li>a.selected { background-color:#0E7AC4; box-shadow:none; transform:translate3d(0,3px,0) } .container { position:relative; float:left; width:calc(100% - 18vw); height:100% } .tooltip { display:none; position:absolute; top:0; left:0; margin:0; padding:0; font-size:1.1vw; line-height:1.8em; color:#FFF } .tooltip>dt { margin:0; padding:0 .5em; background-color:#16A085 } .tooltip>dd { margin:0; padding:0 .5em 0 2em; background-color:#1ABC9C } .tooltip>dd+dd { border-top:solid 1px #16A085 } </style> </head> <body> <!-- partial:index.partial.html --> <div class="wrapper"> <div class="menu-wrapper"> <ul id="jsi-category-container" class="menu"> <li><a href="1">metadata content</a></li> <li><a href="2">flow content</a></li> <li><a href="3">sectioning content</a></li> <li><a href="4">heading content</a></li> <li><a href="5">phrasing content</a></li> <li><a href="6">embedded content</a></li> <li><a href="7">interactive content</a></li> <li><a href="8">palpable content</a></li> <li><a href="9">sectioning root</a></li> <li><a href="10">form-associated elements</a></li> <li><a href="11">listed elements</a></li> <li><a href="12">submittable elements</a></li> <li><a href="13">resettable elements</a></li> <li><a href="14">labelable elements</a></li> <li><a href="15">reassociateable elements</a></li> <li><a href="16">script-supporting elements</a></li> </ul> </div> <div id="jsi-elements-container" class="container"> <dl id="jsi-tooltip-container" class="tooltip"><dt>categories</dt> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd> <dd class="jsc-tip-category"></dd><dt>content models</dt> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> <dd class="jsc-tip-contents-model"></dd> </dl> </div> </div> <!-- partial --> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jquery-3.2.1.min.js"></script> <script> var RENDERER = { PADDING: 0.05, init: function(a, b) { this.setParameters(a); this.reconstructMethods(); this.adjustContainer(); this.createElements(b); this.bindEvent(); this.render() }, setParameters: function(a) { this.categoryData = a; this.$window = $(window); this.$container = $("#jsi-elements-container"); this.$categoryContainer = $("#jsi-category-container"); this.$categoryWrapper = this.$categoryContainer.parent(); this.$categories = this.$categoryContainer.find("a"); this.$tipContainer = $("#jsi-tooltip-container"); this.$tipCategories = this.$tipContainer.find(".jsc-tip-category"); this.$tipContents = this.$tipContainer.find(".jsc-tip-contents-model"); this.width = this.$container.width(); this.height = this.$container.height(); this.$canvas = $("<canvas />"); this.context = this.$canvas.attr({ width: this.width, height: this.height }).appendTo(this.$container).get(0).getContext("2d"); this.selectedIndices = this.$categories.filter(".selected").map(function() { return parseInt($(this).attr("href")) }); this.animationCount = 0; this.elements = [] }, adjustContainer: function() { this.width = this.$container.width(); this.height = this.$container.height(); this.elementWidth = this.width * (1 - this.PADDING * 2) / 8; this.elementWidth += this.elementWidth / 8; this.elementHeight = this.elementWidth / 4; var b = 20 * this.width / 1200; if (this.elementHeight * 14.5 > this.height * (1 - this.PADDING * 2)) { this.elementHeight = this.height * (1 - this.PADDING * 2) / 14.5; b = 20 * this.height / 600 } this.font = "400 " + b + 'px "HG正楷書体-PRO"'; this.$canvas.attr({ width: this.width, height: this.height }); this.$categoryWrapper.css("overflow-y", (this.$categoryContainer.height() > this.$categoryWrapper.height() ? "scroll" : "hidden")); var a = Math.sqrt(Math.pow(this.width, 2) + Math.pow(this.height, 2)); this.gradient = this.context.createRadialGradient(this.width / 2, this.height / 2, 0, this.width / 2, this.height / 2, a); this.gradient.addColorStop(0, "hsl(220, 80%, 40%)"); this.gradient.addColorStop(1, "hsl(220, 80%, 10%)"); for (var c = 0, d = this.elements.length; c < d; c++) { this.elements[c].init() } }, createElements: function(a) { for (var b = 0, c = a.length; b < c; b++) { this.elements.push(new ELEMENT(this, a[b], b, this.selectedIndices)) } }, reconstructMethods: function() { this.render = this.render.bind(this) }, bindEvent: function() { var a = this; this.$categories.each(function(c) { var b = $(this); b.on("click", a.selectCategory.bind(a, c)) }); this.$window.on("resize", this.adjustContainer.bind(this)); this.$container.on("mouseleave mouseenter mousemove", this.checkMousePosition.bind(this)) }, selectCategory: function(c, a) { a.preventDefault(); if (this.$categories.eq(c).hasClass("selected")) { this.$categories.eq(c).removeClass("selected"); for (var b = 0, d = this.selectedIndices.length; b < d; b++) { if (this.selectedIndices[b] == c + 1) { this.selectedIndices.splice(b, 1); break } } } else { this.$categories.eq(c).addClass("selected"); this.selectedIndices.push(c + 1) } for (var b = 0, d = this.elements.length; b < d; b++) { this.elements[b].transform(this.selectedIndices) } }, checkMousePosition: function(b) { var a = this.$container.offset(), e = b.clientX - a.left + this.$window.scrollLeft(), f = b.clientY - a.top + this.$window.scrollTop(); for (var c = 0, d = this.elements.length; c < d; c++) { this.elements[c].checkMousePosition(e, f) } }, showToolTip: function(b, a) { this.context.fillStyle = "hsla(0, 0%, 0%, 0.5)"; this.context.fillRect(0, 0, this.width, this.height); this.$tipContainer.show(); this.$tipCategories.hide(); this.$tipContents.hide(); for (var c = 0, f = b.categories.length; c < f; c++) { this.$tipCategories.eq(c).text(this.categoryData[b.categories[c]]).show() } if (b.categories.length == 0) { this.$tipCategories.eq(0).text("none").show() } var d = 0; for (var c = 0, f = b.contents.categories.length; c < f; c++) { this.$tipContents.eq(d++).text(this.categoryData[b.contents.categories[c]]).show() } for (var c = 0, f = b.contents.tags.length; c < f; c++) { this.$tipContents.eq(d++).text("<" + b.contents.tags[c] + ">").show() } if (d == 0) { this.$tipContents.eq(0).text("none").show() } var h = this.$tipContainer.outerWidth(), g = this.$tipContainer.outerHeight(), e = (a.x <= this.width / 2) ? (a.x + this.elementWidth + this.width / 40) : (a.x - this.elementWidth - this.width / 40 - h), j = (a.y <= this.height / 2) ? (a.y + this.elementHeight + this.height / 80) : (a.y - this.elementHeight - this.height / 80 - g); if (e < 10) { e = 10 } else { if (e + h > this.width - 10) { e = this.width - h - 10 } } if (j < 10) { j = 10 } else { if (j + g > this.height - 10) { j = this.height - g - 10 } } this.context.lineWidth = 1; this.context.strokeStyle = "#FFFFFF"; this.context.beginPath(); this.context.moveTo(a.x + this.elementWidth / 2 * ((a.x <= this.width / 2) ? 1 : -1), a.y); this.context.lineTo(e + ((a.x <= this.width / 2) ? 0 : h), j + ((a.y <= this.height / 2) ? 0 : g)); this.context.stroke(); this.$tipContainer.css({ left: e, top: j }) }, render: function() { requestAnimationFrame(this.render); this.$tipContainer.hide(); this.context.fillStyle = this.gradient; this.context.fillRect(0, 0, this.width, this.height); this.elements.sort(function(c, d) { if (d.z - c.z > 0) { return 1 } else { if (d.z - c.z < 0) { return -1 } else { return c.hovered ? 1 : -1 } } }); this.context.font = this.font; this.context.textAlign = "center"; this.context.textBaseline = "middle"; for (var a = 0, b = this.elements.length; a < b; a++) { this.elements[a].render(this.context) } } }; var ELEMENT = function(c, a, b, d) { this.renderer = c; this.data = a; this.index = b; this.selected = this.setSelected(d); this.init() }; ELEMENT.prototype = { FOCUS_POSITION: 300, FAR_LIMIT: 600, ANIMATION_COUNT: 30, init: function() { this.x = this.renderer.width * this.renderer.PADDING + this.renderer.elementWidth / 2 + (this.index % 8) * this.renderer.elementWidth * 7 / 8 - this.renderer.width / 2; this.y = -this.renderer.elementHeight / 2 - Math.floor(this.index / 8) * this.renderer.elementHeight - ((this.index % 8 % 2 == 0) ? 0 : this.renderer.elementHeight / 2) - (this.renderer.height - this.renderer.elementHeight * 14.5) / 2 + this.renderer.height / 2; this.z = this.z0 = this.selected ? 0 : this.FAR_LIMIT; this.animationCount = -1; this.hovered = false }, setSelected: function(f) { for (var a = 0, c = f.length; a < c; a++) { var e = false; for (var b = 0, d = this.data.categories.length; b < d; b++) { if (f[a] == this.data.categories[b]) { e = true; break } } if (!e) { return false } } return true }, getRandomValue: function(b, a) { return b + (a - b) * Math.random() }, transform: function(b) { var a = this.setSelected(b); if (this.selected == a) { return } this.selected = a; this.animationCount = this.ANIMATION_COUNT; this.z0 = this.z }, ease: function(a) { return a < 0.5 ? 2 * a * a : -1 + (4 - 2 * a) * a }, checkMousePosition: function(e, f) { if (this.z > 0) { return } this.hovered = false; var a = this.getAxis(), d = this.renderer.elementWidth, b = this.renderer.elementHeight, c = b / d * 4; if (e < a.x - d / 2 || e > a.x + d / 2 || f < a.y - b / 2 || f > a.y + b / 2) { return } if (e <= a.x) { if (Math.abs((f - a.y) / (e - (a.x - d / 2))) > c) { return } } else { if (e > a.x && Math.abs((f - a.y) / (e - (a.x + d / 2))) > c) { return } } this.hovered = true }, getAxis: function() { var a = this.FOCUS_POSITION / (this.z + this.FOCUS_POSITION), b = this.renderer.width / 2 + this.x * a, c = this.renderer.height / 2 - this.y * a; return { rate: a, x: b, y: c } }, render: function(b) { var a = this.getAxis(), h = this.renderer.elementWidth, d = this.renderer.elementHeight, c = b.createLinearGradient(-this.renderer.elementWidth * 5 / 8, 0, this.renderer.elementWidth * 5 / 8, 0), e = 175 + (Math.floor(this.index / 8) % 2 == 0 ? 0 : 10), f = 70 * a.rate; this.showToolTip(a); if (this.animationCount >= 0) { var g = this.ease((this.ANIMATION_COUNT - this.animationCount) / this.ANIMATION_COUNT); if (this.selected) { this.z = this.z0 * (1 - g) } else { this.z = this.z0 + (this.FAR_LIMIT - this.z0) * g } this.animationCount-- } c.addColorStop(0, "hsla(" + e + ", " + f + "%, 30%, 0.9)"); c.addColorStop(0.3, "hsla(" + e + ", " + f + "%, 40%, 0.9)"); c.addColor.........完整代码请登录后点击上方下载按钮下载查看
网友评论0