Как vue+canvas реализует симпатичный интерфейс входа в систему на станции b

внешний интерфейс SVG Vue.js Canvas
Как vue+canvas реализует симпатичный интерфейс входа в систему на станции b

Когда я увидел страницу логина медведя в Наггетс, она многим понравилась, поэтому я без зазрения совести сказал, что буду использовать канвас для ее реализации, я действительно поставил себе флаг, но результат был плохой.

Уважаемые зрители, возможно, это самая мрачная демонстрация, которую вы когда-либо видели, надеюсь, она вам не понравится.

Сначала посмотрите на рендеры других людей

думать

  1. Почему медвежонок двигается при вводе в поле ввода.
  2. Почему медвежьи уши сдвигаются вперед
  3. Какова схема движения медведя

Сделайте некоторое логическое мышление и исключение

  1. 2d
  2. 3d
  3. Определите координаты фокуса текстового поля, чтобы обеспечить поддержку данных для вращения медведя и других действий.

Векторный класс, реализующий 3D

var eyeLength = 250, centerX = 200/ 2, centerY = 200 / 2;
//设定视距,中心点的坐标

  function Vector3(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
    this._get2d = function() {
    //将空间左边进行缩放后生成平面视图中的坐标
      var scale = eyeLength / (eyeLength + this.z);
      var x = centerX + this.x * scale;
      var y = centerY + this.y * scale;
      return { x: x, 
              y: y };
    }
  }

Вращение объекта в пространстве

function rotateX(vec3,angleX) {
    var cos = Math.cos(angleX);
    var sin = Math.sin(angleX);
 
      var y1 = vec3.y * cos - vec3.z * sin;
      var z1 = vec3.z * cos + vec3.y * sin;
      vec3.y = y1;
      vec3.z = z1;

  }

  function rotateY(vec3,angleY) {
    var cos = Math.cos(angleY);
    var sin = Math.sin(angleY);

      var x1 = vec3.x * cos - vec3.z * sin;
      var z1 = vec3.z * cos + vec3.x * sin;
      vec3.x = x1;
      vec3.z = z1;
  }

Путем ввода значения вектора и угла выполняется расчет для генерации координат после поворота координат в пространстве.Используемая здесь формула расчета представляет собой матрицу поворота, и матрица не выделяется в отдельный класс.

класс формы

Те, кто читал предыдущее объяснение 2d-вектора, знают, что когда мы используем векторы для обработки, нам нужно обрабатывать каждую точку вектора, поэтому мы не можем напрямую использовать такие какfillRectи т. д., здесь я использую кривые Безье для построения графика.

function shape(option) {
	this.points=[];
	this.site=new Vector3(0,0,0);
	this.create(option);
	this.face=[];
	this.ctx={};
}
shape.prototype.render = function(ctx) {
	this.ctx=ctx;
    for(let f =0;f<this.paths.length;f++){
    	this.face[f]=new Face(this.ctx,this.color,...this.paths[f]);
    }
    this.face.sort(function(a,b){
    	return a-b;
    })
    this.face.forEach( function(face, index) {
    	face.draw(ctx);
    });
  }

Мы создаем поверхность, захватывая вектор в путях, а затем используем поверхность для формирования объекта и перестраиваем поверхность в той же форме, чтобы поверхность можно было нарисовать в соответствии сz(深度)Для рендера произвести эффект окклюзии.

Таким образом, мы сможем создать форму следующим образом

var face=new shape({
		paths:[[new Vector3(-50,0,4),new Vector3(-50,-70,4),new Vector3(50,-70,4),new Vector3(50,0,4)]],
		color:"#3366C"
	})
	var eyes=new shape({
		paths:[[new Vector3(-54,0,6),new Vector3(-54,-8,6),new Vector3(-46,-4,6),new Vector3(-46,0,6)],
		[new Vector3(-54,0,6),new Vector3(-54,8,6),new Vector3(-46,4,6),new Vector3(-46,0,6)]],
		color:"white"
	})

Самый быстрый способ сделать такой рисунок — сначала нарисовать координаты на бумаге, а затем реализовать их в коде.

После того, как рисунок и преобразование реализованы, следующим шагом будет взаимодействие.Здесь я использую vue для записи страницы, которая рассчитывается путем отслеживания длины текста в поле ввода (длина текста * размер шрифта) + левое поле = координата фокуса .

var vm=new Vue({
		el:'#bod',
		data:{
			username:"",//记录输入框
			left:0,//距离左边的长度,用于判断旋转何时结束
			len:0,//焦点坐标
			pos:0,//是否开始选择
			dir:'left'//旋转的方向
		},
		computed:{
		//计算文本长度
			roate:function (argument) {
				this.len=this.username.length;
			}
		},
		watch:{
		//监听len的值,判断是增还是减
			len:function(o,n){
				this.pos=1;
				if(n<o){
					this.dir='right';
				}else {
					this.dir='left'
				}
			}
		}
	})

Затем мы можем передать все браузеру

function anima(){
		if(vm.pos===1){//如果可以旋转
			if(vm.left<r){//如果长度不够,继续旋转
				ctx.clearRect(0,0,200,200);
				switch (vm.dir) {//判断方向
					case 'right':
						face.rotate(0,r);
						eyes.rotate(0,r);
						face.render(ctx);
						eyes.render(ctx);
						vm.left+=r/5;
						break;
					case 'left':
						face.rotate(0,-r);
						eyes.rotate(0,-r);
						face.render(ctx);
						eyes.render(ctx);
						vm.left+=r/5;
						break;
				}
			}else{//长度达到后则重置数据
				vm.left=0;
				vm.pos=0;
			}
		}
		requestAnimationFrame(anima)
	}
	anima();

недостаточный

  1. Картина немного некрасивая, не очень понятно, что такое чувство
  2. Для одного объекта выполняется только рендеринг глубины, а рендеринг пространственной глубины не реализован.
  3. Функции векторов и форм не идеальны, что делает эффект очень ограниченным.

Вот так это выглядит без ввода.Для контраста я сказал,что угол поворота увеличен.

Исходный код находится здесь:исходный код

Суммировать

На самом деле это не просто сделать.Когда я использовал PS или AE для анимации, я думал только о том, как бы приукрасить эффект.После того, как я это понял, я почувствовал, что группа людей в графическом движке была действительно потрясающей. С самого начала я планировал сделать его простым. , На это ушло почти полдня, я пропихнул много идей в середину, а потом разобрался. Хотя конечный эффект не очень, но я все равно беззастенчиво надеюсь, что я смогу соблазнить некоторых больших парней присоединиться к команде холста и вместе написать интересные истории.

Время от времени обновляйте технические руководства, связанные с холстом и svg, включая фактический тип боя и тип основного принципа, включая 2d, 2.5d и 3d, а также включают базовые знания линейной алгебры, физики, графики и т. д.

Приглашаем гостей собрать и обратить внимание