3D标签云/滚动词条

vue:

<!DOCTYPE html>
<html>
<head>
    <title>svg3D标签云</title>
    <script src="https://cdn.bootcss.com/vue/2.2.0/vue.min.js"></script>
</head>
<body>
<div id='app' >
    <svg :width='width' :height='height' @mousemove='listener($event)'>
        <a :href="tag.href" v-for='tag in tags'>
            <text  :x='tag.x' :y='tag.y' :font-size='20 * (600/(600-tag.z))' :fill-opacity='((400+tag.z)/600)'>{{tag.text}}</text>
        </a>
    </svg>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            width:700,
            height:700,
            tagsNum:20,
            RADIUS:200,
            speedX:Math.PI/360,
            speedY:Math.PI/360,
            tags: [],
            colors:[],
        },
        computed:{
            CX(){
                return this.width/2;
            },
            CY(){
                return this.height/2;
            }
        },
        created(){
            this.changeColors();
            //初始化标签位置
            let tags=[];
            for(let i = 0; i < this.tagsNum; i++){
                let tag = {};
                let k = -1 + (2 * (i + 1) - 1) / this.tagsNum;
                let a = Math.acos(k);
                let b = a * Math.sqrt(this.tagsNum * Math.PI)
                tag.text = i + 'tag';
                tag.x = this.CX +  this.RADIUS * Math.sin(a) * Math.cos(b);
                tag.y = this.CY +  this.RADIUS * Math.sin(a) * Math.sin(b);
                tag.z = this.RADIUS * Math.cos(a);
                tag.href = 'https://imgss.github.io'
                tags.push(tag)

            }
            this.tags = tags;

        },
        mounted(){//使球开始旋转
            setInterval(()=>{
                this.rotateX(this.speedX);
                this.rotateY(this.speedY);
            }, 17)
        },
        methods:{

            rotateX(speedX){
                var cos = Math.cos(speedX);
                var sin = Math.sin(speedX);
                for(let tag of this.tags){
                    var y1 = (tag.y- this.CY) * cos - tag.z * sin  + this.CY;
                    var z1 = tag.z * cos + (tag.y- this.CY) * sin;
                    tag.y = y1;
                    tag.z = z1;
                }
            },
            rotateY(speedY){
                var cos = Math.cos(speedY);
                var sin = Math.sin(speedY);
                for(let tag of this.tags){
                    var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
                    var z1 = tag.z * cos + (tag.x - this.CX) * sin;
                    tag.x = x1;
                    tag.z = z1;
                }
            },
            listener(event){//响应鼠标移动
                var x = event.clientX - this.CX;
                var y = event.clientY - this.CY;
                this.speedX = x*0.0001>0 ? Math.min(this.RADIUS*0.00002, x*0.0001) : Math.max(-this.RADIUS*0.00002, x*0.0001);
                this.speedY = y*0.0001>0 ? Math.min(this.RADIUS*0.00002, y*0.0001) : Math.max(-this.RADIUS*0.00002, y*0.0001);
            },
            changeColors(){
                for(var i = 0;i<30;i++){
                    var r = Math.floor(Math.random() * 256);
                    var g = Math.floor(Math.random() * 256);
                    var b = Math.floor(Math.random() * 256);
                    this.colors[i] = "rgb(" + r + ',' + g + ',' + b + ")";
                }
            },
        }
    })
</script>
</body>
</html>

no vue:

<!DOCTYPE html>
<html>
<head>
    <title>svg3D标签云</title>
</head>
<body>
<svg width='700' height='700'>
    <a href="https://www.baidu.com">
        <text x='10' y='12'>1222</text>
    </a>
    <text x='100' y='120'>weed</text>
    <text x='120' y='152'>sdcc</text>
    <text x='160' y='222'>dfdf</text>
    <text x='60' y='92'>vbbb</text>
    <text x='160' y='300'>evvv</text>
    <text x='290' y='400'>hhhh</text>
    <text x='633' y='300'>wrgg</text>
    <text x='400' y='500'>ohhh</text>
    <text x='320' y='400'>qvbn</text>
    <text x='480' y='200'>rvbj</text>
    <text x='303' y='120'>eghj</text>
    <text x='100' y='120'>weed</text>
    <text x='120' y='152'>sdcc</text>
    <text x='160' y='222'>dfdf</text>
    <text x='60' y='92'>vbbb</text>
    <text x='160' y='300'>evvv</text>
    <text x='290' y='400'>hhhh</text>
    <text x='633' y='300'>wrgg</text>
    <text x='400' y='500'>ohhh</text>
    <text x='320' y='400'>qvbn</text>
    <text x='480' y='200'>rvbj</text>
    <text x='303' y='120'>eghj</text>
</svg>
<script>
    var paper = document.querySelector("svg");//svg
    tags = document.querySelectorAll('svg text');
    RADIUS =200,
        FONTSIZE = RADIUS*0.1,
        fallLength = 600,//焦距
        tagArr=[],
        angleX = Math.PI/300,
        angleY = Math.PI/300,
        CX = paper.getAttribute('width')/2,//球心坐标
        CY = paper.getAttribute('height')/2;//球心坐标


    function Tag(ele , x , y , z){
        this.ele = ele;
        this.x = x;
        this.y = y;
        this.z = z;
    }
    function init(){
        var len = tags.length
        for(var i=0;i<len;i++){
            var a , b;
            var k = -1+(2*(i+1)-1)/len;
            var a = Math.acos(k);
            var b = a*Math.sqrt(len*Math.PI);
            // var a = Math.random()*2*Math.PI;
            // var b = Math.random()*2*Math.PI;
            var x =CX +  RADIUS * Math.sin(a) * Math.cos(b);
            var y =CY +  RADIUS * Math.sin(a) * Math.sin(b);
            var z = RADIUS * Math.cos(a);
            var t = new Tag(tags[i] , x , y , z);
            tags[i].setAttribute('x',x);
            tags[i].setAttribute('y',y);
            tags[i].setAttribute('font-size', FONTSIZE * (fallLength/(fallLength-this.z)));
            tags[i].setAttribute('fill', "rgb("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+")")
            tagArr.push(t);
        }
    }
    Array.prototype.forEach = function(callback){
        for(var i=0;i<this.length;i++){
            callback.call(this[i]);
        }
    }
    function animate(){
        setInterval(function(){
            // angleY += Math.PI/300;
            // angleY = angleX>Math.PI? 0 : angleX
            rotateX();
            rotateY();
        } , 17);
    }
    function rotateX(){
        var cos = Math.cos(angleX);
        var sin = Math.sin(angleX);
        tagArr.forEach(function(){
            var y1 = (this.y-CY) * cos - this.z * sin  +CY;
            var z1 = this.z * cos + (this.y-CY) * sin;
            this.y = y1;
            this.z = z1;
            this.ele.setAttribute('y',this.y)
            this.ele.setAttribute('font-size', FONTSIZE * (fallLength/(fallLength-this.z)));
        })

    }
    function rotateY(){
        var cos = Math.cos(angleY);
        var sin = Math.sin(angleY);
        tagArr.forEach(function(){
            var x1 = (this.x-CX) * cos - this.z * sin +CX;
            var z1 = this.z * cos + (this.x-CX) * sin;
            this.x = x1;
            this.z = z1;
            this.ele.setAttribute('x',this.x)
            this.ele.setAttribute('font-size', FONTSIZE * (fallLength/(fallLength-this.z)));
        })
    }
    paper.addEventListener("mousemove" , function(event){
        var x = event.clientX - CX;
        var y = event.clientY - CY;
        // angleY = -x* (Math.sqrt(Math.pow(x , 2) + Math.pow(y , 2)) > RADIUS/4 ? 0.0002 : 0.0001);
        // angleX = -y* (Math.sqrt(Math.pow(x , 2) + Math.pow(y , 2)) > RADIUS/4 ? 0.0002 : 0.0001);
        angleY = x*0.0001>0 ? Math.min(RADIUS*0.00002,x*0.0001) : Math.max(-RADIUS*0.00002,x*0.0001);
        angleX = y*0.0001>0 ? Math.min(RADIUS*0.00002,y*0.0001) : Math.max(-RADIUS*0.00002,y*0.0001);
    });
    init();
    animate();

</script>
</body>
</html>

canvas:

https://github.com/goat1000/TagCanvas

原理:

https://www.cnblogs.com/axes/p/3501424.html

参考:

https://github.com/imgss/imgss.github.io/tree/master/demo/svg
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值