import G = require("./globals"); import * as $ from "jquery"; import Help = require("./helper"); import { DrawChart } from "./drawChart"; export class DrawImage { public _drawChart: DrawChart; private _image = G.Image.getInstance(); private readonly _saturationSliderID: string = "SaturationSlider"; private readonly _replotButtonID: string = "rePlot"; private readonly _transparencySliderID: string = "TrasparencySlider"; private readonly _resetID: string = "reset"; private readonly _exportImageID: string = "ExportImage"; private readonly _selectionCanvasID: string; private readonly _myCanvasID: string = "myCanvas"; private _context: CanvasRenderingContext2D; private _saturationSlider: HTMLInputElement; private _replotButton: HTMLButtonElement; private _transparencySlider: HTMLInputElement; private _reset: HTMLDivElement; private _exportImage: HTMLDivElement; private _pixel1: G.coordinates; private _pixel2: G.coordinates; private _xMinRange: number; private _xMaxRange: number; private _selectionCanvas: HTMLCanvasElement; private _myCanvas: HTMLCanvasElement; private _ctx; private _startX: number; private _startY: number; private _mouseX: number; private _mouseY: number; private _isDown = false; constructor(canvas: string) { this._drawChart = new DrawChart(this); this._selectionCanvasID = canvas; this._selectionCanvas = <HTMLCanvasElement>document.getElementById(this._selectionCanvasID); this._ctx = this._selectionCanvas.getContext("2d"); this._myCanvas = <HTMLCanvasElement>document.getElementById(this._myCanvasID); this._saturationSlider = <HTMLInputElement>document.getElementById(this._saturationSliderID); this._replotButton = <HTMLButtonElement>document.getElementById(this._replotButtonID); this._transparencySlider = <HTMLInputElement>document.getElementById(this._transparencySliderID); this._reset = <HTMLDivElement>document.getElementById(this._resetID); this._exportImage = <HTMLDivElement>document.getElementById(this._exportImageID); this._saturationSlider.addEventListener("mouseup", this.saturationSliderMouseUp, false); this._replotButton.addEventListener("click", this.replotButtonClick, false); this._transparencySlider.addEventListener("mouseup", this.trasparencySliderMouseUp, false); this._reset.addEventListener("click", this.resetClick, false); this._exportImage.addEventListener("click", this.exportImageClick, false); this._selectionCanvas.addEventListener("mousedown", this.selectionCanvasMouseDown, false); this._selectionCanvas.addEventListener("mouseup", this.clickdown, false); this._selectionCanvas.addEventListener("mousemove", this.selectionCanvasMouseMove, false); this._selectionCanvas.addEventListener("mouseup", this.selectionCanvasMouseUp, false); this._selectionCanvas.addEventListener("mouseout", this.selectionCanvasMouseOut, false); } private saturationSliderMouseUp = (event: MouseEvent): void => { this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange); }; private replotButtonClick = (event: MouseEvent) => { //bottone per colorare con il max relativo this._image.rePrint = true; this._saturationSlider.value = "100"; // opacity value? this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange); }; private trasparencySliderMouseUp = (event: MouseEvent) => { this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange); }; private resetClick = (event: MouseEvent) => { this._image.newOrigin = { x: 0, y: 0 }; this._image.rePrint = false; G.Chart.getInstance().calibrated = false; this._image.globalxMinRange = 0; this._image.globalxMaxRange = this._image.channelDepth; this._saturationSlider.value = "100"; this._transparencySlider.value = "0"; this._drawChart.spinBoxMin.setAttribute("value", "-"); this._drawChart.spinBoxMax.setAttribute("value", "-"); this.drawImg(this._image, { x: 0, y: 0 }, { x: this._image.width - 1, y: this._image.height - 1 }, 0, this._image.channelDepth); this._drawChart.drawChart(this._image, { x: 0, y: 0 }, { x: this._image.width - 1, y: this._image.height - 1 }, 0, this._image.channelDepth); }; private exportImageClick = (event: MouseEvent) => { //esportazione immagine let img = this._selectionCanvas.toDataURL("image/png"); this._selectionCanvas.setAttribute("href", img.replace("image/png", "image/octet-stream")); document.getElementById("ExportLink").setAttribute("href", img); }; private clickdown = (event: MouseEvent): void => { this.setPosition(event, this._image.zPixel2, this._selectionCanvasID); let tmp: number; if (this._image.zPixel1.y > this._image.zPixel2.y) { tmp = this._image.zPixel1.y; this._image.zPixel1.y = this._image.zPixel2.y; this._image.zPixel2.y = tmp; } //se รจ stato cliccato un punto disegno il grafico, altrimenti disegno anche il //canvas e aggiorno l'origine if (this._image.zPixel1.x != this._image.zPixel2.x || this._image.zPixel1.y != this._image.zPixel2.y) { this._image.newOrigin = { x: this._image.zPixel1.x, y: this._image.zPixel1.y }; this.drawImg(this._image, this._image.zPixel1, this._image.zPixel2, this._image.globalxMinRange, this._image.globalxMaxRange); } this._drawChart.drawChart(this._image, this._image.zPixel1, this._image.zPixel2, this._image.globalxMinRange, this._image.globalxMaxRange); }; private selectionCanvasMouseDown = (event: MouseEvent) => { event.preventDefault(); event.stopPropagation(); //calculate mouse position let scrollTOP: number = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop; let scrollLEFT: number = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft; let allX: number = event.clientX + scrollLEFT; let allY: number = event.clientY + scrollTOP; let elParent: any = this._myCanvas; let objX: number = 0, objY: number = 0; while (elParent) { objX += elParent.offsetLeft; objY += elParent.offsetTop; elParent = elParent.offsetParent; } this._startX = allX - objX; this._startY = allY - objY; // set a flag indicating the drag has begun this._isDown = true; }; private selectionCanvasMouseUp = (event: MouseEvent) => { event.preventDefault(); event.stopPropagation(); // the drag is over, clear the dragging flag this._isDown = false; //this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height); }; private selectionCanvasMouseMove = (event: MouseEvent) => { event.preventDefault(); event.stopPropagation(); // if we're not dragging, just return if (!this._isDown) { return; } //calculate mouse position let scrollTOP: number = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop; let scrollLEFT: number = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft; let allX: number = event.clientX + scrollLEFT; let allY: number = event.clientY + scrollTOP; let elParent: any = this._myCanvas; let objX: number = 0, objY: number = 0; while (elParent) { objX += elParent.offsetLeft; objY += elParent.offsetTop; elParent = elParent.offsetParent; } this._mouseX = allX - objX; this._mouseY = allY - objY; // clear the canvas //this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height); // calculate the rectangle width/height based // on starting vs current mouse position let width = this._mouseX - this._startX; let height = this._mouseY - this._startY; // draw a new rect from the start position // to the current mouse position this._ctx.fillRect(this._startX, this._startY, width, height); }; private selectionCanvasMouseOut = (event: MouseEvent) => { event.preventDefault(); event.stopPropagation(); // the drag is over, clear the dragging flag this._isDown = false; //this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height); }; //Il metodo findPosition definisce la posizione del cursore del mouse //relativa al canvas nel momento in cui avviene l'evento passato in input private setPosition(event: any, pixel: G.coordinates, canvasID: string) { let image = G.Image.getInstance(); let scrollTOP: number = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop; let scrollLEFT: number = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft; let allX: number = event.clientX + scrollLEFT; let allY: number = event.clientY + scrollTOP; let elParent: any = document.getElementById(canvasID); let objX: number = 0, objY: number = 0; while (elParent) { objX += elParent.offsetLeft; objY += elParent.offsetTop; elParent = elParent.offsetParent; } pixel.x = Math.floor((allX - objX - 1) / image.pixelDim) + image.newOrigin.x; pixel.y = Math.floor((allY - objY - 1) / image.pixelDim) + image.newOrigin.y; } drawImg(image: G.Image, pixel1: G.coordinates, pixel2: G.coordinates, xMinRange: number, xMaxRange: number, callback?: () => void) { this._pixel1 = pixel1; this._pixel2 = pixel2; //alert("disegno in corso"); //numero di pixel per dimensione let nPixelX: number = this._pixel2.x - this._pixel1.x + 1; let nPixelY: number = this._pixel2.y - this._pixel1.y + 1; //dimensione dei canvas let mappaPannelDim: any = document.querySelector("#mappa-pannel").getBoundingClientRect(); let mappaWidth: number = mappaPannelDim.right - mappaPannelDim.left - 40; let mappaHeigth: number = 400; //dimensione reale dei pixel let dimPixelx: number = Math.floor(mappaWidth / nPixelX); let dimPixely: number = Math.floor(mappaHeigth / nPixelY); image.pixelDim = dimPixelx < dimPixely ? dimPixelx : dimPixely; //dimensioni esatte dei canvas this._myCanvas.height = nPixelY * image.pixelDim; this._myCanvas.width = nPixelX * image.pixelDim; this._selectionCanvas.height = nPixelY * image.pixelDim; this._selectionCanvas.width = nPixelX * image.pixelDim; let ctx = this._myCanvas.getContext("2d"); //contesto del canvas if (xMaxRange - xMinRange >= image.channelDepth) { //range completo let max: number = 0; //massimo relativo o assoluto if (image.rePrint) { max = Help.findMax(image.nOfCounts, this._pixel1, this._pixel2); } else { max = image.maxAbsolute; } max *= parseInt(this._saturationSlider.value) / 100; this.drawCanvas(image, image.nOfCounts, max); } else { //range parziale (solo alcuni canali) let xMinRangeCh: number = Math.floor((xMinRange * 1000 + this._image.calibration.b) / this._image.calibration.a - 1); //16 let xMaxRangeCh: number = Math.floor((xMaxRange * 1000 + this._image.calibration.b) / this._image.calibration.a - 1); //16371 //calcolo il numero di conteggi solo dei canali selezionati let nOfCountsRelative: number[][]; nOfCountsRelative = new Array(image.width); for (let i: number = 0; i < image.width; i++) { nOfCountsRelative[i] = new Array(image.height); for (let j: number = 0; j < image.height; j++) { nOfCountsRelative[i][j] = Help.sumVect(image.DataMatrix[i][j], xMinRangeCh, xMaxRangeCh); } } //calcolo il massimo let max: number = 0; if (image.rePrint) { max = Help.findMax(nOfCountsRelative, this._pixel1, this._pixel2); } else { max = Help.findMax(nOfCountsRelative, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }); } max *= parseInt(this._saturationSlider.value) / 100; if(max == 0) alert("WARNING: max value is 0"); else this.drawCanvas(image, nOfCountsRelative, max); } if (typeof (callback) != typeof (undefined)) callback(); } private drawCanvas(image: G.Image, noc, max) { //controllo il valore della trasparenza let setTrsp: number = 1 - parseInt(this._transparencySlider.value) / 100; //scorro tutti i pixel: ne determino il colore e li disegno let color: string = ""; for (let i: number = this._pixel1.x; i <= this._pixel2.x; i++) { for (let j: number = this._pixel1.y; j <= this._pixel2.y; j++) { let intensity: number = noc[i][j] / max; if (intensity < 1 / 5) //blu color = "rgba(0, 0, " + Math.floor(intensity * 5 * 255) + "," + setTrsp + ")"; else if (1 / 5 <= intensity && intensity < 2 / 5) //blu+verde color = "rgba(0, " + Math.floor((intensity - 1 / 5) * 5 * 255) + ",255, " + setTrsp + ")"; else if (2 / 5 <= intensity && intensity < 3 / 5) // verde-blu color = "rgba(0, 255, " + (255 - Math.floor((intensity - 2 / 5) * 5 * 255)) + ", " + setTrsp + ")"; else if (3 / 5 <= intensity && intensity < 4 / 5) //verde + rosso color = "rgba(" + Math.floor((intensity - 3 / 5) * 5 * 255) + ",255,0," + setTrsp + ")"; //rosso -verde else color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")"; this._ctx.fillStyle = color; this._ctx.fillRect((i - this._pixel1.x) * image.pixelDim, (j - this._pixel1.y) * image.pixelDim, image.pixelDim, image.pixelDim); } } //console.log(color); image.rePrint = false; //annullo rePrint this._ctx.fillStyle = "rgba(0, 110, 255, 0.25)"; this._isDown = false; } }