Я начинающий веб-разработчик из Японии.
Я плохо говорю по-английски, извините.
Я сделал образец кода, который вы можете перемещать или изменять размер прямоугольника.
Я использую vue.js и svg.
<template>
<div class = "rotate-area">
<div class = "rotate">
<svg width = "608" height = "408" viewBox = "0 0 608 408" xmlns = "http://www.w3.org/2000/svg" class = "svg" ref = "svg" @mousemove = "mouseMove" @mouseup = "mouseUp">
<g stroke-width = "1" fill = "#ffffff" fill-rule = "evenodd" fill-opacity = "0" stroke = "#000000" class = "layer" :transform = "rotate">
<g fill-opacity = "1">
<rect stroke-width = "2" fill-opacity = "0" :x = "masterX" :y = "masterY" :width = "width" :height = "height" @mousedown.self = "select($event , 'master')"></rect>
<rect fill = "#ffffff" :x = "leftTopX" :y = "leftTopY" width = "7" height = "7" @mousedown.self = "select($event , 'leftTop')"></rect>
<rect fill = "#ffffff" :x = "rightTopX" :y = "rightTopY" width = "7" height = "7" @mousedown.self = "select($event , 'rightTop')"></rect>
<rect fill = "#ffffff" :x = "rightBottomX" :y = "rightBottomY" width = "7" height = "7" @mousedown.self = "select($event , 'rightBottom')"></rect>
<rect fill = "#ffffff" :x = "leftBottomX" :y = "leftBottomY" width = "7" height = "7" @mousedown.self = "select($event , 'leftBottom')"></rect>
</g>
</g>
</svg>
</div>
<input type = "number" v-model = "angle">
</div>
</template>
<script lang = "ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component({
components: {}
})
export default class Rotate extends Vue {
width = 150
widthBefore = 150
height = 150
heightBefore = 150
masterX = 24
masterXBefore = 24
masterY = 25
masterYBefore = 25
leftTopX = 20.5
leftTopXBefore = 20.5
leftTopY = 20.5
leftTopYBefore = 20.5
rightTopX = 170.5
rightTopXBefore = 170.5
rightTopY = 20.5
rightTopYBefore = 20.5
rightBottomX = 170.5
rightBottomXBefore = 170.5
rightBottomY = 172.5
rightBottomYBefore = 172.5
leftBottomX = 20.5
leftBottomXBefore = 20.5
leftBottomY = 172.5
leftBottomYBefore = 172.5
angle = 0
mouseDownState = false
mouseDownType = ""
pointStart = {
x: 0,
y : 0
}
get middleVector() {
return {
x : (this.leftTopX + this.rightTopX) / 2 ,
y : (this.leftTopY + this.leftBottomY) / 2
}
}
get rotate() {
return "rotate(" + this.angle + "," + this.middleVector.x + "," + this.middleVector.y + ")";
}
public select(event : MouseEvent , mouseDownType){
this.mouseDownState = true
this.mouseDownType = mouseDownType
this.pointStart.x = event.clientX
this.pointStart.y = event.clientY
}
public mouseMove(event : MouseEvent){
if (this.mouseDownState){
let moveDistance = {
x : event.clientX - this.pointStart.x,
y : event.clientY - this.pointStart.y
}
if (this.mouseDownType= = "master"){
this.masterX = this.masterXBefore + moveDistance.x
this.masterY = this.masterYBefore + moveDistance.y
this.leftTopX = this.leftTopXBefore + moveDistance.x
this.leftTopY = this.leftTopYBefore + moveDistance.y
this.rightTopX = this.rightTopXBefore + moveDistance.x
this.rightTopY = this.rightTopYBefore + moveDistance.y
this.rightBottomX = this.rightBottomXBefore + moveDistance.x
this.rightBottomY = this.rightBottomYBefore + moveDistance.y
this.leftBottomX = this.leftBottomXBefore + moveDistance.x
this.leftBottomY = this.leftBottomYBefore + moveDistance.y
}else if (this.mouseDownType == "leftTop") {
this.masterX = this.masterXBefore + moveDistance.x
this.masterY = this.masterYBefore + moveDistance.y
this.leftTopX = this.leftTopXBefore + moveDistance.x
this.leftTopY = this.leftTopYBefore + moveDistance.y
this.rightTopY = this.rightTopYBefore + moveDistance.y
this.leftBottomX = this.leftBottomXBefore + moveDistance.x
this.width = this.widthBefore - moveDistance.x
this.height = this.heightBefore - moveDistance.y
} else if (this.mouseDownType == "rightTop") {
this.masterY = this.masterYBefore + moveDistance.y
this.leftTopY = this.leftTopYBefore + moveDistance.y
this.rightTopX = this.rightTopXBefore + moveDistance.x
this.rightTopY = this.rightTopYBefore + moveDistance.y
this.rightBottomX = this.rightBottomXBefore + moveDistance.x
this.width = this.widthBefore + moveDistance.x
this.height = this.heightBefore - moveDistance.y
} else if (this.mouseDownType == "rightBottom") {
this.rightTopX = this.rightTopXBefore + moveDistance.x
this.rightBottomX = this.rightBottomXBefore + moveDistance.x
this.rightBottomY = this.rightBottomYBefore + moveDistance.y
this.leftBottomY = this.leftBottomYBefore + moveDistance.y
this.width = this.widthBefore + moveDistance.x
this.height = this.heightBefore + moveDistance.y
} else if (this.mouseDownType == "leftBottom") {
this.masterX = this.masterXBefore + moveDistance.x
this.leftTopX = this.leftTopXBefore + moveDistance.x
this.rightBottomY = this.rightBottomYBefore + moveDistance.y
this.leftBottomX = this.leftBottomXBefore + moveDistance.x
this.leftBottomY = this.leftBottomYBefore + moveDistance.y
this.width = this.widthBefore - moveDistance.x
this.height = this.heightBefore + moveDistance.y
}
}
}
mouseUp(){
this.mouseDownState = false
if (this.mouseDownType= = "master"){
this.masterXBefore = this.masterX
this.masterYBefore = this.masterY
this.leftTopXBefore = this.leftTopX
this.leftTopYBefore = this.leftTopY
this.rightTopXBefore = this.rightTopX
this.rightTopYBefore = this.rightTopY
this.rightBottomXBefore = this.rightBottomX
this.rightBottomYBefore = this.rightBottomY
this.leftBottomXBefore = this.leftBottomX
this.leftBottomYBefore = this.leftBottomY
}else if (this.mouseDownType == "leftTop") {
this.masterXBefore = this.masterX
this.masterYBefore = this.masterY
this.leftTopXBefore = this.leftTopX
this.leftTopYBefore = this.leftTopY
this.rightTopYBefore = this.rightTopY
this.leftBottomXBefore = this.leftBottomX
this.widthBefore = this.width
this.heightBefore = this.height
}else if (this.mouseDownType == "rightTop") {
this.masterYBefore = this.masterY
this.leftTopYBefore = this.leftTopY
this.rightTopXBefore = this.rightTopX
this.rightTopYBefore = this.rightTopY
this.rightBottomXBefore = this.rightBottomX
this.widthBefore = this.width
this.heightBefore = this.height
}else if (this.mouseDownType == "rightBottom") {
this.rightTopXBefore = this.rightTopX
this.rightBottomXBefore = this.rightBottomX
this.rightBottomYBefore = this.rightBottomY
this.leftBottomYBefore = this.leftBottomY
this.widthBefore = this.width
this.heightBefore = this.height
}else if (this.mouseDownType == "leftBottom"){
this.masterXBefore = this.masterX
this.leftTopXBefore = this.leftTopX
this.rightBottomYBefore = this.rightBottomY
this.leftBottomXBefore = this.leftBottomX
this.leftBottomYBefore = this.leftBottomY
this.widthBefore = this.width
this.heightBefore = this.height
}
}
}
</script>
<style lang = "scss">
</style>
Извините, что этот код не стильный и его трудно читать.
У меня здесь проблема.
Когда вы изменяете размер после поворота, захватываемая кромка и перемещение курсора не совпадают.
Когда угол равен 0, он работает правильно.
Я хочу, чтобы кромка всегда следовала за курсором.
Я думал, что мне нужно инвертировать матрицу вращения.
public mouseMove(event : MouseEvent){
if (this.mouseDownState){
let moveDistance = {
x : event.clientX - this.pointStart.x,
y : event.clientY - this.pointStart.y
}
moveDistance.x = Math.cos(this.angle) * (moveDistance.x - this.middleVector.x) + Math.sin(this.angle) * (moveDistance.y - this.middleVector.y) + this.middleVector.x
moveDistance.y = ***
Должен ли я сделать что-то подобное?
Хотя я плохо разбираюсь в математике.
Кто-нибудь, помогите мне, пожалуйста !!! (> ___ <)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Верно ли, что ваша программа вращает / изменяет размер прямоугольника, когда пользователь нажимает на один из углов и перемещает мышь? Логика должна быть примерно такой:
var centerX = ______; //whatever the center of the rect is
var centerY = ______; //whatever the center of the rect is
var rectangleWidth = ________; //initial width of rectangle;
var rectangleHeight = ________; //initial height of rectangle;
var scale = 1; //scale of shown image to original
var rectangleRotation = 0; //initally no rotation
var clickX;
var clickY;
var rotationOfRectangleWhenClicked //rotation of the rectangle at the time it is clicked
var clickScale; //scale of rectangle when clicked
var clickRotation; //angle of mouse to the rectangle's center
var clickDistance; //distance of mouse to center of rectangle
function mouseDown(mouseEvent) {
//sets variables when a corner gets clicked
clickX = mouseEvent.clientX;
clickY = mouseEvent.clientY;
rotationOfRectangleWhenClicked = rectangleRotzation;
clickRotation = Math.atan(clickY / clickX);
clickDistance = Math.sqrt((clickX - centerX) ** 2 + (clickY - centerY) ** 2)
clickScale = scale;
}
function moveMouse(mouseEvent) {
//run when you move the mouse after clicking on a corner
//does the logic of resizing and rotation
//resize
var ratioToResize = Math.sqrt(((mouseEvent.clientX - centerX) ** 2 + (mouseEvent.clientY - centerY) ** 2)) / clickDistance
scale = ratioToResize * clickScale;
//rotation
var angle = Math.atan((mouseEvent.clientY - centerY) / (mouseEvent.clientX - centerX))
rectangleRotation = rotationOfRectangleWhenClicked + angle - clickRotation;
}
function mouseUp(mouseEvent) {
}Вот программа для создания движущегося прямоугольника:
<!DOCTYPE html>
<html>
<head>
<script src = "math.js" type = "text/javascript"></script>
</head>
<body>
It's a moving rectangle!
<div id = "rectangle" style = "background-color:#ff0000; position:absolute; width: 100px; height: 100px; top:100px; left: 100px">
</div>
<script type = "text/javascript">
mousePressed=false;
centerX = 400; //whatever the center of the rect is
centerY = 300; //whatever the center of the rect is
rectangleWidth = 400; //initial width of rectangle;
rectangleHeight = 300; //initial height of rectangle;
rectangleRotation = 0; //initally no rotation
rectangle = document.getElementById("rectangle");
rectangle.style.top = (centerY-rectangleHeight/2)+'px';
rectangle.style.left = (centerX-rectangleWidth/2)+'px';
rectangle.style.width = rectangleWidth+'px';
rectangle.style.height = rectangleHeight+'px';
rectangle.style.transform = 'rotate('+rectangleRotation*180/Math.PI+'deg)';
rectangle.onmousedown = mouseDown;
document.onmouseup = mouseUp;
document.onmousemove = moveMouse;
clickX;
clickY;
rotationOfRectangleWhenClicked; //rotation of the rectangle at the time it is clicked
clickWidth; //width of rectangle when clicked
clickHeight; //height of rectangle when clicked
clickRotation; //angle of mouse to the rectangle's center
clickDistance; //distance of mouse to center of rectangle
function mouseDown(mouseEvent) {
//sets variables when a corner gets clicked
mousePressed=true;
rectangle.style.backgroundColor = '#0000ff';
clickX=mouseEvent.clientX;
clickY=mouseEvent.clientY;
rotationOfRectangleWhenClicked = rectangleRotation;
clickRotation = Math.atan2((mouseEvent.clientY-centerY),(mouseEvent.clientX-centerX))
clickDistance = Math.sqrt((clickX-centerX)**2 + (clickY-centerY)**2);
clickWidth = rectangleWidth;
clickHeight = rectangleHeight;
}
function moveMouse(mouseEvent) {
if (!mousePressed) {
return 0;}
//run when you move the mouse after clicking on a corner
//does the logic of resizing and rotation
rectangle.style.backgroundColor = "#00ff00";
//resize
var ratioToResize = Math.sqrt(((mouseEvent.clientX-centerX)**2 + (mouseEvent.clientY-centerY)**2))/clickDistance
rectangleWidth = ratioToResize*clickWidth;
rectangleHeight = ratioToResize*clickHeight;
//rotation
var angle = Math.atan2((mouseEvent.clientY-centerY),(mouseEvent.clientX-centerX))
rectangleRotation = rotationOfRectangleWhenClicked + angle - clickRotation;
rectangle.style.top = (centerY-rectangleHeight/2)+'px';
rectangle.style.left = (centerX-rectangleWidth/2)+'px';
rectangle.style.width = rectangleWidth+'px';
rectangle.style.height = rectangleHeight+'px';
rectangle.style.transform = 'rotate('+rectangleRotation*180/Math.PI+'deg)';
}
function mouseUp(mouseEvent) {
mousePressed=false;
rectangle.style.backgroundColor = '#ff0000';
}
</script>
</body>
</html>Спасибо. В моем коде ротация происходит только тогда, когда вы вводите число в тег ввода внизу.
Это отличный код, спасибо вам большое. Но я хочу переместить весь прямоугольник, который является «основным» шаблоном в моем коде. И я хочу, чтобы диагональ края не двигалась при изменении размера. Например, когда вы изменили его размер, потянув leftTop, положение rightBottom не должно измениться.
Но очень хорошая идея. Большое спасибо. Я могу перевести свой код.
Спасибо за отличный ответ, но у меня другая проблема, если можете, проверьте мой новый вопрос. stackoverflow.com/questions/52176195/…
Доброе утро!!! Мне очень жаль, что мой ответ запоздал. Я спал. Я проверю ответ после того, как приеду свою работу. Спасибо, гадость!