Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D3 —— 动画、事件、交互 #13

Open
Heqingsong opened this issue Aug 16, 2019 · 0 comments
Open

D3 —— 动画、事件、交互 #13

Heqingsong opened this issue Aug 16, 2019 · 0 comments

Comments

@Heqingsong
Copy link
Owner

Heqingsong commented Aug 16, 2019

动画效果

属性过渡

    var width = 400;
    var height = 300;

    var svg = d3.select('body')
          .append('svg')
          .attr({
            'width': width,
            'height': height
          })
          .style({
            'background-color': '#212030'
          });

    var rect = svg.append('rect')
                .attr({
                    'x': 0,
                    'y': 0,
                    'width': 100,
                    'height': 30
                })
                .style({
                    'fill': '#F00'
                });

    // 第一种方法
    // .transition()
    // .attr('width', 300);

    var text = svg.append('text')
                .attr({
                    'fill': '#FFF',
                    'x': 0,
                    'y': 0,
                    'dy': '1.2em',
                    'text-anchor': 'end'
                })
                .text(100);

    // 第二种方法
    // 创建过渡对象
    var rectTran = rect.transition()
    
    // 设定延迟时间
    .delay(500)

    // 设定过渡的持续时间
    .duration(2000)

    // 过渡的样式 
    // linear 线性变化
    // cubic 逐渐加快
    // elastic 类似弹簧接近终点
    // back 先回缩再冲向终点
    // bounce 在终点处回弹几次
    // 上述可以在后面追加 -in 正方向运动 | -out 反方向运动 | -in-out 前半段in后半段out | -out-in 前半段out后半段in
    .ease('bounce')
    
    // 过渡到目标的属性
    .attr({
    // 'width': width,
        'height': height
    })

    // 将属性使用插值函数 tween() 进行过渡
    .attrTween('width', function(d, i, a){
        return function(t){
            return Number(a) + t * height;
        }
    })

    // 过渡到目标的样式
    .style({
        'fill': '#4caf50'
    })

    // 与 attrTween 类似
    // .styleTween()

    // 过渡结束后,删除被过渡的元素
    .remove();

    var initx = text.attr('x');
    var initText = text.text();

    var textTran = text.transition()
        .delay(500)
        .duration(2000)
        // .text('fcc')
        // 文字过渡需要使用tween
        .tween('text', function(){
            return function(t){
                d3.select(this)
                .attr({
                    'x': Number(initx) + t * 400,
                    'y': Number(initx) + t * 285
                })
                .text(Math.floor(Number(initText) + t * 300));
            }
        });

子元素过渡

    var width = 400;
    var height = 300;

    var svg = d3.select('body')
          .append('svg')
          .attr({
            'width': width,
            'height': height
          })
          .style({
            'background-color': '#212030'
          });

    // var g = d3.select('g')
    //           .transition()
    //           .attr('x', 50);

    var g = svg.append('g');

    var dataset = [100, 100, 100];

    var rect = g.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr({
              'fill': '#FFF',
              'id': function(d, i){
                return 'rect' + i;
              },
              'x': 10,
              'y': function(d, i){
                return 10 + i * 35;
              },
              'width': function(d, i){
                return d;
              },
              'height': 30
            });

   g.selectAll('rect')
    .transition()
    .duration(2000)

    // 添加过滤器 过滤掉第一个元素
    .filter(function(d, i){
        return i >= 1;
    })
    .attr('width', width - 20)

    // 过渡事件监听
    .each('start', function(d, i){
        console.log('过渡开始的时候执行!');
    })
    .each('end', function(d, i){
        console.log('过渡完毕的时候执行!');
    })
    .each('interrupt', function(d, i){
        console.log('过渡被打断的时候执行!');
    });

    // 制造故意打断
    setTimeout(function(){
       g.select('#rect2')
        .transition()
        .attr('width', dataset[2]);
    }, 1000);

    // 执行结果
    // 2 过渡开始的时候执行!
    // 过渡被打断的时候执行!
    // 过渡完毕的时候执行!


    // 设置比例尺的过渡
    var xScale = d3.scale.linear()
                .domain([0, 10])
                .range([0, 300]);

    var xAxis = d3.svg.axis()
                .scale(xScale)
                .orient('bottom');

    var g = svg.append('g')
            .attr({
                'class': 'axis',
                'transform': 'translate(50, 200)'
            })
            .call(xAxis);

    xScale.domain([0, 50]);
    g.transition()
     .duration(2000)
     .call(xAxis);

事件监听器、鼠标、键盘、触屏

    var width = 500;
    var height = 500;

    // 创建容器
    var svg = d3.select('body')
        .append('svg')
        .attr({
            'width': width,
            'height': height
        })
        .style({
            'background-color': '#404a58'
        });

    var cirlceUpdate = svg.selectAll('circle')
        .data([1, 70])
        .enter()
        .append('circle')
        .attr({
            'cx': 250,
            'cy': 250,
            'r': 100,
            'fill': '#c23632'
        })

        // 支持的事件列表 https://developer.mozilla.org/zh-CN/docs/Web/Events

        // 绑定执行一次的事件
        .on('click', function(d){
            // 注意 d3 event 保存的对象是不同的,留意下面的log 输出
            // MouseEvent {isTrusted: true, screenX: 857, screenY: 384, clientX: 218, clientY: 215, …}
            console.log(d3.event);
          
            // 获取相对容器的坐标
            console.log(d3.mouse(this)); // [258, 221]
            
            // 删除 click 事件监听
            d3.select(this).on('click', null);
        })
        .on('mouseover', function(d, i){
            d3.select(this)
                .transition()
                .duration(500)
                .attr({
                    'fill': '#FFF',
                    'r': 150
                });
        })
        .on('mouseout', function(d, i){
            d3.select(this)
                .transition()
                .duration(500)
                .attr({
                    'fill': 'red',
                    'r': 100
                });
        })
        .on('touchmove', function(d){
            
            // TouchEvent {isTrusted: true, touches: TouchList, targetTouches: TouchList, changedTouches: TouchList, altKey: false, …}
            console.log(d3.event);
            
            var pos = d3.touches(this)[0];
            d3.select(this)
                .attr({
                    'cx': pos[0],
                    'cy': pos[1]
                })
        });

    d3.select('body')
    // !!! 注意 过渡对象只能在 事件监听之后,过渡对象没有 on()
    // .transition()
    .on('keydown', function(d){
    
        // KeyboardEvent {isTrusted: true, key: "j", code: "KeyJ", location: 0, ctrlKey: false, …}
        console.log(d3.event);
    
        console.log(d3.event.keyCode);
        console.log(String.fromCharCode(d3.event.keyCode));
    });

行为

拖拽

    var width = 500;
    var height = 500;

    // 创建容器
    var svg = d3.select('body')
        .append('svg')
        .attr({
            'width': width,
            'height': height
        })
        .style({
            'background-color': '#404a58'
        });

    // 创建一个拖拽行为
    var drag = d3.behavior.drag()

             // 设置拖拽的起点
             .origin(function(d, i){
               return {x: 250, y: 250};
             })
             .on('dragstart', function(d){
               console.log('拖拽开始');
             })
             .on('dragend', function(d){
               console.log('拖拽结束');
             })
             
             // 拖动监听器
             .on('drag', function(d){
               d3.select(this)
                 .attr({
                   'cx': d.cx = d3.event.x,
                   'cy': d.cy = d3.event.y
                 });
             });

    var cirlceUpdate = svg.selectAll('circle')
        .data([1, 70])
        .enter()
        .append('circle')
        .attr({
            'cx': 250,
            'cy': 250,
            'r': 50,
            'fill': '#c23632'
        })
        .call(drag);

缩放

    var width = 500;
    var height = 500;

    // 创建容器
    var svg = d3.select('body')
        .append('svg')
        .attr({
            'width': width,
            'height': height
        })
        .style({
            'background-color': '#404a58'
        });

    var x = d3.scale.linear().domain([0, width]).range([0, width]);
    var y = d3.scale.linear().domain([0, height]).range([0, height]);

    // 创建一个缩放
    var zoom = d3.behavior.zoom()
        // 设置x,y比例尺 根据比例尺的放大缩小改变
        .x(x)
        .y(y)

        // 设置缩放中心
        .center([250, 250])

        // 设置缩放的最大小值
        .scaleExtent([1, 10])
        .on('zoomstart', function(d){
        console.log('缩放开始');
        })
        .on('zoomend', function(d){
        console.log('缩放结束');
        })
        // 缩放中
        .on('zoom', function(d){
        d3.select(this)
            .attr('transform', 'translate('+ d3.event.translate +')' + 'scale('+ d3.event.scale +')')
        });

    var cirlceUpdate = svg.selectAll('circle')
        .data([1, 70])
        .enter()
        .append('circle')
        .attr({
            'cx': 250,
            'cy': 250,
            'r': 50,
            'fill': '#c23632'
        })
        .call(zoom);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant