snapping to fixed angles / scales with shift key.
This commit is contained in:
parent
2e491b752e
commit
2051f7ef8b
4 changed files with 95 additions and 63 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue