外层元素旋转,其包括在内的子元素一并旋转(不改变旋转中心),单元测试

news/2025/3/15 23:26:07/

思路:外层旋转后坐标,元素旋转后坐标,计算偏移坐标
在这里插入图片描述

在这里插入图片描述

<template><div class="outbox"><label>角度: <input v-model.number="rotate" type="number" /></label><br><div class="resizebox" :style="{width: `${resize.w}px`, height: `${resize.h}px`, transform: `translate(${resize.x}px, ${resize.y}px) rotate(${rotate}deg)`}"></div><div :class="['itxm', `itxm-${idx}`]" v-for="(item, idx) in points" :key="idx" :style="{width: `${item.w}px`, height: `${item.h}px`, transform: `translate(${item.x}px, ${item.y}px) rotate(${rotate}deg)`}">{{idx+1}}</div></div>
</template>
<script>export default {name: 'HelloWorld',data() {return {rotate: 15,resize: {x: 200,y: 200,w: 500,h: 300,r: 60},points: [{x: 200,y: 200,w: 50,h: 30,r: 0},{x: 650,y: 200,w: 50,h: 30,r: 0},{x: 300,y: 300,w: 50,h: 30,r: 0},{x: 200,y: 470,w: 50,h: 30,r: 0},{x: 650,y: 470,w: 50,h: 30,r: 0}]};},watch: {rotate() {this.watchRotate();}},mounted() {this.watchRotate();},methods: {watchRotate() {const cx = this.resize.x+this.resize.w/2const cy = this.resize.y+this.resize.h/2this.points.forEach(v => {if (!v.oldx) v.oldx = v.xif (!v.oldy) v.oldy = v.y// resize旋转为矩形参考const rotateEnd = this.recaculateXY({x: v.oldx || v.x, y: v.oldy || v.y, cx, cy, rotate: this.rotate})const rotateThis = this.recaculateXY({x: v.x, y: v.y, cx: v.x+v.w/2, cy: v.y+v.h/2, rotate: this.rotate})// 外层旋转坐标偏移 - 自身旋转坐标偏移const rangex = rotateEnd.x - rotateThis.xconst rangey = rotateEnd.y - rotateThis.yv.x += rangexv.y += rangey})},recaculateXY({x, y, cx, cy, rotate}) {// 矩阵公式const rad = (rotate * Math.PI) / 180;const rotatedX = (x - cx) * Math.cos(rad) - (y - cy) * Math.sin(rad) + cxconst rotatedY = (x - cx) * Math.sin(rad) + (y - cy) * Math.cos(rad) + cyreturn {x: rotatedX, y: rotatedY}},},
};
</script><style scoped>
.outbox {position: relative;
}
.resizebox {width: 500px;height: 300px;border: 1px dotted blue;position: absolute;left: 0;top: 0;&::after {content: '';width: 100%;height: 1px;background: red;display: block;position: absolute;top: 50%;}&::before {content: '';width: 1px;height: 100%;background: red;display: block;position: absolute;left: 50%;}
}
.itxm {background: green;position: absolute;left: 0;top: 0;
}
.itxm-1 {background: orange;
}
.itxm-2 {background: rebeccapurple;
}
</style>

–end


http://www.ppmy.cn/news/1579424.html

相关文章

Linux驱动开发实战(五):Qt应用程序点RGB灯(保姆级快速入门!)

Linux驱动开发实战&#xff08;五&#xff09;&#xff1a;Qt应用程序点RGB灯&#xff08;保姆级快速入门&#xff01;&#xff09; 文章目录 Linux驱动开发实战&#xff08;五&#xff09;&#xff1a;Qt应用程序点RGB灯&#xff08;保姆级快速入门&#xff01;&#xff09;前…

Oracle中In和Exists区别分析

在Oracle中&#xff0c;IN和EXISTS都是用于子查询的条件判断&#xff0c;但它们在执行逻辑、性能和应用场景上有显著区别。以下是两者的主要差异&#xff1a; 1.执行机制 IN IN 先执行子查询&#xff0c;将子查询的结果集缓存到内存中&#xff0c;生成一个静态列表。 主查询的…

本地化语音识别CapsWriter结合内网穿透远程会议录音秒变文字稿

文章目录 前言1. 软件与模型下载2. 本地使用测试3. 异地远程使用3.1 内网穿透工具下载安装3.2 配置公网地址3.3 修改config文件3.4 异地远程访问服务端 4. 配置固定公网地址4.1 修改config文件 5. 固定tcp公网地址远程访问服务端 前言 今天我要给大家推荐一个绝对能让你 produ…

【Javascript网页设计】个人简历网页案例

代码如下: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>个人简历 - 张三…

文件系统 linux ─── 第19课

前面博客讲解的是内存级文件管理,接下来介绍磁盘级文件管理 文件系统分为两部分 内存级文件系统 : OS加载进程 ,进程打开文件, OS为文件创建struct file 和文件描述符表 ,将进程与打开的文件相连, struct file 内还函数有指针表, 屏蔽了底层操作的差异,struct file中还有内核级…

Unity中WolrdSpace下的UI展示在上层

一、问题描述 Unity 中 Canvas使用World Space布局的UI&#xff0c;想让它不被3d物体遮挡&#xff0c;始终显示在上层。 二、解决方案 使用shader解决 在 UI 的材质中禁用深度测试&#xff08;ZTest&#xff09;&#xff0c;强制 UI 始终渲染在最上层。 Shader "Custo…

《第六章 终章》在VMware中进行UR10e机器人的手眼标定实验全过程(ur10e手眼标定实验实机演示)

第六章&#xff1a;在VMware中进行UR10e机器人的手眼标定实验全过程 本实验需要用到的硬件设备&#xff1a; ur10e机器人 (其他型号)、windows电脑、Intel RealSense D455 深度相机 (其他型号) 网线、usb数据线&#xff08;用来连接安卓手机&#xff09;、usb3.0数据线&…

uniapp+Vue3 组件之间的传值方法

一、父子传值&#xff08;props / $emit 、ref / $refs&#xff09; 1、props / $emit 父组件通过 props 向子组件传递数据&#xff0c;子组件通过 $emit 触发事件向父组件传递数据。 父组件&#xff1a; // 父组件中<template><view class"container">…