2008-05-12

用 YUI imagecropper (beta) 做 step-by-step 設計/顯示

對一張給定的圖檔做 step-by-step 設計,說穿了就是用 AJAX 拉幾個長方型,記下它們的座標,存進資料庫;而顯示,就是倒過來,步驟幾就 new 幾個 DIV ,一個個蓋上去。
這邊講的是利用 YUI imagecropper (beta) 的做法,只要 hack YUI 就不需要自己寫 wrapper, mask, resizer 等等麻煩的東西了!
記下座標:

var crop = new YAHOO.widget.ImageCropper(id, {
initialXY: [0, 0], keyTick: 5,
minHeight: 10, minWidth: 10 });
var div = new Array();
var it = 0;
function readpoint() {
var coords = crop.getCropCoords();
var img = document.getElementById(id);

// some YUI bugs triggered by this hack
if(coords.top < 0) coords.top = 0;
if(coords.left < 0) coords.left = 0;
if(coords.top + coords.height > img.height)
coords.height = img.height - coords.top;
if(coords.left + coords.width > img.width)
coords.width = img.width - coords.left;

var data = '('+coords.left+','+coords.top+','+coords.width+','+coords.height+')';
results.innerHTML += data+'<br>'; // all coordinates stored here

var url = crop.get('element').getAttribute('src', 2); // image URL
div[it] = document.createElement('div'); // create a div with border and number
div[it].id = 'div_'+it;
div[it].className = 'step-by-step';
div[it].innerHTML = '<h1 style="color:red">'+(it+1)+'</h1>';
div[it].style.position = 'absolute';
div[it].style.border = '1px solid red';
div[it].style.top = coords.top + 'px';
div[it].style.left = coords.left + 'px';
div[it].style.width = coords.width + 'px';
div[it].style.height = coords.height + 'px';
div[it].style.backgroundImage = 'url(' + url + '#)';
div[it].style.backgroundPosition = '-'+coords.left+'px -'+coords.top+'px'; // as indicated in YUI source
crop._wrap.appendChild(div[it]);
it++;
crop._resizeEl.style.left = (coords.left + coords.width) + 'px';
crop._resizeEl.style.top = coords.top + 'px';
crop._syncBackgroundPosition();
};

顯示:

var cx = someJSONDataSource; // [ { top:0,left:0,width:0,height:0 }, { ... } ]
var divs = new Array();

function removeMasks() {
var x = document.getElementById('image');
for(var i = x.childNodes.length - 1; i >= 0; i--) { // remember we're removing...
var o = x.childNodes[i];
if(o.tagName.toLowerCase() == 'div') x.removeChild(o); // eliminate divs
}
}
function showStep(n) {
removeMasks();
for(var i = 1; i <= n; i++) {
document.getElementById('image').appendChild(divs[i]);
}
}
function init() {
var img = document.getElementById('ans');
var n = 1;
cx[cx.length] = { top: 0, left: 0, width: img.width, height: img.height };
for(var i in cx) {
steps.innerHTML += '<span class="solutions" onClick="showStep('+n+');">步驟'+n+'</span>';
if(n < cx.length) steps.innerHTML += ' &gt;&gt; ';
divs[n] = document.createElement('div');
divs[n].style.position = 'absolute';
divs[n].style.top = cx[i].top + 'px';
divs[n].style.left = cx[i].left + 'px';
divs[n].style.width = cx[i].width + 'px';
divs[n].style.height = cx[i].height + 'px';
divs[n].style.backgroundImage = 'url(' + img.src + '#)';
divs[n].style.backgroundPosition = '-' + cx[i].left + 'px -' + cx[i].top + 'px';
n++;
}
}