Vue

Experimento para girar um elemento no seu próprio eixo

by Dian Carlos Cabral dos Santos

HTML

<div id="app" v-on:mousemove="transformMove($event)" v-on:mouseup="endTransform()" :style="{

    backgroundImage: `

    linear-gradient(to right, transparent 0, transparent 29px, rgba(0, 0, 0, .2) 30px, rgba(0, 0, 0, .2) 30px),
    linear-gradient(to bottom, transparent 0, transparent 29px, rgba(0, 0, 0, .2) 30px, rgba(0, 0, 0, .05) 30px)

    `,
    'background-size': `30px 100%, 100% 30px, 30px 100%, 100% 30px`,
    'background-repeat' : `repeat-x, repeat-y, repeat-x, repeat-y`

}">

  <span style="position: absolute; width: 300px; top: 15px; left: 15px;">{{ transform }}</span>

  <div class="box" :style="{
    
      transform: `translate3d(${x}px, ${y}px, 0) rotate(${rotate}deg)`

  }" v-on:mousedown="startDrag($event)" >
  
    ME MOVA!
    
    <p>x {{ x }}</p>
    <p>y {{ y }}</p>
    <p>deg {{ rotate }}</p>
    
    <div class="box__rotate" v-on:mousedown.stop="startRotate($event)">girar</div>
    
   </div>
  

</div>

SCSS

body {
  margin: 0;
  user-select: none
}

#app {
    
    position: fixed;
    
    top: 0;
    left: 0;
    
    width: 100%;
    height: 100%;
  
}

.box {
  
    position: fixed;
    
    width: 300px;
    height: 100px;
    
    background: #3399ff;
    
    border-radius: 6px;
    
    cursor: move;
    
    &__rotate {
      
        $size: 14px;
        
        position: absolute;
        
        top: -$size;
        right: -$size;
        
        width: $size;
        height: $size;
        
        background: red;
        
        border-radius: $size;
      
    }
  
}

Vue

new Vue({
  el: "#app",
  data: {
    x : 0,
    y : 0,
    rotate: 0, // final rotate
    transform : {
    	
      active : false,
      type: null,
      x: 0,
      y: 0,
      clientX: 0,
      clientY: 0,
      left: 0,
      top: 0,
      width: 0,
      height: 0,
      angle : 0,
      rotation: 0,
      startAngle : 0
    
    }
    
  },
  
  filters: {
    pretty: function(value) {
      return JSON.stringify(JSON.parse(value), null, 4)
    }
  },
  
  methods: {
  
  	startDrag(e){
    	
      this.transform = {
      	
        ...this.transform,
        active: true,
        type: 'move',
        x : JSON.parse(JSON.stringify(this.x)),
        y: JSON.parse(JSON.stringify(this.y)),
        clientX: e.clientX,
        clientY: e.clientY
      
      }
    
    },
    
    startRotate(e){
    
    	let { left, top, width, height } = e.target.closest('.box').getBoundingClientRect()
    	
      this.transform = {
      	
        ...this.transform,
        active: true,
        type: 'rotate',
        left,
        top,
        width,
        height,
        angle : this.rotate
      
      }
      
      let x = left + (width / 2)
			let y = top + (height / 2)
          
      this.transform.startAngle = Math.atan2(e.clientY - y, e.clientX - x) * (180 / Math.PI)
    
    },
    
    endTransform(){
    	
      	this.transform = {
    	
        active : false,
        type: null,
        x: 0,
        y: 0,
        clientX: 0,
        clientY: 0,
        left: 0,
        top: 0,
        width: 0,
        height: 0,
        angle : 0,
        rotation: 0,
        startAngle : 0

      }
    
    },
    
    transformMove(e){
    	
      if(this.transform.active){
      	
        if(this.transform.type === 'move'){

          this.x = Math.ceil((this.transform.x + (e.clientX - this.transform.clientX)) / 30) * 30
          this.y = Math.ceil((this.transform.y + (e.clientY - this.transform.clientY)) / 30) * 30
          
       	} if(this.transform.type ===...