1
0
Fork 0

添加后台区域标记大屏位置功能

develop
vine_liutk 2023-08-01 19:33:36 +08:00
parent bdc88db320
commit 5fde7566f4
6 changed files with 213 additions and 2 deletions

View File

@ -10,8 +10,9 @@ use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\RegionService;
use Slowlyo\OwlAdmin\Renderers\Button;
use App\Admin\Components;
use App\Models\Device;
use App\Models\MonitorMode;
use App\Models\Region;
use Illuminate\Http\Request;
class RegionController extends AdminController
{
@ -50,7 +51,9 @@ class RegionController extends AdminController
amisMake()->Operation()->label(__('admin.actions'))->buttons([
$this->showRegion(),
$this->rowEditButton(true, 'lg'),
$this->rowDeleteButton()
$this->rowDeleteButton(),
amisMake()->Button()->label('设置大屏位置')->level('link')->actionType('url')->blank(true)
->url(url('/regions-position').'/'.'${id}')
]),
]);
@ -93,4 +96,32 @@ class RegionController extends AdminController
])->size('full')->actions([])
);
}
public function setRegionPosition($id, Request $request){
$region = Region::find($id);
$x = $region?->position_x ?? 0;
$y = $region?->position_y ?? 0;
return view('region-position', compact('id', 'x', 'y'));
}
public function saveRegionPosition(Request $request)
{
$id = $request->input('id', 0);
$positionX = $request->input('x', 0);
$positionY = $request->input('y', 0);
$region = Region::find($id);
if(!$region){
return response()->json(['code'=>1, 'msg'=> '非法请求']);
}
if($positionX <= 0 || $positionY <= 0){
return response()->json(['code'=>2, 'msg'=>'请点击地图,标记位置']);
}
$region->update([
'position_x'=> $positionX,
'position_y'=> $positionY
]);
//直接关闭窗口
echo '<script>window.opener=null;window.close();</script>';
return ;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 MiB

1
public/admin/js/uuidv4.min.js vendored 100644
View File

@ -0,0 +1 @@
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).uuidv4=e()}(this,(function(){"use strict";var t,e=new Uint8Array(16);function o(){if(!t&&!(t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return t(e)}var n=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function r(t){return"string"==typeof t&&n.test(t)}for(var i=[],u=0;u<256;++u)i.push((u+256).toString(16).substr(1));return function(t,e,n){var u=(t=t||{}).random||(t.rng||o)();if(u[6]=15&u[6]|64,u[8]=63&u[8]|128,e){n=n||0;for(var f=0;f<16;++f)e[n+f]=u[f];return e}return function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=(i[t[e+0]]+i[t[e+1]]+i[t[e+2]]+i[t[e+3]]+"-"+i[t[e+4]]+i[t[e+5]]+"-"+i[t[e+6]]+i[t[e+7]]+"-"+i[t[e+8]]+i[t[e+9]]+"-"+i[t[e+10]]+i[t[e+11]]+i[t[e+12]]+i[t[e+13]]+i[t[e+14]]+i[t[e+15]]).toLowerCase();if(!r(o))throw TypeError("Stringified UUID is invalid");return o}(u)}}));

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,176 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>在地图上打标点</title>
<style>
/* html,body{
width: 100%;
height: 100%;
} */
canvas {
cursor: crosshair;
width:1350px;
height: 900px;
}
</style>
<script src="{{asset('/admin/js/uuidv4.min.js')}}"></script>
</head>
<body>
<canvas id="myCanvas"></canvas>
<div style="position: relative;top:-900px;left: 1360px;width: 100px;">
<form id='positionForm' action="{{url('regions-position/save')}}" method="post" enctype="multipart/form-data">
@csrf
<input type="hidden" name="id" value="{{$id}}">
<input type="hidden" name="x" id="x" value="{{$x}}">
<input type="hidden" name="y" id="y" value="{{$y}}">
<button type="submit" onclick="return submitXY(this.form)">保存</button>
<button onclick="script:window.close();">返回</button>
</form>
</div>
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const sx = '{{$x}}';
const sy = '{{$y}}';
const map = new Image();
map.src = "/admin/dashboard-map.png";
map.onload = function () {
resizeCanvas();
drawMarkers();
};
const markerImage = new Image();
markerImage.src = "/admin/map-marker.png";
const markerRadius = 15;
const markers = [];
if(sx >0 && sy >0) {
markers.push({id: uuidv4(),
x:sx,
y:sy,
selected: false});
}
function addMarker(x, y) {
const marker = {
id: uuidv4(),
x,
y,
selected: false
};
markers.length = 0;
markers.push(marker);
document.getElementById("x").value = x;
document.getElementById("y").value = y;
console.log("新增", marker);
drawMarkers();
}
function drawMarkers() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 获取父容器的宽度和高度
const canvasWrapper = document.getElementById("myCanvas");
const canvasWrapperWidth = canvasWrapper.offsetWidth;
const canvasWrapperHeight = canvasWrapper.offsetHeight;
// 设置Canvas的大小为父容器的大小
canvas.width = canvasWrapperWidth;
canvas.height = canvasWrapperHeight;
// 绘制地图图片并调整大小以铺满Canvas
const scale = Math.max(canvas.width / map.width, canvas.height / map.height);
const newWidth = map.width * scale;
const newHeight = map.height * scale;
const offsetX = (canvas.width - newWidth) / 2;
const offsetY = (canvas.height - newHeight) / 2;
ctx.drawImage(map, offsetX, offsetY, newWidth, newHeight);
markers.forEach(marker => {
// if (marker.selected) {
// ctx.beginPath();
// ctx.arc(marker.x, marker.y, 15, 0, 8 * Math.PI);
// ctx.strokeStyle = "red";
// ctx.stroke();
// }
ctx.drawImage(markerImage, marker.x - markerRadius, marker.y - markerRadius, markerRadius * 2, markerRadius * 2);
});
}
function resizeCanvas() {//初始化地图
drawMarkers();
}
window.addEventListener("resize", resizeCanvas);
let isDragging = false;
let dragIndex = -1;
canvas.addEventListener("mousedown", event => {
const x = event.offsetX;
const y = event.offsetY;
markers.forEach((marker, index) => {
if (x >= marker.x - markerRadius / 2 && x <= marker.x + markerRadius / 2 && y >= marker.y - markerRadius / 2 && y <= marker.y + markerRadius / 2) {
isDragging = true;
dragIndex = index;
markers[index].selected = true;
} else {
markers[index].selected = false;
}
});
if (!isDragging) {
addMarker(x, y);
}
drawMarkers();
});
canvas.addEventListener("mousemove", event => {
if (isDragging) {
const x = event.offsetX;
const y = event.offsetY;
markers[dragIndex].x = x;
markers[dragIndex].y = y;
drawMarkers();
}
});
canvas.addEventListener("mouseup", event => {
isDragging = false;
dragIndex = -1;
});
function submitXY(theform)
{
var ttx = document.getElementById("x").value;
var tty = document.getElementById("y").value;
if(ttx <=0 || tty <=0){
alert('请点击地图,标记位置');
return false;
}
var res = theform.submit();
if($res['code'] != undefined){
if($res['code'] > 0){
alert($res['msg']);
return false;
}
}
return false;
}
</script>
</body>
</html>

View File

@ -20,3 +20,6 @@ Route::prefix('callback')->group(function () {
Route::get('/', function () {
return view('welcome');
});
$router->get('regions-position/{id}', [\App\Admin\Controllers\RegionController::class, 'setRegionPosition']);
$router->post('regions-position/save', [\App\Admin\Controllers\RegionController::class, 'saveRegionPosition']);