empty space when dragging it - sass

I have a simple custom splitter that works great. However, I have a little issue:
The first time I drag the splitter down it adds an empty space, after that I can drag with it with no problem (up or down). Can anyone tell me what may be causing the extra space issue? Thanks a lot in advance!
Here's the code:
PLUNKER
#HostListener('document:mousemove', ['$event'])
onMouseMove(event: MouseEvent) {
if (!this.grabber) {
return;
}
this.resizer(event.clientY - this.oldY);
this.oldY = event.clientY;
}

First, you should consider using clientHeight instead of offsetHeight because CSS height is calculated as clientHeight minus CSS paddings* while offsetHeight also includes borders height
clientHeight = content height + paddings
offsetHeight = clientHeight + borders height
Now you have two options
1) Use clientHeight together with box-sizing: border-box; (paddings will be included in css height)
ts
ngOnInit() {
this.height = parseInt(this.el.nativeElement.parentNode.clientHeight);
}
css
.textarea {
box-sizing: border-box;
}
Example
2) Use content height
ngOnInit() {
const elem = this.el.nativeElement.parentNode;
const computedStyle = getComputedStyle(elem);
const paddingsHeight = parseFloat(computedStyle.paddingTop)
+ parseFloat(computedStyle.paddingBottom)
this.height = parseFloat(elem.clientHeight) - paddingsHeight;
}
Example

Related

I have a nice way to speed up scatter plots in d3 if someone can help me with panning

This is related a question I posted earlier
d3 got slow all of a sudden
In that question, I pointed out a slowdown in d3.js that happened a few versions back (3.2). The slowdown is most noticeable in IE, but is definitely there in other browsers as well. The problem comes up when clicking the mouse, and it takes a long time (2.5 seconds in IE) before the mouse event even gets to our code. The problem is caused by the amount of data in the plot. Simple scatterplots do not have this problem.
No answers were forthcoming on the topic, so I am solving the problem a different way. I am using nested divs like this:
<div class = "plot_container" id = "thing_plot_container">
<div class = "ghost_container" id = "thing_ghost_container"></div>
</div>
And this set of styles:
div.plot_container {
position: relative;
margin:0px; padding:0px; /* insurance */
border: none;
}
div.ghost_container {
position: absolute;
margin:0px; padding:0px; /* insurance */
top: 0px;left: 0px;
width:0px; height:0px; /* width and height are irrelevant */
overflow: visible; /* insurance */
border: none;
}
This lets me put my d3.js plot in the outer plot_container div and a separate div in ghost_container that I attach mouse events to.
Here is the rest of the relevant code. First the main d3 svg:
var div = d3.select("body").append("div")
.attr("class","tooltip")
.style("opacity",0);
var viewportWidth = window.innerWidth - 40;
var viewportHeight = window.innerHeight - 80;
var svg = d3.select("#thing_plot_container").append("svg")
.attr("id", "mySVG")
.attr("width",viewportWidth)
.attr("height",viewportHeight)
.call(zoom)
.on("dblclick.zoom", null)
//.on("mousewheel.zoom", zoomFun)//for FF
.on("DOMMouseScroll.zoom", zoomFun)//for FF(1.7 or earlier)
.on("wheel.zoom", zoomFun)
.append("g")
.attr("class", "main")
.attr("transform","translate("+(left_shift)+","+(top_shift)+")");
And this is the ghost div overlaying the regular div:
//
// set up ghost/overlay svg element to handle mouse clicks
//
var use_overlay = true;
var catcherWidth = viewportWidth;
var catcherHeight = viewportHeight;
var svgns = "http://www.w3.org/2000/svg";
if (use_overlay == true){
var mouse_div = document.getElementById('thing_ghost_container');
var mouse_svg_container = document.createElementNS(svgns, "svg");
console.log('replace these magic numbers with viewportWidth and height');
mouse_svg_container.setAttribute("width",catcherWidth+"px"); // clips on chrome/ff if not done this way
mouse_svg_container.setAttribute("height",catcherHeight+"px");
mouse_div.appendChild(mouse_svg_container);
var rect_mouse = document.createElementNS(svgns, "rect");
rect_mouse.setAttribute("x",0);
rect_mouse.setAttribute("y",0);
rect_mouse.setAttribute("fill","blue");
rect_mouse.setAttribute("fill-opacity",0.05); // set this to 0.0 when working
rect_mouse.setAttribute("width", catcherWidth+"px");
rect_mouse.setAttribute("height", catcherHeight+"px");
rect_mouse.setAttribute("onclick", "ghost_click(evt)"); // this HAS to be evt to get all browsers cooperating
// leaving these mouse down/mouseup events to the original svg does not work. The overaly svg kills it
rect_mouse.setAttribute("onmousedown", "ghost_mousedown(evt)");
rect_mouse.setAttribute("onmouseup", "ghost_mouseup(evt)");
mouse_svg_container.appendChild(rect_mouse)
}
This works very well as far as it goes. This completely sidesteps the slowdown issue with element-heavy plots like scatter plots. The mouse click event immediately gets served this way. The problem is that I cannot grab with the mouse and pan my chart! I need help getting the mouse events passed into the d3 pan/zoom code.
Here is a fiddle showing what I have so far:
https://jsfiddle.net/pkrouse/5sbqchnn/

Qt5 QML ListView contents zoom

I am trying to implement an image viewer (sort of):
model/view approach
using both c++ and qml
the images are just a ListView filled up with Image (delegate) items
Here is a piece of code:
property double zoomFactor: 1.5;
property double imgScale: 1;
CustomToolBar
{
id: toolBar
onZoomInSignal:
{
imgScale = imgScale*zoomFactor;
}
onZoomOutSignal:
{
imgScale = imgScale/zoomFactor;
}
onZoomFitSignal:
{
imgScale = 1;
}
}
Rectangle
{
id: bgRect
Layout.fillWidth: true
Layout.fillHeight: true
color: "Grey"
anchors.margins: 10
ScrollView
{
id: scrollView
anchors.fill: parent
ListView
{
id: listView
anchors.fill: parent
clip: true
spacing: 10
model: listItemModel
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 10
boundsBehavior: Flickable.StopAtBounds
delegate: Image
{
id: item_id
anchors.horizontalCenter: parent.horizontalCenter
source: item_img_path + "/" + Math.random()
scale: imgScale
}
}
}
}
The images are loaded correctly, I need to be able to zoom them.
In order to zoom I just modify the scale property of the Image delegate.
Images not scaled (scale = 1) CORRECT:
Images unzoomed (scale = 1/1.5) WRONG! images spacing (?) is being incremented:
Images zoomed (scale = 1.5) WRONG! images overlap:
As you can see, zoom minus increments the spacing (I'm quite not sure it is really the spacing) between the images, and zoom plus overlaps the images.
Furthermore, it would be nice to have the horizontal scrollbar for the ScrollView when zooming in, but I cannot achieve this.
Can anyone help me?
Thanks
EDIT:
Following the solution proposed by grillvott the images are zoomed in/out correctly, but the whole ListView is getting smaller/bigger with them:
The result should be instead something like this (gimp mode ON):
Any idea?
I don't think that scale will take any boundaries into consideration. You could encapsulate the image and use fillMode to make sure the image scales accordingly:
delegate: Item {
anchors.horizontalCenter: parent.horizontalCenter
width: img.sourceSize.width * imgScale
height: img.sourceSize.height * imgScale
Image {
id: img
anchors.fill: parent
source: item_img_path + "/" + Math.random()
fillMode: Image.Stretch
}
}

Display existing images as cropped thumbnail (and keep aspect ratio) in Dropzone.js instead of squished images?

When I upload images to Dropzone.js they keep their aspect ratio and just get cropped.
They look like this which is good:
When I use this code to display previously uploaded files:
...
$.getJSON('files/list-all', function(data) {
$.each(data, function(index, val) {
var mockFile = { name: val.name, size: val.size };
thisDropZone.options.addedfile.call(thisDropZone, mockFile);
thisDropZone.options.thumbnail.call(thisDropZone, mockFile, "uploads/" + val.id + "." + val.extension);
});
});
...
I get these squished versions of the images:
So the question is how do I get the thumbnails to look good like they when you upload?
Same problem, my workaround. It's not the cropped effect, but keeps the aspect ratio. It also centers the picture within the frame.
It goes by implementing the 'fileadded' listener in the 'init' option on dropzone creation. Then, adjust the image.
Steps:
Finds the IMG element in the preview frame;
Waits for the image to be loaded (the dimensions aren't available before);
Retrieves its dimensions;
Computes the aspect ratio, pretended dimensions and position;
Defines inline css (overriding the css class 'dropzone').
Listing:
var thisDropZone = new Dropzone($("#thisDropZone"), {
url: "files/upload",
init: function () {
this.on("addedfile", function (file) {
var img = $(file.previewTemplate).find("img");
img[0].onload = function () {
var max = this.width > this.height ? this.width : this.height;
var ratio = 100.0 / max;
var width = this.width * ratio;
var height = this.height * ratio;
img.css({
width: width + "px",
height: height + "px",
top: ((100 - height) / 2) + "px",
left: ((100 - width) / 2) + "px"
});
};
}
}
});
The recurring magic number '100' is the 'width' and 'weight' property values for IMG element, as defined by the css class '.dropzone' in theirs default stylesheet 'dropzone.css'.
To achieve this, you can't call the 'addedfile' event like you do; you have to trigger it like this:
$.getJSON('files/list-all', function(data) {
$.each(data, function(index, val) {
var mockFile = { name: val.name, size: val.size };
thisDropZone.emit("addedfile", mockFile);
thisDropZone.emit("thumbnail", mockFile, "uploads/" + val.id + "." + val.extension);
});
});
Hope it helps!

Center an image while keeping full screen height

I want an image to remain the full height of the browser window even if the window is made smaller. This seems to do the trick. However, at current, the image remains anchored to the left side of the screen with the right side of the image being what is lost as the window resizes. Instead, I'd like the image to chop from both sides leaving a centered image. Is this possible?
Note: I need the image in a div, not set as background.
Thanks!
Here is the CSS I'm currently using:
.div
{
min-height:100%;
min-width:100%;
text-align:center;
overflow: hidden;
margin: 0 auto;
}
.img
{
min-height:100%;
min-width:100%;
margin: 0 auto;
}
something like this ?
var origWidth;
$(document).ready(function() {
origWidth = $(window).width(); //store the window's width when the document loads
origHeight = $(window).height(); //store the window's width when the document loads
});
$(window).resize(function() {
var curWidth = $(window).width(); //store the window's current width
var curHeight = $(window).width(); //store the window's current height
var deltaTop = (curWidth- origWidth);
var deltaLeft = (curHeight- origHeight);
$("#image1").offset({top:($("#image1").offset().top + deltaTop)});
$("#image1").offset({left:($("#image1").offset().top + deltaLeft)});
origWidth = curWidth;
origHeight =curHeight;
});
JsFiddle
(inspired by this question's solution: link)

Circular Slider using Jquery

How to slide mouse in circular ?
Draw an arc and a mouse pointer in a canvas. Mouse should be drag gable on the circular path?
//function to create mouse event to drag the mouse hover the arc
function mousedrag() {
var canvasoffset = $(this.canvas).offset();
var offsetX = canvasoffset.left;
var offsetY = canvasoffset.top;
var mouseX = parseInt(e.offsetX || e.clientX - offsetX);
var mouseY = parseInt(e.offsetY || e.clientY - offsetY);
var radius = this.width / 2;
var twoPI = 2 * Math.PI;
var toRad = twoPI / 360;
var r_width = this.width * 0.8;
var radial_Angle = Math.atan2(mouseY - radius,mouseX - radius);
var p_side_x = radius + r_width * Math.cos(radial_Angle);
var p_side_y = radius + r_width * Math.sin(radial_Angle);
var p_mouse_x = radius + ((r_width+10) * Math.sin(radial_Angle));
var p_mouse_y = radius + ((r_width+ 10) * Math.sin(radial_Angle));
var imgData = this.ctx.getImageData(p_side_x, p_side_y, 1, 1).data;
var selectedColor = new Color(imgData[0], imgData[1], imgData[2]);
clearDraw();
renderSpectrum();
renderMouse(p_side_x, p_side_y, p_mouse_x, p_mouse_y);
}
mouse handle does not slide properly.
You can't actually force the mouse to be constrained into a circle.
But you can calculate the mouse position relative to a centerpoint.
// define a centerpoint
var cx=150;
var cy=150;
var angleVersusCenter=0;
// listen for mouse moves
function handleMouseMove(e){
// get the mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// set the current radian angle of the mouse
// versus the centerpoint
var angleVersusCenter = Math.atan2( mouseY-cy, mouseX-cx );
}
A Demo: http://jsfiddle.net/m1erickson/z6cQB/
Here is the jQuery roundSlider plugin for your requirement, check here http://roundsliderui.com/. This might helps you.
This roundslider having the similar options like the jQuery ui slider. It support default, min-range and range slider type. Not only the round slider it also supports various circle shapes such as quarter, half and pie circle shapes.
For more details check the demos and documentation page.
Please check the demo from jsFiddle.
Live demo:
$("#slider").roundSlider({
width: 10,
handleSize: "+8",
value: "40"
});
$("#half-slider").roundSlider({
width: 10,
circleShape: "half-top",
handleSize: "+8",
value: "80"
});
.rs-control {
display: inline-block;
float: left;
margin-left: 30px;
}
.rs-control .rs-path-color {
background-color: #e9e9e9;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.js"></script>
<link href="https://cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.css" rel="stylesheet"/>
<div id="slider" class="rslider"></div>
<div id="half-slider" class="rslider"></div>
Screenshots with different appearances:
Check more details about different theme from here.

Resources