Web前端笔记-圆环随时间逐渐缩小(使用two.js)

这里给出效果图:

这里就给出截图,不搞gif了:

运行时:

这里主要是使用了setInterval去操作的,并且设置的timeout为0,这样的效果是比较好的。

关键代码如下:

画图相关文件:

;

import * as Two from "JS/two";
import * as $ from "JS/jquery";

let two;
let mouse;
let isPressed = false;
let originalPositionX = 0;
let originalPositionY = 0;
let map = new Map();
let rect;

export function drawGraphic(){

  let elem = document.getElementById("draw-shapes");
  let params = {

    type: Two.Types['canvas'],
    fullscreen: true,
    autostart: true
  };

  two = new Two(params).appendTo(elem);
  mouse = new Two.ZUI(two.scene);
  mouse.addLimits(0.01, 10);

  let $stage = $(two.renderer.domElement);
  $stage.bind('mousewheel wheel', function(event){

    let e = event.originalEvent;
    e.stopPropagation();
    e.preventDefault();

    let dy = (e.wheelDeltaY || -e.deltaY) / 1000;
    // console.log(e.clientX + "   " + e.clientY)
    mouse.zoomBy(dy, e.clientX, e.clientY);
  });

  $stage.bind('mouseup', function(event){

    isPressed = false;
  });
  $stage.bind('mouseout', function(event){

    isPressed = false;
  });

  $stage.bind('mousedown', function(event){

    isPressed = true;
    originalPositionX = event.clientX;
    originalPositionY = event.clientY;

    let x = event.clientX;
    let y = event.clientY;

    for(let value of map){

      let xOffset = value[0]._width / 2;
      let yOffset = value[0]._height / 2;

      let letX = ((value[0]._translation._x - xOffset) * (two.scene._matrix.elements[0]) + two.scene._matrix.elements[2]);
      let letY = ((value[0]._translation._y - yOffset) * (two.scene._matrix.elements[4]) + two.scene._matrix.elements[5]);
      let letWidth = value[0]._width * two.scene._matrix.elements[0];
      let letHeight = value[0]._height * two.scene._matrix.elements[4];

      if(x > letX &&
        y > letY &&
        x < letX + letWidth &&
        y < letY + letHeight
      ){


        let rgbStr = getRandColor();
        value[0].fill = rgbStr;
        break;
      }
    }

  });

  $stage.bind('mousemove', function(event){

    if(isPressed){

      let boolX = event.clientX - originalPositionX;
      let boolY = event.clientY - originalPositionY;
      mouse.graphicMove(boolX, boolY);
      originalPositionX = event.clientX;
      originalPositionY = event.clientY;
    }
  });

  for(let i = -5000; i < 5000; i += 200){

    for(let j = -5000; j < 5000; j += 200){

      let rgbStr = getRandColor();
      createBtn(1001, i, j, 500, rgbStr);
    }
  }
}

function createBtn(id, x, y, weight, color) {

  rect = two.makeRectangle(x, y, 200, 200);
  rect.noStroke();
  rect.fill = color;
  rect.myId = id;

  map.set(rect, weight);
}

function getRandColor(){

  let r = Math.round(Math.random() * 255);
  let g = Math.round(Math.random() * 255);
  let b = Math.round(Math.random() * 255);
  let rgbStr = "rgb(" + r + "," + g + "," + b + ")";
  return rgbStr;
}

//计算当前屏幕圆心 对应的 图形坐标
function getScreenOriginal(){

  let original = {
    x: 0,
    y: 0
  };

  original.x = two.width / 2;
  original.y = two.height / 2;

  // console.log(two.scene._matrix.elements)

  //获取水平位移及垂直位移
  //将浏览器上界面坐标转换为two.js的场景坐标,也就是 cirX和cirY为当前界面中点的场景坐标
  let cirX = (original.x - two.scene._matrix.elements[2]) / two.scene._matrix.elements[0];
  let cirY = (original.y - two.scene._matrix.elements[5]) / two.scene._matrix.elements[4];

  console.log("当前圆心 cirX:" + cirX + "  cirY:" + cirY);

  original.x = cirX;
  original.y = cirY;

  return original;
}

export function flyToPosition(x, y){

  //当前屏幕中点 对应的 场景坐标
  let dot = getScreenOriginal();
  console.log("dot:" + dot);

  //屏幕中心点坐标
  let original = {
    x: 0,
    y: 0
  };

  original.x = two.width / 2;
  original.y = two.height / 2;

  let c = two.makeCircle(x, y, 10);
  c.fill = "red";

  let differenceValueX = (dot.x - x) * two.scene._matrix.elements[0];
  let differenceValueY = (dot.y - y) * two.scene._matrix.elements[4];
  console.log(two.scene._matrix.elements);
  console.log("差值:"+ differenceValueX + "  " + differenceValueY);

  let currentStep = 0;
  let browX = 0;
  let browY = 0;
  let time = setInterval(function(){

    //先把scale设置为最小
    if(currentStep == 0){

      if(mouse.scale <= 0.02){

        currentStep = 1;
        console.log("over1");
      }
      else{

        mouse.zoomBy(-0.05, original.x, original.y)
      }
    }

    //当界面最小时,计算x,y,在屏幕上的坐标
    if(currentStep == 1){

      browX = (x * two.scene._matrix.elements[0]) + two.scene._matrix.elements[2];
      browY = (y * two.scene._matrix.elements[4]) + two.scene._matrix.elements[5];

      console.log("note: browX:" + browX + "  browY:" + browY);
      currentStep = 2;
    }

    //慢慢放大
    if(currentStep == 2){

      if(mouse.scale >= 2){

        currentStep = 3;
      }
      else{

        mouse.zoomBy(0.05, browX, browY)
      }
    }


    if(currentStep == 3){

      console.log("over exit")
      clearInterval(time);
    }

  }, 0);


  //飞到对应x,y坐标点,这个x, y将会变成新的屏幕中心点
  //mouse.graphicMove(differenceValueX, differenceValueY);

  // originalPositionX = differenceValueX;
  // originalPositionY = differenceValueY;

}


export function waterWave(x, y) {

  let repeat = 1000;
  let radius = 1000;
  let cir = two.makeCircle(0, 0, radius);
  cir.noFill();
  cir.linewidth = 3;
  cir.stroke = "rgba(255, 255, 0, 0.5)";

  let radiusTime = setInterval(function(){

    radius -= 10;
    if(radius <= 0){

      radius = 1000;
      cir.radius = radius;
    }
    cir.radius = radius;
  }, 1);
  let time = setInterval(function(){

    if(repeat < 0){

      cir.remove();
      clearInterval(radiusTime);
      clearInterval(time);
    }


    repeat--;
  }, 0);

}

鼠标滚轮及放缩相关:

(function(Two){

  let _ = Two.Utils;

  let Surface = function(object) {

    this.object = object;

  };

  _.extend(Surface.prototype, {

    limits: function(min, max) {

      let min_exists = !_.isUndefined(min);
      let max_exists = !_.isUndefined(max);

      if (!max_exists && !min_exists) {
        return { min: this.min, max: this.max };
      }

      this.min = min_exists ? min : this.min;
      this.max = max_exists ? max : this.max;

      return this;

    },

    apply: function(px, py, s) {
      this.object.translation.set(px, py);
      this.object.scale = s;
      return this;
    }

  });

  let ZUI = Two.ZUI = function(group, domElement) {

    this.limits = {

      scale: ZUI.Limit.clone(),
      x: ZUI.Limit.clone(),
      y: ZUI.Limit.clone()
    };

    this.viewport = domElement || document.body;
    this.viewportOffset = {
      matrix: new Two.Matrix()
    };

    this.surfaceMatrix = new Two.Matrix();

    this.surfaces = [];
    this.reset();
    this.updateSurface();

    this.add(new Surface(group));

  };

  _.extend(ZUI, {

    Surface: Surface,

    Clamp: function(v, min, max) {
      return Math.min(Math.max(v, min), max);
    },

    Limit: {

      min: -Infinity,
      max: Infinity,
      clone: function() {

        let result = {};
        for (let k in this) {

          result[k] = this[k];
        }
        return result;
      }
    },

    TranslateMatrix: function(m, x, y) {

      m.elements[2] += x;
      m.elements[5] += y;
      return m;
    },

    PositionToScale: function(pos){

      return Math.exp(pos);
    },

    ScaleToPosition: function(scale){

      return Math.log(scale);
    }

  });

  _.extend(ZUI.prototype, {

    constructor: ZUI,

    add: function(surface){

      this.surfaces.push(surface);
      let limits = surface.limits();
      this.addLimits(limits.min, limits.max);
      return this;
    },

    addLimits: function(min, max, type) {

      type = type || 'scale';

      if (!_.isUndefined(min)){

        if(this.limits[type].min){

          this.limits[type].min = Math.max(min, this.limits[type].min);
        }
        else{

          this.limits[type].min = min;
        }
      }

      if(_.isUndefined(max)){

        return this;
      }

      if(this.limits[type].max){

        this.limits[type].max = Math.min(max, this.limits[type].max);
      }
      else{

        this.limits[type].max = max;
      }

      return this;

    },

    clientToSurface: function(x, y) {

      this.updateOffset();
      let m = this.surfaceMatrix.inverse();
      let n = this.viewportOffset.matrix.inverse().multiply(x, y, 1);
      return m.multiply.apply(m, _.toArray(n));
    },

    surfaceToClient: function(v) {

      this.updateOffset();
      let vo = this.viewportOffset.matrix.clone();
      let sm = this.surfaceMatrix.multiply.apply(this.surfaceMatrix, _.toArray(v));
      return vo.multiply.apply(vo, _.toArray(sm));
    },

    graphicMove: function(clientX, clientY){

      let dx = clientX;
      let dy = clientY;
      this.translateSurface(dx, dy);
      return this;
    },

    zoomBy: function(byF, clientX, clientY){

      let s = ZUI.PositionToScale(this.zoom + byF);
      this.zoomSet(s, clientX, clientY);
      return this;
    },

    zoomSet: function(zoom, clientX, clientY) {

      let newScale = this.fitToLimits(zoom);
      this.zoom = ZUI.ScaleToPosition(newScale);

      if (newScale === this.scale) {

        return this;
      }

      let sf = this.clientToSurface(clientX, clientY);
      let scaleBy = newScale / this.scale;

      this.surfaceMatrix.scale(scaleBy);
      this.scale = newScale;

      let c = this.surfaceToClient(sf);
      let dx = clientX - c.x;
      let dy = clientY - c.y;
      this.translateSurface(dx, dy);

      return this;
    },

    translateSurface: function(x, y) {

      ZUI.TranslateMatrix(this.surfaceMatrix, x, y);
      this.updateSurface();
      return this;
    },

    updateOffset: function() {

      let rect = this.viewport.getBoundingClientRect();
      _.extend(this.viewportOffset, rect);

      this.viewportOffset.left -= document.body.scrollLeft;
      this.viewportOffset.top -= document.body.scrollTop;

      this.viewportOffset.matrix
        .identity()
        .translate(this.viewportOffset.left, this.viewportOffset.top);

      return this;

    },

    updateSurface: function() {

      let e = this.surfaceMatrix.elements;
      for(let i = 0; i < this.surfaces.length; i++){

        this.surfaces[i].apply(e[2], e[5], e[0]);
      }
      return this;
    },

    reset: function() {
      this.zoom = 0;
      this.scale = 1.0;
      this.surfaceMatrix.identity();
      return this;
    },

    fitToLimits: function(s) {
      return ZUI.Clamp(s, this.limits.scale.min, this.limits.scale.max);
    }

  });

})
((typeof global !== 'undefined' ? global : (this || window)).Two);

 

©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值