{wcademy}

Drag-and-drop элементов в PixJS

June 09, 2020

D'n'd круга с pixi.js

Недавно мы с вами знакомились с PixiJS, может продолжим? Сегодня давайте сделаем пример, в котором мы немного оживим получаемую картинку, научившись перетаскивать элементы.

Про первоначальную установку повторять не буду, все было в прошлой статье (да, еще раз ссылка, для тех, кто пропустил ее в первом абзаце).

Давай начнем сразу с редактирования, еще пустого main.ts

  1. Привычно создаем рендерер и добавляем канвас на страницу:
import * as PIXI from 'pixi.js'

const renderer = PIXI.autoDetectRenderer({
  height: window.innerHeight,
  width: window.innerWidth,
  transparent: true,
  antialias: true,
})

document.body.appendChild(renderer.view)
  1. Создаем сцену. Ключевое отличие - флаг interactive. Это говорит pixi начать обрабатывать пользовательские события.
const stage = new PIXI.Container()
stage.interactive = true
  1. Нарисуем круг, зальем его красным цветов и тоже сделаем интерактивным:
const circle = new PIXI.Graphics()
// ему тоже нужен флаг интерактивности
circle.interactive = true
circle.beginFill(0xff0000)
circle.drawCircle(0, 0, 30)
circle.x = renderer.width / 2
circle.y = renderer.height / 2
circle.endFill()

stage.addChild(circle)
  1. Добавим к кругу обработку событий, как для мыши, так и для устройств с тач-скрином. По их названиям вполне понятно, для чего они предназначены, так что без дополнительных комментариев.
circle
  .on('mousedown', onDragStart)
  .on('touchstart', onDragStart)
  .on('mouseup', onDragEnd)
  .on('mouseupoutside', onDragEnd)
  .on('touchend', onDragEnd)
  .on('touchendoutside', onDragEnd)
  .on('mousemove', onDragMove)
  .on('touchmove', onDragMove)
  1. Реализуем обработчики:
function onDragStart(e) {
  // сохраняем данные из события
  this.data = e.data
  // во время переноса сделаем элемент полпрозрачным
  this.alpha = 0.5
  // и поставим флаг, что этот элемент сейчас тащат
  this.dragging = true
}

function onDragEnd(e) {
  // просто обнуляем все, что установили в onDragStart
  this.data = null
  this.alpha = 1
  this.dragging = false
}

function onDragMove(e) {
  // если флаг не установлен, то
  // мы просто провели мышью наж элементов - игнорируем
  if (!this.dragging) {
    return
  }

  // получаем координаты мыши и изменяем координаты круга на них
  const newPosition = this.data.getLocalPosition(this.parent)
  this.position.x = newPosition.x
  this.position.y = newPosition.y
}
  1. И рисуем все на канвасе, заодно прося браузер перерисовывать изображение каждый кадр:
const main = () => {
  // отрисовываем
  renderer.render(stage)
  // и просим браузер вызвать этот же main,
  // когда он будет готов орисовать следующий кадр
  requestAnimationFrame(main)
}

main()

Все, всем спасибо, полный пример на нашем гитхабе.

🚀  Если узнал из статьи что-то полезное, ставь лайк и подписывайся на наш канал в Телеграм или группу ВК. Обсудить статью можно в нашем уютном чатике 😏

© 2019 - 2022, {wcademy}