snapping to fixed angles / scales with shift key.

This commit is contained in:
Teja 2015-06-26 12:07:57 +02:00
parent 2e491b752e
commit 2051f7ef8b
4 changed files with 95 additions and 63 deletions

View file

@ -1629,7 +1629,16 @@ input.search-query,
}
#wa_filelist .file_list_entry .title {
max-width: 80%;
float: left;
/*float: left;*/
}
#wa_filelist .file_list_entry .detail_information {
clear: both;
}
.misfit_warning {
display: none;
}
.misfit .misfit_warning {
display: block;
}
#files .file_list_entry .title {

View file

@ -125,8 +125,6 @@ Snap.plugin(function (Snap, Element, Paper, global) {
dragHandleRotateEnd.bind( rotateDragger, freetransEl )
);
freetransEl.ftStoreInitialTransformMatrix();
// freetransEl.ftStoreGlobalScaling();
freetransEl.ftHighlightBB();
return this;
};
@ -160,15 +158,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
Element.prototype.ftStoreInitialTransformMatrix = function() {
this.data('initialTransformMatrix', this.transform().localMatrix );
return this;
};
// Element.prototype.ftStoreGlobalScaling = function() {
// var scale = this.transform().globalMatrix.a;
// this.data('globalScale', scale );
// return this;
// };
};
Element.prototype.ftGetInitialTransformMatrix = function() {
return this.data('initialTransformMatrix');
@ -202,11 +192,6 @@ Snap.plugin(function (Snap, Element, Paper, global) {
return this;
};
// Element.prototype.ftTransformedPoint = function( x, y ) {
// var transform = this.transform().diffMatrix;
// return { x: transform.x( x,y ) , y: transform.y( x,y ) };
// };
Element.prototype.ftUpdateTransform = function() {
var tstring = "t" + this.data("tx") + "," + this.data("ty") + this.ftGetInitialTransformMatrix().toTransformString() + "r" + this.data("angle") + 'S' + this.data("scale" );
@ -224,8 +209,8 @@ Snap.plugin(function (Snap, Element, Paper, global) {
.attr({ fill: "none", stroke: ftOption.handleFill, strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDashPreset.join(',') })
.transform( this.transform().global.toString() ) );
// outer bbox
//this.data("bb", this.paper.select('#userContent').rect( rectObjFromBB( this.getBBox() ) )
// .attr({ fill: "none", stroke: ftOption.handleFill3, strokeDasharray: ftOption.handleStrokeDash }) );
this.data("bb", this.paper.select('#userContent').rect( rectObjFromBB( this.getBBox() ) )
.attr({ fill: "none", stroke: 'gray', strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDash }) );
return this;
};
@ -241,21 +226,34 @@ Snap.plugin(function (Snap, Element, Paper, global) {
} );
mainEl.data("otx", mainEl.data("tx") || 0);
mainEl.data("oty", mainEl.data("ty") || 0);
mainEl.data('obb', mainEl.getBBox());
mainEl.data('wa', snap.select('#coordGrid').getBBox());
};
function elementDragMove( mainEl, dx, dy, x, y ) {
var dragHandle = this;
var unscale = mainEl.data('unscale');
var bb = mainEl.data('obb');
var udx = dx*unscale;
var udy = dy*unscale;
// check limits
// udx = Math.max(udx, -bb.x);
// udx = Math.min(udx, mainEl.data('wa').x2 - bb.x2);
// udy = Math.max(udy, -bb.y);
// udy = Math.min(udy, mainEl.data('wa').y2 - bb.y2);
// update drag handle
this.parent().selectAll('circle').forEach( function( el, i ) {
el.attr({ cx: +el.data('ocx') + udx, cy: +el.data('ocy') + udy });
} );
mainEl.data("tx", mainEl.data("otx") + +udx);
mainEl.data("ty", mainEl.data("oty") + +udy);
// update element
var tx = mainEl.data("otx") + +udx;
var ty = mainEl.data("oty") + +udy;
mainEl.data("tx", tx);
mainEl.data("ty", ty);
mainEl.ftUpdateTransform();
mainEl.ftDrawJoinLine( dragHandle );
}
@ -277,20 +275,16 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var unscale = mainEl.data('unscale');
handle.attr({ cx: +handle.data('ocx') + dx*unscale, cy: +handle.data('ocy') + dy*unscale });
var angle;
if(event.ctrlKey){
angle = 0
} else {
angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180;
}
var angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180;
if(event.shiftKey){
angle = Math.round(angle/30) * 30;
}
mainEl.data("angle", angle );
var scale;
var distance = calcDistance( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') );
var scale = distance / mainEl.data("scaleFactor");
if(event.shiftKey){
scale = 1;
} else {
var distance = calcDistance( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') );
scale = distance / mainEl.data("scaleFactor");
scale = Math.round(scale*4) / 4;
}
mainEl.data("scale", scale );

View file

@ -241,13 +241,6 @@ $(function(){
if(hasText !== null && hasText.length > 0){
self.svg_contains_text_warning(newSvg);
}
// TODO debug. bounding boxes are always zero sized when not displayed.
// var misfitting = self.outsideWorkingArea(newSvg);
// if(misfitting.oversized || misfitting.outside){
// self.svg_misfitting_warning(newSvg, misfitting);
// newSvg.translate(misfitting.dx, misfitting.dy);
// newSvg.scale(misfitting.scale);
// }
newSvg.bake(); // remove transforms
newSvg.attr(newSvgAttrs);
@ -256,10 +249,11 @@ $(function(){
newSvg.attr({id: previewId});
snap.select("#userContent").append(newSvg);
newSvg.transformable();
file.id = previewId;
file.id = id; // list entry id
file.previewId = previewId;
file.url = url;
file.misfit = "";
self.placedDesigns.push(file);
};
@ -272,7 +266,7 @@ $(function(){
self.removeSVG = function(file){
self.abortFreeTransforms();
snap.select('#'+file.previewId).remove();
snap.selectAll('#'+file.previewId).remove();
self.placedDesigns.remove(file);
// TODO debug why remove always clears all items of this type.
// self.placedDesigns.remove(function(item){
@ -284,6 +278,19 @@ $(function(){
// } else return false;
// });
};
self.fitSVG = function(file){
self.abortFreeTransforms();
var svg = snap.select('#'+file.previewId);
var fitMatrix = new Snap.matrix();
fitMatrix.scale(svg.data('fitMatrix').scale);
fitMatrix.translate(svg.data('fitMatrix').dx, svg.data('fitMatrix').dy);
var localMatrix = svg.transform().localMatrix;
var compositeMatrix = localMatrix.add(fitMatrix)
svg.transform(compositeMatrix);
svg.data('fitMatrix', null);
$('#'+file.id).removeClass('misfit');
};
self.toggleTransformHandles = function(file){
var el = snap.select('#'+file.previewId);
if(el){
@ -292,7 +299,7 @@ $(function(){
};
self.outsideWorkingArea = function(svg){
var waBB = snap.select('#userContent').getBBox();
var waBB = snap.select('#coordGrid').getBBox();
var svgBB = svg.getBBox();
var tooWide = svgBB.w > waBB.w;
var tooHigh = svgBB.h > waBB.h;
@ -307,6 +314,7 @@ $(function(){
dx = -svgBB.x;
dy = -svgBB.y;
}
console.log("svgBB", svgBB.x, svgBB.x2);
return { oversized: tooWide || tooHigh, outside: outside, scale: scale, dx: dx, dy: dy };
};
@ -362,10 +370,10 @@ $(function(){
}
}
if(doc_height === "100%"){
doc_height = 1052.3622047 // 297mm @ 90dpi
doc_height = 1052.3622047; // 297mm @ 90dpi
}
if(doc_height === null){
doc_height = 1052.3622047 // 297mm @ 90dpi
doc_height = 1052.3622047; // 297mm @ 90dpi
}
}
@ -395,7 +403,7 @@ $(function(){
}
}
return [[1,0,0],[0,1,0], [0,0,1]]
return [[1,0,0],[0,1,0], [0,0,1]];
};
//a dictionary of unit to user unit conversion factors
@ -452,15 +460,6 @@ $(function(){
return "wa_" + md5(data["origin"] + ":" + data["name"]);
};
self.getEntryElement = function(data) {
var entryId = self.getEntryId(data);
var entryElements = $("#" + entryId);
if (entryElements && entryElements[0]) {
return entryElements[0];
} else {
return undefined;
}
};
self.init = function(){
// init snap.svg
@ -519,6 +518,7 @@ $(function(){
var el = tip[i];
el.ftRemoveHandles();
}
self.check_sizes_and_placements();
};
self.getCompositionSVG = function(){
@ -528,8 +528,6 @@ $(function(){
var dpiFactor = self.svgDPI()/25.4; // convert mm to pix 90dpi for inkscape, 72 for illustrator
var w = dpiFactor * self.workingAreaWidthMM();
var h = dpiFactor * self.workingAreaHeightMM();
// var w = dpiFactor * self.settings.printerProfiles.currentProfileData().volume.width;
// var h = dpiFactor * self.settings.printerProfiles.currentProfileData().volume.depth;
var svg = '<svg height="'+ h +'" version="1.1" width="'+ w +'" xmlns="http://www.w3.org/2000/svg"><defs/>'+ tmpsvg +'</svg>';
return svg;
@ -567,12 +565,38 @@ $(function(){
self.state.workingArea = self;
self.files.workingArea = self;
// check this on tab change as before the bounding boxes are sized 0.
$('#wa_tab_btn').on('shown.bs.tab', function (e) {
self.trigger_resize();
self.check_sizes_and_placements();
});
$(window).resize(function(){
self.trigger_resize();
});
self.trigger_resize(); // initialize
self.init();
};
self.check_sizes_and_placements = function(){
ko.utils.arrayForEach(self.placedDesigns(), function(design) {
if(design.type === 'model'){
var svg = snap.select('#' + design.previewId);
var misfitting = self.outsideWorkingArea(svg);
console.log(misfitting);
console.log(misfitting.scale * misfitting.dy);
if(misfitting.oversized || misfitting.outside){
//var tstr ='matrix(' + misfitting.scale + ',0,0,'+ misfitting.scale + ',' + misfitting.scale*misfitting.dx + ',' + misfitting.scale*misfitting.dy +')' ;
//var tstr ='s' + misfitting.scale + 't' + misfitting.scale*misfitting.dx + ',' + misfitting.scale*misfitting.dy ;
svg.data('fitMatrix', misfitting);
$('#'+design.id).addClass('misfit');
} else {
$('#'+design.id).removeClass('misfit');
svg.data('fitMatrix', null);
}
}
});
};
}

View file

@ -20,9 +20,8 @@
</a>
</div>
<ul class="nav nav-pills">
<li class="active"><a href="#workingarea" data-toggle="tab">working area</a></li>
<li class="active"><a href="#workingarea" data-toggle="tab" id="wa_tab_btn">working area</a></li>
<li><a href="#designlib" data-toggle="tab">design library</a></li>
<!--<li><a href="#gcode" data-toggle="tab">gcode</a></li>-->
<li><a href="#focus" data-toggle="tab">focus</a></li>
<li><a href="#term" data-toggle="tab">terminal</a></li>
@ -179,7 +178,7 @@
<div class="accordion-body collapse in overflow_visible" id="wa_filelist">
<div class="accordion-inner">
<div class="gcode_files" data-bind="slimScrolledForeach: placedDesigns">
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<div class="entry" data-bind="attr: { id: $data.id }, template: { name: $root.templateFor($data), data: $data }"></div>
</div>
<script type="text/html" id="wa_template_machinecode">
@ -193,11 +192,17 @@
<script type="text/html" id="wa_template_model_svg">
<div class="file_list_entry">
<div class="title muted" data-bind="text: name"></div>
<div class="title muted pull-left" data-bind="text: name"></div>
<div class="btn-group action-buttons pull-right">
<div class="btn btn-mini" data-bind="click: function() { $root.toggleTransformHandles($data); }"><i class="icon-move" title="{{ _('Transform') }}"></i></div>
<div class="btn btn-mini" data-bind="click: function() { $root.removeSVG($data); }"><i class="icon-remove" title="{{ _('Remove') }}"></i></div>
</div>
<div class="detail_information" >
<div class="misfit_warning" >
<i class="icon-exclamation-sign" style="color:red;" title="{{ _('exceeds working area') }}"> Design exceeds the working area.</i>
<a href="#" data-bind="click: function(){ $root.fitSVG($data) } ">Transform to fit closely</a>
</div>
</div>
</div>
</script>