jquery实现标签悬浮标注效果代码

代码语言:html

所属分类:其他

代码描述:jquery实现标签悬浮标注效果代码

代码标签: 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