Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class BluePrintInput {
- constructor(blueprint,settings) {
- settings = settings || {};
- this.blueprint = blueprint;
- this.canvas = this.blueprint.canvas;
- this.ctx = this.blueprint.ctx;
- // Like CSS Properties
- this.top = settings.top || 0;
- this.left = settings.left || 0;
- this.width = settings.width || 150;
- this.height = settings.height || 17;
- this.paddingTop = settings.paddingTop || 0;
- this.paddingLeft = settings.paddingLeft || 0;
- this.paddingBottom = settings.paddingBottom || 0;
- this.paddingRight = settings.paddingRight || 0;
- this.marginTop = settings.marginTop || 0;
- this.marginLeft = settings.marginLeft || 0;
- this.marginBottom = settings.marginBottom || 0;
- this.marginRight = settings.marginRight || 0;
- this.background = settings.background || '#fff';
- this.hover_background = settings.hover_background || '#00f';
- this.focus_background = settings.focus_background || '#f00';
- this.borderSize = settings.borderSize || 1;
- this.borderColor = settings.borderColor || '#000';
- this.hover_borderColor = settings.hover_borderColor || '#000';
- this.focus_borderColor = settings.focus_borderColor || '#000';
- this.radius = settings.radius || 0;
- this.color = settings.color || '#000';
- this.selectColor = settings.selectColor || '#08f';
- // Font
- this.fontSize = 15;
- this.fontFamily = 'Verdana';
- this.font = this.fontSize+'px '+this.fontFamily;
- // Caret
- this.caretX = 0;
- this.caretY = 0;
- this.caretWidth = settings.caretWidth || 1;
- this.caretHeight = settings.caretHeight || this.fontSize;
- this.caretColor = settings.caretColor || this.color;
- this.caretTime = Date.now();
- this.caretTick = settings.caretTick || 500;
- this.caretIsVisible = false;
- this.caretStart = 0;
- this.caretEnd = 0;
- this.caretSelection = false;
- // Focus & Blur event register
- this.onfocus = typeof settings.onfocus === 'function' ? settings.onfocus : null;
- this.onblur = typeof settings.onblur === 'function' ? settings.onblur : null;
- // Key Event
- this.onkeydown = typeof settings.onkeydown === 'function' ? settings.onkeydown : null;
- this.onkeyup = typeof settings.onkeyup === 'function' ? settings.onkeyup : null;
- // Onchange Event
- this.onchange = typeof settings.onchange === 'function' ? settings.onchange : null;
- // overflow
- this.overflowX = 0;
- this.value = settings.value || '';
- this.focusValue = this.value;
- this.isFocus = false;
- this.canblur = false;
- this.isMouseDown = false;
- }
- /**
- * Check if the control can be copy (CTRL + C)
- * @return {Boolean} if the control can be copy
- */
- canCopy() {
- return this.caretEnd != this.caretStart;
- }
- /**
- * Check if the control can be cut (CTRL + X)
- * @return {Boolean} if the control can be cut
- */
- canCut() {
- return this.caretEnd != this.caretStart;
- }
- /**
- * Copy Data from input (CTRL + C)
- */
- copy() {
- var caretStart = this.caretStart < this.caretEnd ? this.caretStart : this.caretEnd;
- var caretEnd = this.caretStart < this.caretEnd ? this.caretEnd : this.caretStart;
- var value = this.value.slice(caretStart, caretEnd);
- var el = document.createElement('textarea');
- el.value = value;
- el.setAttribute('readonly', '');
- el.style.position = 'fixed';
- el.style.left = '-9999px';
- document.body.appendChild(el);
- el.select();
- document.execCommand('copy');
- document.body.removeChild(el);
- }
- /**
- * Cut Data from input (CTRL + X)
- */
- cut() {
- var caretStart = this.caretStart < this.caretEnd ? this.caretStart : this.caretEnd;
- var caretEnd = this.caretStart < this.caretEnd ? this.caretEnd : this.caretStart;
- this.copy();
- var caretStart = this.caretStart < this.caretEnd ? this.caretStart : this.caretEnd;
- var caretEnd = this.caretStart < this.caretEnd ? this.caretEnd : this.caretStart;
- this.value = this.value.slice(0,caretStart) + this.value.substring(caretEnd);
- if (this.caretStart > this.caretEnd) {
- this.caretStart = this.caretEnd;
- } else {
- this.caretEnd = this.caretStart;
- }
- }
- /**
- * Paste Data in input (CTRL + V) Event
- * @param {String} clipboard
- */
- onPaste(text) {
- if (text == '') return;
- // replace with content already selected
- if (this.canCopy()) {
- var caretStart = this.caretStart < this.caretEnd ? this.caretStart : this.caretEnd;
- var caretEnd = this.caretStart < this.caretEnd ? this.caretEnd : this.caretStart;
- this.value = this.value.slice(0,caretStart) + this.value.substring(caretEnd);
- if (this.caretStart > this.caretEnd) {
- this.caretStart = this.caretEnd;
- } else {
- this.caretEnd = this.caretStart;
- }
- }
- this.value = this.value.slice(0,this.caretEnd) + text + this.value.substring(this.caretEnd);
- this.caretEnd += text.length;
- this.caretStart = this.caretEnd;
- }
- /**
- * Event: When the control has the focus
- * @param {BluePrintInput} Event
- */
- onFocus(event) {
- this.isMouseDown = true;
- // Propagate the event
- if (!this.isFocus) {
- this.isFocus = true;
- this.focusValue = this.value;
- var _this = this;
- // extend the propagation outside
- if (this.onfocus != null) this.onfocus(this);
- // register key event
- this.blueprint.onkeydown = function(event){_this.onKeyDown(event);};
- this.blueprint.onkeyup = function(event){_this.onKeyUp(event);};
- // register paste event
- this.blueprint.onpaste = function(text){_this.onPaste(text);};
- }
- }
- /**
- * Event: When the control lost the focus
- * @param {BluePrintInput} Event
- */
- onBlur(event) {
- // Propagate the event
- if (this.isFocus) {
- this.isFocus = false;
- // extend the propagation outside
- if (this.onblur != null) this.onblur(this);
- // if value change, fired the event onchange
- if (this.focusValue != this.value) this.onChange(this);
- // unregister key event
- this.blueprint.onkeydown = null;
- this.blueprint.onkeyup = null;
- // unregister paste event
- this.blueprint.onpaste = null;
- }
- }
- /**
- * Event: When the value is changed
- * @param {BluePrintInput} Event
- */
- onChange(event) {
- if (this.onchange != null) this.onchange(event);
- }
- /**
- * Event: When user press down a key
- * @param {KeyboardEvent} Event
- */
- onKeyDown(event) {
- var key = event.key;
- var keyCode = event.keyCode;
- // CTRL + C
- if ((event.ctrlKey || event.metaKey) && keyCode == 67 && this.canCopy()) {
- this.copy();
- return;
- }
- // CTRL + X
- if ((event.ctrlKey || event.metaKey) && keyCode == 88 && this.canCut()) {
- this.cut();
- return;
- }
- if (event.ctrlKey || event.metaKey) return;
- if (key.length == 1) {
- this.value = this.value.slice(0,this.caretEnd) + key + this.value.substring(this.caretEnd);
- this.caretEnd++;
- this.caretStart = this.caretEnd;
- } else {
- switch (keyCode) {
- case 8: // Backspace
- if (this.value.length > 0) {
- if (this.caretStart == this.caretEnd) {
- this.value = this.value.slice(0,this.caretEnd-1) + this.value.substring(this.caretEnd);
- this.caretEnd--;
- this.caretStart = this.caretEnd;
- } else {
- var caretStart = this.caretStart < this.caretEnd ? this.caretStart : this.caretEnd;
- var caretEnd = this.caretStart < this.caretEnd ? this.caretEnd : this.caretStart;
- this.value = this.value.slice(0,caretStart) + this.value.substring(caretEnd);
- if (this.caretStart > this.caretEnd) {
- this.caretStart = this.caretEnd;
- } else {
- this.caretEnd = this.caretStart;
- }
- }
- }
- break;
- case 37: // Arrow Left
- if (this.caretEnd > 0) this.caretEnd--;
- this.caretStart = this.caretEnd;
- break;
- case 39: // Arrow Right
- if (this.caretEnd < this.value.length) this.caretEnd++;
- this.caretStart = this.caretEnd;
- break;
- default:
- }
- }
- if (this.onkeydown != null) this.onkeydown(event);
- }
- /**
- * Event: When user press up a key
- * @param {KeyboardEvent} Event
- */
- onKeyUp(event) {
- if (this.onkeyup != null) this.onkeyup(event);
- }
- /**
- * Overflow: translate
- * @param {Boolean} apply a translate
- * @return {Number} overflow translate
- */
- overflow(b) {
- if (BluePrintUtils.measureText(this.ctx,this.font,this.value.slice(0,this.caretEnd)) - this.overflowX > this.width) {
- this.overflowX += this.width;
- }
- if (BluePrintUtils.measureText(this.ctx,this.font,this.value.slice(0,this.caretEnd)) - this.overflowX < 0) {
- this.overflowX -= this.width / 2;
- }
- if (!b) this.ctx.translate(-this.overflowX,0);
- return this.overflowX;
- }
- /**
- * retrieve index of character in the whole string
- * @return {Number} index of char
- */
- getStartMouse() {
- var x = ( this.blueprint.mouseX - this.canvas.width/2 ) / this.blueprint.zoom - (this.blueprint.x + this.blueprint.mx);
- var over = this.overflow(true);
- var index = null;
- var value = this.value + " ";
- for (var i = 0; i < value.length; i++) {
- if (this.left + BluePrintUtils.measureText(this.ctx,this.font,value.slice(0,i)) > x + over) {
- index = i;
- break;
- }
- }
- return index == null ? this.value.length : index-1;
- }
- /**
- * draw Caret
- */
- drawCaret() {
- // blink the caret when focus
- if (this.isFocus && Date.now() - this.caretTime > this.caretTick) {
- this.caretTime = Date.now();
- this.caretIsVisible = this.caretIsVisible ? false : true;
- }
- // draw caret
- if (this.caretIsVisible && this.isFocus) {
- // update caret position
- this.caretX = BluePrintUtils.measureText(this.ctx, this.font, this.value.slice(0,this.caretEnd));
- this.caretIsVisible = true;
- this.ctx.save();
- this.blueprint.applyCamera(this.blueprint.x+this.blueprint.mx,this.blueprint.y+this.blueprint.my);
- this.ctx.translate(this.left,this.top);
- this.overflow();
- this.ctx.beginPath();
- this.ctx.rect(this.caretX,this.caretY+1,this.caretWidth,this.caretHeight);
- this.ctx.fillStyle = this.caretColor;
- this.ctx.fill();
- this.ctx.restore();
- }
- }
- /**
- * Draw Method
- * @param {Boolean} if a item is already overflown
- * @param {Boolean} disable drawing
- * @return {Boolean} return if mouse is overflown this item
- */
- draw(a,b) {
- var hover = false;
- this.ctx.save();
- this.blueprint.applyCamera(this.blueprint.x+this.blueprint.mx,this.blueprint.y+this.blueprint.my);
- // isHover ?
- this.ctx.roundRect(
- this.left-this.paddingLeft-this.borderSize,
- this.top-this.paddingTop-this.borderSize,
- this.width+this.paddingRight+this.paddingLeft+this.borderSize*2,
- this.height+this.paddingBottom+this.paddingTop+this.borderSize*2,
- this.radius
- );
- var hover = !a && this.ctx.isPointInPath(this.blueprint.mouseX,this.blueprint.mouseY);
- // Border
- this.ctx.roundRect(
- this.left-this.paddingLeft-this.borderSize,
- this.top-this.paddingTop-this.borderSize,
- this.width+this.paddingRight+this.paddingLeft+this.borderSize*2,
- this.height+this.paddingBottom+this.paddingTop+this.borderSize*2,
- this.radius
- );
- this.ctx.fillStyle = this.isFocus ? this.focus_borderColor : hover ? this.hover_borderColor : this.borderColor;
- if (!b) this.ctx.fill();
- // Background
- this.ctx.roundRect(
- this.left-this.paddingLeft,
- this.top-this.paddingTop,
- this.width+this.paddingRight+this.paddingLeft,
- this.height+this.paddingBottom+this.paddingTop,
- this.radius
- );
- this.ctx.fillStyle = this.isFocus ? this.focus_background : hover ? this.hover_background : this.background;
- if (!b) this.ctx.fill();
- // Overflow hidden
- this.ctx.clip();
- // translate
- this.overflow();
- // draw selection
- if (this.caretEnd != this.caretStart) {
- this.ctx.beginPath();
- var color = BluePrintUtils.hexToRgb(this.selectColor);
- var caretStart = this.caretStart < this.caretEnd ? this.caretStart : this.caretEnd;
- var caretEnd = this.caretStart < this.caretEnd ? this.caretEnd : this.caretStart;
- this.ctx.rect(this.left+BluePrintUtils.measureText(this.ctx,this.font,this.value.slice(0,caretStart)),this.top,BluePrintUtils.measureText(this.ctx,this.font,this.value.slice(caretStart,caretEnd)),this.fontSize+2);
- this.ctx.fillStyle = 'rgba('+color.r+','+color.g+','+color.b+',0.8)';
- if (!b) this.ctx.fill();
- }
- // Remove Focus
- if (!hover && !this.blueprint.mouseIsLeftDown && !this.canblur && this.isFocus) {
- this.isMouseDown = false;
- this.canblur = 1;
- }
- if (hover && !this.blueprint.mouseIsLeftDown) {
- this.isMouseDown = false;
- }
- if (this.canblur == 1 && this.blueprint.mouseIsLeftDown) {
- this.canblur = 2;
- }
- if (this.canblur == 2 && this.blueprint.mouseIsLeftDown) {
- this.onBlur();
- this.canblur = false;
- }
- // is Focused ?
- if (hover && this.blueprint.mouseIsLeftDown) {
- this.onFocus();
- }
- if (this.isFocus && this.isMouseDown) {
- var mouseX = (this.blueprint.mouseX - this.canvas.width/2) / this.blueprint.zoom - (this.blueprint.x+this.blueprint.mx);
- if (
- mouseX > this.left &&
- mouseX < this.left + this.width) {
- // retrieve the index of character in the string
- this.caretEnd = this.getStartMouse();
- // show now the caret
- this.caretTime = 0;
- this.caretIsVisible = false;
- // starting selection
- if (!this.caretSelection) {
- this.caretStart = this.caretEnd;
- }
- this.caretSelection = true;
- } else {
- if (mouseX < this.left) {
- if (this.caretEnd > 0) {
- this.caretEnd--;
- }
- } else {
- if (this.caretEnd < this.value.length) {
- this.caretEnd++;
- }
- }
- }
- }
- // Disable Selection
- if (!this.blueprint.mouseIsLeftDown) {
- this.caretSelection = false;
- }
- // Draw value
- this.ctx.textBaseline = 'middle';
- this.ctx.font = this.font;
- this.ctx.fillStyle = this.color;
- if (!b) this.ctx.fillText(this.value,this.left,this.top+this.height/2+2);
- // Draw caret
- if (!b) this.drawCaret();
- this.ctx.restore();
- return hover || this.isFocus;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement