上述範例已完成了初始化繪製,還有調整大小的功能。有寫好如果拉的大小少於5px,即不可再縮小。

底圖的部分,加入這張:

圖片來源:Photo by Ryoji Iwata on Unsplash

html

<span>
<img src="./walker_900x518.jpg" style="width: 900px; height: 518px;">
</span>

由於操作中發現幾個問題跟可以延伸的部分,基於此範例去做修改。

問題:
當拖拉框超出圖片大小,會繪製出去或超出畫布。

解法:
先設定好圖片大小

    let imgHeight = 518;
let imgWidth = 900;

在「移動框框」時加上限制,限制不可超出畫布。

在「縮小放大左上角」時加上限制,限制不可超出畫布。

在「縮小放大左上角」時加上限制,限制不可超出畫布。

在「縮小放大右上角」時加上限制,限制不可超出畫布。

在「縮小放大右下角」時加上限制,限制不可超出畫布。

延伸部分:

1. 新增一個按鈕,按下時新增初始化畫框

html

<div style="position: fixed; top:500px;"><button id="add-btn">新增一個框框</button></div>

js

$('#add-btn').on('click', function (e) {
let element = document.createElement('DIV');
element.id = id;
element.classList.add('frame');
element.style.cursor = 'move';
id++;
document.body.appendChild(element)

let dr = new CreateDragRect(document.getElementById(element.id), {
x: 100,
y: 100,
width: 100,
height: 100,
});
dr.bindDragEvent(document.getElementById(element.id));
});

其中x, y, width, height是預設點按下去繪製畫框的位置及寬高。

點選特定框框時,框線顏色變以及四角顏色變化

js

$(document).on('click', '.frame', function(event){
let certainId = this.id;
let all = $(".frame").map(function() {
if (certainId == this.id) {
this.style.border = '3px solid red';
this.classList.add('selectedicon');
let element = document.getElementById(this.id);
let children = element.children;
for (let i = 0; i < children.length; i++){
let child = children[i];
child.style.backgroundColor = 'purple';
child.style.width = '6px';
child.style.height = '6px';
}
} else {
this.style.border = '3px solid yellow';
this.classList.remove('selectedicon');
let element = document.getElementById(this.id);
let children = element.children;
for (let i = 0; i < children.length; i++){
let child = children[i];
child.style.backgroundColor = 'yellow';
child.style.width = '0px';
child.style.height = '0px';
}
}
}).get();
});

被點選中的,會加上 selectedicon 這個 class,方便後續要刪除時可以直接取用。另外,邊界顏色與大小皆有相應調整。

2. 刪除選到的該框

html

<div style="position: fixed; top:540px;"><button id="delete-btn">刪除選到的框框</button></div>

js

$('#delete-btn').on('click', function (e) {
let myobjArr = document.getElementsByClassName("selectedicon");
if (myobjArr.length) {
myobjArr[0].remove();
}
});

針對被選取到的做刪除。

3. 清除所有的畫框

html

<div style="position: fixed; top:580px;"><button id="clear-btn">清除所有框框</button></div>

js

$('#clear-btn').on('click', function (e) {
removeAll();
});


function removeAll() {
let myobjArr = document.getElementsByClassName("frame");
for (let i = myobjArr.length - 1; i >= 0; i--){
myobjArr[i].remove();
}
}

4. 回到預設(給初始畫框)

html

<div style="position: fixed; top:620px;"><button id="reset-btn">回到預設</button></div>

js


$('#reset-btn').on('click', function (e) {
removeAll();
let data = [
{
x: 101,
y: 255,
width: 114,
height: 209,
},
{
x: 459,
y: 99,
width: 123,
height: 199,
}
]
redraw(data);
});


function redraw(data) {
for (let i = 0; i < data.length; i++) {
let element = document.createElement('DIV');
element.id = 'default' + [i];
element.classList.add('frame');
element.style.cursor = 'move';
document.body.appendChild(element)

let dr = new CreateDragRect(document.getElementById(element.id), {
x: data[i].x,
y: data[i].y,
width: data[i].width,
height: data[i].height,
});
dr.bindDragEvent(document.getElementById(element.id));
}
}

5.印出目前畫框資訊

html

<div style="position: fixed; top: 660px;"><button id="get-position-btn">印出目前框資訊</button></div>

js

$('#get-position-btn').on('click', function (e) {
let all = $(".frame").map(function() {
const id = this.id;
const width = this.style.width;
const height = this.style.height;
const top = this.style.top;
const left = this.style.left;
$('#all-frame').append(`<p>id: ${id} width: ${width} height: ${height} top: ${top} left: ${left}</p>`);
}).get();
});

成果:

附上 drag-transform-rect 專案的 GitHub 檔案連結 🔗 ,專案資料夾名稱:drag-tranform-rect 。其中有完整的程式碼可以參考。

延伸:

let img = document.getElementById('certain-img');
let imgNaturalHeight = img.naturalHeight;
let imgHeight = img.clientHeight;

naturalHeightclientHeight 各自取到圖片本身大小以及呈現在畫面的大小。依這些值計算要縮放的比例大小,即可算出點在「原始圖片」對應的位置。

--

--