作爲一個mootools類,可能更接近於jQuery的香草。它的怪癖,這是一個急於工作,我沒有改善或重構。每次更新/更改數據(x,y,角度等)時觸發onChanged事件。
var guillotine = new Class({
Implements: [Options, Events],
changed: function(){
this.fireEvent('changed');
},
options : {
test: 'whatever',
defaults : {
width: 250,
height: 300,
zoomStep: 0.1,
init: null,
eventOnChange: null,
onChange: null
}
},
initialize : function(element, options) {
this.setOptions(options);
console.log(this.options.test);
this.img = $(element)
this.zoomInFactor = 1 + this.options.defaults.zoomStep;
this.zoomOutFactor = 1/this.zoomInFactor;
this.width = this.height = this.left = this.top = this.angle = this.myDragStart = this.myDragEnd = 0;
this.data = {
scale: 1,
angle: 0,
x: 0,
y: 0,
w: this.options.defaults.width,
h: this.options.defaults.height
};
//set hardware acceleration on for the element given
this.img.setStyles({'-webkit-perspective': 1000, 'perspective': 1000, '-webkit-backface-visibility': 'hidden', 'backface-visibility': 'hidden' });
//do the element creation
//wrap the existing img up in the new divs
if(this.img.get('tag') === 'img'){
if (this.img.naturalWidth) {
width = this.img.naturalWidth;
height = this.img.naturalHeight;
} else {
this.img.addClass('guillotine-sample');
width = this.img.width;
height = this.img.height;
this.img.removeClass('guillotine-sample');
}
} else {
width = this.img.width;
height = this.img.height;
};
//why do they create this ratio of widths
this.width = width/this.options.defaults.width;
this.height = height/this.options.defaults.height;
//so now we have the natural width of the image that is being used
//including the ratio
//this.img.width = width/this.options.defaults.width;
//this.img.height = height/this.options.defaults.height;
//new canvas element has to have the raio width * 100 %
this.canvas = new Element('div',{
id: 'canvas',
'class': 'guillotine-canvas',
styles : {
width: (width/this.options.defaults.width) * 100 + '%',
height: (height/this.options.defaults.height) * 100 + '%',
top: 0,
left: 0
}
}).wraps(this.img.id);
this.window = new Element('div',{
'class': 'guillotine-window',
styles : {
width: '100%',
height: 'auto',
'padding-top': this.options.defaults.height/this.options.defaults.width * 100 + '%'
}
}).wraps(this.canvas);
//setup the dragging of the canvas
this.myDrag = new Drag('canvas', {
snap: 0,
onComplete: function(el){
//need the figures in percentages not the px
containerDimensions = this.window.getSize()
myLeft = el.getPosition(this.window).x/containerDimensions.x;
myTop = el.getPosition(this.window).y/containerDimensions.y;
this.offset(-myLeft, -myTop);
//this.canvas.setStyle('left' , (myLeft * 100) + '%')
//this.canvas.setStyle('top' , (myTop * 100) + '%')
}.bind(this)
});
this.fireEvent('imageChange', this.data);
},
//functions
fit : function(){
var prevWidth, relativeRatio, newWidth, newHeight;
prevWidth = this.width;
relativeRatio = this.height/this.width
if (relativeRatio > 1) {
this.width = 1;
this.height = relativeRatio;
} else {
this.width = 1/relativeRatio;
this.height = 1;
}
this.canvas.setStyle('width' , (this.width * 100).toFixed(2) + '%');
this.canvas.setStyle('height' , (this.height * 100).toFixed(2) + '%');
//set the data container to the scale unit use the previous width above
this.offset((this.width - 1)/2, (this.height - 1)/2);
this.data.scale *= this.width/prevWidth;
this.fireEvent('changed');
},
zoom : function(direction) {
if(direction == 'in'){
factor = this.zoomInFactor;
}else if(direction == 'out'){
factor = this.zoomOutFactor;
}
if (factor <= 0 || factor === 1) {
return;
}
var w = this.width, h = this.height;
if (w * factor > 0 && h * factor > 0) {
//*= >> x = x * y
this.width *= factor;
this.height *= factor;
this.canvas.setStyle('width', (this.width * 100).toFixed(2) + '%');
this.canvas.setStyle('height' , (this.height * 100).toFixed(2) + '%');
//set the record transformations
this.data.scale *= factor;
} else {
this.fit();
factor = this.width/w;
}
//now sort out the centre zoomStep
var left = (this.left + 0.5) * factor - 0.5;
var top = (this.top + 0.5) * factor - 0.5;
this.offset(left,top);
},
rotate : function(angle) {
var canvasRatio, glltRatio, h, w, _ref, _ref1, _ref2;
//check if angle is a 90 degree unit
if (!(angle !== 0 && angle % 90 === 0)) {
return;
}
this.angle = (this.angle + angle) % 360;
if (this.angle < 0) {
this.angle = 360 + this.angle;
}
if (angle % 180 !== 0) {
glltRatio = this.options.defaults.height/this.options.defaults.width;
_ref = [this.height * glltRatio, this.width/glltRatio], this.width = _ref[0], this.height = _ref[1];
if (this.width >= 1 && this.height >= 1) {
this.canvas.setStyle('width' , this.width * 100 + '%');
this.canvas.setStyle('height' , this.height * 100 + '%');
} else {
this.fit();
}
}
_ref1 = [1, 1], w = _ref1[0], h = _ref1[1];
if (this.angle % 180 !== 0) {
canvasRatio = this.height/this.width * glltRatio;
_ref2 = [canvasRatio, 1/canvasRatio], w = _ref2[0], h = _ref2[1];
}
this.img.setStyles({
'width' : w * 100 + '%',
'height' : h * 100 + '%',
'left' : (1 - w)/2 * 100 + '%',
'top' : (1 - h)/2 * 100 + '%',
transform : 'rotate(' + this.angle + 'deg)'
})
this.data.angle = this.angle;
this.center();
},
center : function() {
this.offset((this.width - 1)/2, (this.height - 1)/2);
},
offset : function(left,top) {
if (left || left === 0) {
if (left < 0) {
//I HAVE REMOVED THIS SO THAT WE CAN MOVE A SHRUNKEN IMAGE AROUND
//left = 0;
}
if (left > this.width - 1) {
//I HAVE REMOVED THIS SO THAT WE CAN MOVE A SHRUNKEN IMAGE AROUND
//left = this.width - 1;
}
this.canvas.setStyle('left' , (-left * 100).toFixed(2) + '%');
this.left = left;
this.data.x = Math.round(left * this.options.defaults.width);
}
if (top || top === 0) {
if (top < 0) {
//I HAVE REMOVED THIS SO THAT WE CAN MOVE A SHRUNKEN IMAGE AROUND
//top = 0;
}
if (top > this.height - 1) {
//I HAVE REMOVED THIS SO THAT WE CAN MOVE A SHRUNKEN IMAGE AROUND
//top = this.height - 1;
}
this.canvas.setStyle('top' , (-top * 100).toFixed(2) + '%');
this.top = top;
this.data.y = Math.round(top * this.options.defaults.height);
}
this.fireEvent('changed');
},
getData : function() {
return this.data;
}
});