167 lines
5.1 KiB
HTML
167 lines
5.1 KiB
HTML
<!doctype html>
|
||
<html lang="tr">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<title>jQuery ile Resizable Kutu</title>
|
||
<style>
|
||
body { font-family: Arial, Helvetica, sans-serif; height:100vh; margin:0; display:flex; align-items:center; justify-content:center; background:#f2f2f2; }
|
||
.stage { width:90vw; height:80vh; border:1px solid #ccc; position:relative; background:#fff; }
|
||
.box {
|
||
position:absolute;
|
||
left:50px; top:50px;
|
||
width:300px; height:200px;
|
||
background:#e8f0ff;
|
||
border:1px solid #5b8cff;
|
||
box-sizing:border-box;
|
||
user-select:none;
|
||
}
|
||
/* küçücük tutamaklar (handles) */
|
||
.handle {
|
||
position:absolute;
|
||
width:12px; height:12px;
|
||
background:#5b8cff;
|
||
border-radius:2px;
|
||
margin:-6px 0 0 -6px; /* merkezler */
|
||
cursor:default;
|
||
}
|
||
.handle.n { top:0; left:50%; cursor:n-resize; }
|
||
.handle.s { bottom:0; left:50%; cursor:s-resize; }
|
||
.handle.e { right:0; top:50%; cursor:e-resize; }
|
||
.handle.w { left:0; top:50%; cursor:w-resize; }
|
||
.handle.ne { right:0; top:0; cursor:ne-resize; }
|
||
.handle.nw { left:0; top:0; cursor:nw-resize; }
|
||
.handle.se { right:0; bottom:0; cursor:se-resize; }
|
||
.handle.sw { left:0; bottom:0; cursor:sw-resize; }
|
||
/* bilgi satırı (isteğe bağlı) */
|
||
.info { position:absolute; left:6px; bottom:6px; font-size:12px; color:#333; background:rgba(255,255,255,0.8); padding:4px 6px; border-radius:4px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="stage">
|
||
<div class="box" id="resizable">
|
||
<div class="handle n" data-dir="n"></div>
|
||
<div class="handle s" data-dir="s"></div>
|
||
<div class="handle e" data-dir="e"></div>
|
||
<div class="handle w" data-dir="w"></div>
|
||
<div class="handle ne" data-dir="ne"></div>
|
||
<div class="handle nw" data-dir="nw"></div>
|
||
<div class="handle se" data-dir="se"></div>
|
||
<div class="handle sw" data-dir="sw"></div>
|
||
<div class="info" id="info"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||
<script>
|
||
$(function(){
|
||
var $doc = $(document);
|
||
var $box = $('#resizable');
|
||
var dragging = false;
|
||
var dir = null;
|
||
var start = {}; // {mouseX, mouseY, left, top, width, height}
|
||
var minW = 60, minH = 40;
|
||
|
||
function updateInfo(){
|
||
var w = Math.round($box.width()), h = Math.round($box.height());
|
||
$('#info').text(w + ' x ' + h);
|
||
}
|
||
updateInfo();
|
||
|
||
$box.on('mousedown', '.handle', function(e){
|
||
e.preventDefault();
|
||
dragging = true;
|
||
dir = $(this).data('dir');
|
||
var offset = $box.position();
|
||
start = {
|
||
mouseX: e.pageX,
|
||
mouseY: e.pageY,
|
||
left: offset.left,
|
||
top: offset.top,
|
||
width: $box.outerWidth(),
|
||
height: $box.outerHeight()
|
||
};
|
||
// disable text selection while dragging
|
||
$('body').css('user-select','none');
|
||
});
|
||
|
||
$doc.on('mousemove', function(e){
|
||
if(!dragging) return;
|
||
e.preventDefault();
|
||
var dx = e.pageX - start.mouseX;
|
||
var dy = e.pageY - start.mouseY;
|
||
var newLeft = start.left;
|
||
var newTop = start.top;
|
||
var newW = start.width;
|
||
var newH = start.height;
|
||
|
||
// handle horizontal changes
|
||
if(dir.indexOf('e') !== -1){
|
||
newW = Math.max(minW, start.width + dx);
|
||
}
|
||
if(dir.indexOf('w') !== -1){
|
||
newW = Math.max(minW, start.width - dx);
|
||
newLeft = start.left + (start.width - newW);
|
||
}
|
||
|
||
// handle vertical changes
|
||
if(dir.indexOf('s') !== -1){
|
||
newH = Math.max(minH, start.height + dy);
|
||
}
|
||
if(dir.indexOf('n') !== -1){
|
||
newH = Math.max(minH, start.height - dy);
|
||
newTop = start.top + (start.height - newH);
|
||
}
|
||
|
||
// apply
|
||
$box.css({ left: newLeft + 'px', top: newTop + 'px', width: newW + 'px', height: newH + 'px' });
|
||
updateInfo();
|
||
});
|
||
|
||
$doc.on('mouseup mouseleave', function(){
|
||
if(dragging){
|
||
dragging = false;
|
||
dir = null;
|
||
$('body').css('user-select','auto');
|
||
}
|
||
});
|
||
|
||
// optional: allow dragging the whole box when clicking inside (but not on handles)
|
||
var draggingBox = false, dragBoxStart = {};
|
||
$box.on('mousedown', function(e){
|
||
if($(e.target).hasClass('handle')) return;
|
||
e.preventDefault();
|
||
draggingBox = true;
|
||
dragBoxStart = { mouseX: e.pageX, mouseY: e.pageY, left: $box.position().left, top: $box.position().top };
|
||
$('body').css('user-select','none');
|
||
});
|
||
$doc.on('mousemove', function(e){
|
||
if(!draggingBox) return;
|
||
var nx = dragBoxStart.left + (e.pageX - dragBoxStart.mouseX);
|
||
var ny = dragBoxStart.top + (e.pageY - dragBoxStart.mouseY);
|
||
$box.css({ left: nx + 'px', top: ny + 'px' });
|
||
});
|
||
$doc.on('mouseup', function(){
|
||
if(draggingBox){
|
||
draggingBox = false;
|
||
$('body').css('user-select','auto');
|
||
}
|
||
});
|
||
|
||
// keyboard nudges (isteğe bağlı)
|
||
$doc.on('keydown', function(e){
|
||
e.preventDefault();
|
||
if(!e.altKey) return; // alt ile etkinleştir
|
||
var pos = $box.position();
|
||
if(e.key === 'ArrowLeft') $box.css('left', pos.left - 1);
|
||
if(e.key === 'ArrowRight') $box.css('left', pos.left + 1);
|
||
if(e.key === 'ArrowUp') $box.css('top', pos.top - 1);
|
||
if(e.key === 'ArrowDown') $box.css('top', pos.top + 1);
|
||
});
|
||
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|