You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.7 KiB
JavaScript
166 lines
5.7 KiB
JavaScript
"use strict";
|
|
const ruler_metrics = [1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000];
|
|
const ruler_metrics_sub = [1,5,10, 50, 100];
|
|
var drawerRuler = function (options) {
|
|
var api = this.builder(options);
|
|
api.constructRulers.call(this, options);
|
|
return {
|
|
api: api,
|
|
};
|
|
};
|
|
|
|
drawerRuler.prototype.builder = function (para) {
|
|
var HORIZONTAL = 1,
|
|
VERTICAL = 2,
|
|
CUR_DELTA_X = 0,
|
|
CUR_DELTA_Y = 0,
|
|
CUR_SCALE = 1;
|
|
|
|
var options,
|
|
defaultOptions = {
|
|
rulerHeight: 20,
|
|
fontFamily: 'arial',
|
|
fontSize: 9,
|
|
strokeStyle: '#505050',
|
|
orientation: HORIZONTAL,
|
|
lineWidth: 1,
|
|
enableMouseTracking: true,
|
|
enableToolTip: true
|
|
};
|
|
|
|
var theRulerDOM = document.getElementById(para.container);
|
|
var ctx = theRulerDOM.getContext('2d');
|
|
var constructRulers = function (curOptions) {
|
|
options = drawerRuler.prototype.utils.extend(defaultOptions, curOptions);
|
|
};
|
|
var redraw = function (widthS, leftR, rightR) {
|
|
var screenWidth = widthS*2;
|
|
ctx.clearRect(0, 0, screenWidth, screenWidth);
|
|
var _lower = leftR;
|
|
var _upper = rightR;
|
|
|
|
if(_upper == 0){
|
|
_upper = 1;
|
|
}
|
|
var pixels_per_unit = screenWidth / ((_upper - _lower)); // pixel per distance
|
|
var _font_size = options.fontSize;
|
|
var aheight = options.rulerHeight;
|
|
// Figure out scale. Largest ticks must be far enough apart to fit largest text in vertical ruler.
|
|
// We actually require twice the distance.
|
|
var scale = Math.ceil(rightR); // Largest number
|
|
var scale_text = "" + scale;
|
|
|
|
var digits = scale_text.length + 1; // Add one for negative sign.
|
|
if (Math.abs(rightR) < 10) {
|
|
digits = 4; // 小数刻度 -0.10
|
|
}
|
|
var miniPixels = digits * _font_size*2;// * 2; // Minimum pixels per 大刻度.
|
|
|
|
var scale_index = 0;
|
|
for (scale_index = 0; scale_index < ruler_metrics.length - 1; scale_index++) {
|
|
var tick_size = ruler_metrics[scale_index];
|
|
if (Math.abs(pixels_per_unit) * tick_size > miniPixels) {
|
|
break;
|
|
}
|
|
}
|
|
// Now we find out what is the subdivide index for the closest ticks we can draw
|
|
var divide_index = 0;
|
|
for (divide_index = 0; divide_index < ruler_metrics_sub.length - 1; ++divide_index) {
|
|
if (ruler_metrics[scale_index] * Math.abs(pixels_per_unit) < 5 * ruler_metrics_sub[divide_index + 1]) {
|
|
break;
|
|
}
|
|
}
|
|
// We'll loop over all ticks.
|
|
// 每个刻度的像素数
|
|
var pixels_per_tick = pixels_per_unit *
|
|
ruler_metrics[scale_index] / ruler_metrics_sub[divide_index];
|
|
|
|
// 每个刻度的实际坐标单位数
|
|
var units_per_tick = pixels_per_tick / pixels_per_unit;
|
|
var ticks_per_unit = 1.0 / units_per_tick;
|
|
|
|
// Find first and last ticks
|
|
var start = 0;
|
|
var end = 0;
|
|
if (_lower < _upper) {
|
|
start = Math.floor(_lower * ticks_per_unit);
|
|
end = Math.ceil(_upper * ticks_per_unit);
|
|
} else {
|
|
start = Math.floor(_upper * ticks_per_unit);
|
|
end = Math.ceil(_lower * ticks_per_unit);
|
|
}
|
|
// 绘制样式
|
|
ctx.strokeStyle = options.strokeStyle;
|
|
ctx.font=options.fontSize*2 + 'px ' + options.fontFamily;
|
|
ctx.lineWidth = 1;//options.lineWidth;
|
|
|
|
ctx.save();
|
|
if(options.orientation == VERTICAL){
|
|
ctx.translate(0, screenWidth);
|
|
ctx.rotate(-Math.PI/2);
|
|
}
|
|
ctx.beginPath();
|
|
|
|
var aperpendicular = options.fontSize;
|
|
// Loop over all ticks
|
|
for (var i = start; i < end+1; ++i) {
|
|
// Position of tick (add 0.5 to center tick on pixel).
|
|
var position = Math.floor(i*pixels_per_tick - _lower*pixels_per_unit) + 0.5;
|
|
|
|
// Height of tick
|
|
var size = aheight-7;
|
|
for (var j = divide_index; j > 0; --j) {
|
|
if (i%ruler_metrics_sub[j] == 0) break;
|
|
size = size / 2 +1;
|
|
}
|
|
|
|
// Draw text for major ticks.
|
|
if (i%ruler_metrics_sub[divide_index] == 0) {
|
|
|
|
var label_value = Math.round(i * units_per_tick);
|
|
var label = label_value.toString();
|
|
ctx.fillText(label, position + 1.5, aheight*2 - aperpendicular*2);
|
|
}
|
|
|
|
// Draw ticks
|
|
// if (_orientation == Gtk::Orientation::HORIZONTAL) {
|
|
ctx.moveTo(position, aheight*2 - size*2);
|
|
//ctx.moveTo(position, 0);
|
|
ctx.lineTo(position, aheight*2 );
|
|
// } else {
|
|
// cr->move_to(awidth - size, position);
|
|
// cr->line_to(awidth , position);
|
|
// }
|
|
}
|
|
ctx.moveTo(0, aheight*2);
|
|
ctx.lineTo(position, aheight*2);
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
};
|
|
var drawGuide = function (positionR) {
|
|
|
|
};
|
|
return {
|
|
redraw: redraw,
|
|
drawGuide: drawGuide,
|
|
constructRulers: constructRulers,
|
|
};
|
|
};
|
|
|
|
drawerRuler.prototype.utils = {
|
|
extend: function extend() {
|
|
for (var i = 1; i < arguments.length; i++)
|
|
for (var key in arguments[i])
|
|
if (arguments[i].hasOwnProperty(key))
|
|
arguments[0][key] = arguments[i][key];
|
|
return arguments[0];
|
|
},
|
|
pixelize: function (val) {
|
|
return val + 'px';
|
|
},
|
|
prependChild: function (container, element) {
|
|
return container.insertBefore(element, container.firstChild);
|
|
},
|
|
};
|
|
|