How to make progress bar match curve of parent - html

I have a toast notification with a progress bar like the following image and I like the rounded corners but I can't figure out how to hide the portion of the loading bar that goes outside the rounded corners. How would I do that given the setup in this example. I would also like to know how I could reverse the direction of the indicator so it starts full and goes toward empty then the notification disappears. Lobibox doesn't appear to have either of these options out of the box but I would really like to add them. Thanks for the help!
Here is a sample of a lobibox notification:
Lobibox.notify('success', {
size: 'mini',
rounded: true,
delayIndicator: true,
msg: 'Project Saved Successfully!',
iconSource: 'fontAwesome',
position: 'top right',
delay: 50000,
});

you can override the css
Lobibox.notify('success', {
size: 'mini',
rounded: true,
delayIndicator: false,
msg: 'Project Saved Successfully!',
iconSource: 'fontAwesome',
position: 'top right',
delay: 20000,
delayIndicator: true
});
body {
background-color: black;
}
.lobibox-notify .lobibox-delay-indicator {
left: 22px !important;
width: 360px;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lobibox#1.2.7/dist/css/lobibox.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lobibox#1.2.7/dist/js/lobibox.min.js"></script>

Figured out how to reverse the indicator direction. Find the _addDelay function in the source and overwrite it with my updated version below. This adds the ability to set options.reverseDelayIndicator = true to reverse the direction of the indicator. It also allows you to have the indicator display properly on rounded and square edge notifications if you include the css snippet below in your solution.
var _addDelay = function ($el) {
if (!me.$options.delay) {
return;
}
if (me.$options.delayIndicator) {
var delay = $('<div class="lobibox-delay-indicator"><div></div></div>');
if (me.$options.rounded) {
delay.addClass("lobibox-delay-rounded");
} else {
delay.removeClass("lobibox-delay-rounded");
}
$el.append(delay);
}
var time = 0;
var interval = 1000 / 30;
var currentTime = new Date().getTime();
var timer = setInterval(function () {
if (me.$options.continueDelayOnInactiveTab) {
time = new Date().getTime() - currentTime;
} else {
time += interval;
}
if (me.$options.reverseDelayIndicator) {
var width = 100 - (100 * time / me.$options.delay);
if (width <= 0) {
width = 0;
me.remove();
timer = clearInterval(timer);
}
} else {
var width = 100 * time / me.$options.delay;
if (width >= 100) {
width = 0;
me.remove();
timer = clearInterval(timer);
}
}
if (me.$options.delayIndicator) {
delay.find('div').css('width', width + "%");
}
}, interval);
if (me.$options.pauseDelayOnHover) {
$el.on('mouseenter.lobibox', function () {
interval = 0;
}).on('mouseleave.lobibox', function () {
interval = 1000 / 30;
});
}
};
CSS To allow both rounded and square indicators display properly:
.lobibox-notify .lobibox-delay-indicator.lobibox-delay-rounded {
left: 22px;
width: calc(100% - 44px);
}

Related

initializing a dynamic background

What my code does:
stays blank for 3 seconds
displayes index 1 of my list of image
loops through the list and restarts at index 0
<div id="background" class="text-center background">
<script type = "text/javascript">
var background = document.getElementById("background");
var currentPos = 0;
var imagesb = ["/images/indeximg0.jpg", "/images/indeximg11.jpg", "/images/indeximg33.jpg", "/images/indeximg44.jpg", "/images/indeximg55.jpg"], i = 0;
function changeimage()
{
if (++currentPos >= imagesb.length)
currentPos = 0;
background.style.backgroundImage = "url(" + imagesb[currentPos] + ")";
}
setInterval(changeimage, 3000);
</script>
</div>
What I want it to do:
no 3 second blank background delay
starts with index 0
What I tried:
I set currentPos = 4
this fixed the issue with the first image being displayed but the 3 second delay was still there. I also don't like this way of doing it because I would have to manually change currentPos if i add or remove images to the list
I tried to initialize my background before the first div to fix the 3 second back background with he following code:
<script type = "text/javascript">
background.style.backgoundImage= "url(/images/indeximg0.jpg)";
</script>
nothing changed. still had the 3 second delay
You should
Call the function once before the setInterval() and
When doing ++currentPos you are actually incrementing the variable so the first time you set the background, the value is already 1. The easiest way to change that is to set the background before your if test.
var background = document.getElementById("background");
var currentPos = 0;
var imagesb = ["https://via.placeholder.com/100", "https://via.placeholder.com/200", "https://via.placeholder.com/300"];
function changeimage() {
background.style.backgroundImage = "url(" + imagesb[currentPos] + ")";
if ((++currentPos) >= imagesb.length) {
currentPos = 0;
}
}
changeimage();
setInterval(changeimage, 1000);
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
.background {
height: 100%;
width: 100%;
}
<div id="background" class="text-center background"></div>

How do I force the pointer icon to 'grab', override underlying cursor styles while panning?

When I set the css of the container to 'grab' I see that it changes, but most of the viewport contains divs with pointer 'hand', which override it.
I want to give the impression that the grab is strictly for panning the contents of the viewport and nothing else.
Some ideas:
use !important (but Javascript css doesn't support that).
Use an invisible or 0 opacity div for panning mode (I am going to try this
one.
Something better that is commonly used that I don't know about
yet.
I wound up creating a jsFiddle by modifying one that I found which was doing something similar.
var scale = 1.0;
var drag = {
elem: null,
x: 0,
y: 0,
state: false
};
var delta = {
x: 0,
y: 0
};
$(document).mousedown(function(e) {
if (!drag.state) {
let $workspace = $('#workspace');
let $workspaceContents = $('.workspace_contents');
$('#pan-screen').css({
width: $workspaceContents.width,
height: $workspaceContents.height
});
drag.elem = $('.workspace-contents');
drag.x = e.pageX;
drag.y = e.pageY;
drag.state = true;
}
return false;
});
$(document).mousemove(function(e) {
if (drag.state) {
delta.x = e.pageX - drag.x;
delta.y = e.pageY - drag.y;
var cur_offset = $(drag.elem).offset();
$(drag.elem).offset({
left: (cur_offset.left + delta.x),
top: (cur_offset.top + delta.y)
});
drag.x = e.pageX;
drag.y = e.pageY;
}
});
$(document).mouseup(function() {
if (drag.state) {
drag.state = false;
}
});
solution fiddle:
https://jsfiddle.net/davidjmcclelland/t51b96em/27/

How to move 3D model on Cesium

I wanted to move the model dynamically using keyboard shortcuts. I could not find relevant article on that.
So for now, I'm trying to move the model on click. When click on the model. The model has to move in one direction (increment the value 1 on tick). Find below the sandcastle code for that.
var selectedMesh; var i=0;
var viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false,
selectionIndicator: false
});
var handle = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
function createModel(url, height) {
viewer.entities.removeAll();
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, heading, pitch, roll);
var entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
minimumPixelSize: 128
}
});
viewer.trackedEntity = entity;
viewer.clock.onTick.addEventListener(function () {
if (selectedMesh) {
console.log("Before 0 : " + selectedMesh.primitive.modelMatrix[12]);
selectedMesh.primitive.modelMatrix[12] = selectedMesh.primitive.modelMatrix[12] + 1;
console.log("After 0 : " + selectedMesh.primitive.modelMatrix[12]);
}
});
}
handle.setInputAction(function (movement) {
console.log("LEFT CLICK");
var pick = viewer.scene.pick(movement.position);
if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
if (!selectedMesh) {
selectedMesh = pick;
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
var options = [{
text: 'Aircraft',
onselect: function () {
createModel('../../SampleData/models/CesiumAir/Cesium_Air.bgltf', 5000.0);
}
}, {
text: 'Ground vehicle',
onselect: function () {
createModel('../../SampleData/models/CesiumGround/Cesium_Ground.bgltf', 0);
}
}, {
text: 'Milk truck',
onselect: function () {
createModel('../../SampleData/models/CesiumMilkTruck/CesiumMilkTruck.bgltf', 0);
}
}, {
text: 'Skinned character',
onselect: function () {
createModel('../../SampleData/models/CesiumMan/Cesium_Man.bgltf', 0);
}
}];
Sandcastle.addToolbarMenu(options);
When I click, the model is moving for the first time. After that, It stays on the same place. I've printed the value in the console. It seems the value is not changing. I'm not sure about the problem here. or I'm implementing the transformation wrongly.
If you keep track of the current lat and lon of the entity, and adjust that lat and lon based on user input, all you need to do is update the orientation of the entity.
var lon = // the updated lon
var lat = // updated lat
var position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
// create an orientation based on the new position
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, heading, pitch, roll);
Then you just need to update the orientation of the entity.
entity.orientation = orientation;
By changing the value, the models orientation, and therefore position will get updated.

Animate css progress bar without jumping between updates?

I'm using this on my site …
<progress id='video-progress' min='0' max='100' value=''></progress>
This is the entire styling of the element …
#video-progress {
-webkit-appearance: none;
border: none;
position:fixed;
bottom:0;
left:0;
height:3px;
width:100%;
z-index:1;
}
So all it does is move from 0 to 100% screen width on the bottom of the page.
The progress bar is updated via Javascript.
However since my video is only 30 seconds long, the single steps of updates are executed as "jumps" for the progress bar. So there is no smooth motion of the bar.
Any idea how I could animate the progress bar or smooth it between the updated steps?
UPDATE:
JavaScript … 
function updateProgressBar() {
var progressBar = document.getElementById('video-progress');
var percentage = Math.floor((100 / fmVideo.duration) * fmVideo.currentTime);
progressBar.value = percentage;
}
You could animate it by incrementing its value every 15 millisecond using setInterval and stop incrementing if the value is greater than percentage using clearInterval.
This code extracts the current value and increments it until it reaches the percentage value.
Note: percentage is manually set to 70.
var progressBar = document.getElementById('video-progress');
function updateProgressBar() {
var percentage = 70;
var curr = progressBar.value;
var update = setInterval(function() {
if (curr > percentage) {
clearInterval(update);
}
progressBar.value = curr++;
}, 15)
}
updateProgressBar();
#video-progress {
-webkit-appearance: none;
border: none;
position: fixed;
bottom: 0;
left: 0;
height: 3px;
width: 100%;
z-index: 1;
}
<progress id='video-progress' min='0' max='100' value=''></progress>
This works perfectly for me!
function smoothProgress(e) {
var id = $("#"+e.data.id),
dur = 5000,
seq = 100,
max = parseInt( id.attr("max"), 10),
chunk = max / dur * seq,
loop = setInterval(function() {
if( id.val() < max )
id.val( id.val() + chunk );
else
clearInterval(loop);
}
}, seq);
}
$(document).ready(function() {
$("#launch").on("click", {id: $("progress").attr("id")}, smoothProgress);
});
Of course, you can adjust the dur parameter or retrieve it dynamically based on your video's duration, as well as the seq parameter (the lower, the smoother).
Here is a fiddle for demo.

Fabric.js clipping individual objects dynamically

I am dynamically adding a rect element to crop/clip (using clipTo) a selected element,
It works perfect at the first time but when i add a second element to the canvas and begin to crop the second element the first element looses the crop/clip. Below is my code, there are 2 buttons 1 to start crop/clip (places a dynamic rect over the element to be cropped) second to do the cropping/clipping.
$('#crop').on('click', function (event) {
var left = el.left - object.left;
var top = el.top - object.top;
left *= 1;
top *= 1;
var width = el.width * 1;
var height = el.height * 1;
object.clipTo = function (ctx)
{
ctx.rect(-(el.width/2)+left, -(el.height/2)+top, parseInt(width*el.scaleX), parseInt(el.scaleY*height));
}
for(var i=0; i<$("#layers li").size();i++)
{
canvas.item(i).selectable= true;
}
disabled = true;
canvas.remove(canvas.getActiveObject());
lastActive = object;
canvas.renderAll();
});
$('#startCrop').on('click',function(){
canvas.remove(el);
if(canvas.getActiveObject())
{
object=canvas.getActiveObject();
if (lastActive && lastActive !== object) {
lastActive.clipTo = null;
}
el = new fabric.Rect
({
fill: 'rgba(0,0,0,0.3)',
originX: 'left',
originY: 'top',
stroke: '#ccc',
strokeDashArray: [2, 2],
opacity: 1,
width: 1,
height: 1,
borderColor: '#36fd00',
cornerColor: 'green',
hasRotatingPoint:false
});
el.left=canvas.getActiveObject().left;
selection_object_left=canvas.getActiveObject().left;
selection_object_top=canvas.getActiveObject().top;
el.top=canvas.getActiveObject().top;
el.width=canvas.getActiveObject().width*canvas.getActiveObject().scaleX;
el.height=canvas.getActiveObject().height*canvas.getActiveObject().scaleY;
canvas.add(el);
canvas.setActiveObject(el);
for(var i=0; i<$("#layers li").size();i++)
{
canvas.item(i).selectable= false;
}
}
else{
alert("Please select an object or layer");
}
});
Is this what you're looking for? http://jsfiddle.net/86bTc/4/
You set the lastActive.clipTo = null;
try this code
function crop()
{
if (!fabric.Canvas.supports('toDataURL')) {
alert('This browser doesn\'t provide means to serialize canvas to an image');
}
else {
var obj = canvas.getActiveObject();
fabric.Image.fromURL(canvas.toDataURL({
format: 'png',
left: obj.left + 1,
top: obj.top + 1,
width: obj.width * obj.scaleX,
height: obj.height * obj.scaleY,
}), function (img) {
canvas.remove(obj);
canvas.remove(ao);
canvas.add(img);
canvas.renderAll();
})
}
}
;
function Select() {
ao = canvas.getActiveObject();
if (!ao)
return;
canvas.bringToFront(ao);
ao.selectable = false;
canvas.add(new fabric.Rect({
left: 200,
top: 200,
width: 200,
height: 200,
fill: 'transparent',
stroke: '#000000',
hasRotatingPoint: false,
strokeDashArray: [5, 5],
cornerSize: 8,
}));
}