I have to show progress graphs exactly in following way where percentage would be in center of circular graph
How can i do this using javascript/jQuery?
Can it be done using Google Chart?
There's a plugin for this at:
http://anthonyterrien.com/knob/
Demo
jQuery Knob
canvas based ; no png or jpg sprites.
touch, mouse and mousewheel, keyboard events implemented.
downward compatible ; overloads an input element...
I searched and know there are at least 5 ways to create Circular progress indicator:
They include:
jquery.polartimer.js
jQuery Knob
CSS3 pie graph timer with jquery
circular progressBar by jQuery andCSS3
ProgressBar.js
I would recommend Highcharts JS for all of your JavaScript graphing needs
Browse through more of the demos; I think you're looking for the Donut Chart :)
You can use CSS sprites (google) for this purpose, if you want to show multiples of 10 (0%, 10%, 20% etc). I guess you need to be a graphics guru to create the sprite..
The sprite is one image containing more than one image. For your purpose, you can create an image, say 16x160px. Imagine that this image is divided into ten 16x16px "slices" and draw the corresponding percentage on that slice. You can then use CSS and JavaScript to show one "frame" from this sprite.
If you are not targeting old browsers, you can easily do that by drawing on a canvas element. This gives you the freedom to do whatever you need with the chart.
That means this solution's only requirement is jQuery and any browser that supports the canvas element...IE9+
Here's a code snippet that demonstrates it...
//input
var dimens = 256;
var color = "rgba(54, 162, 235, 0.9)";
var padding = 12;
var width = 10;
var value = 80;
var maxValue = 100;
var countFontRatio = 0.25; //ratio in relation to the dimens value
$(function() {
$(".chart-total").each(function(idx, element) {
var _render = function() {
var startingPoint = -0.5;
var pointValue = startingPoint;
var currentPoint = startingPoint;
var timer;
var _ctx;
var $canvas = $(element).find("canvas");
var canvas = $canvas.get(0);
pointValue = (value / (maxValue / 20) * 0.1) - 0.5;
canvas.height = dimens;
canvas.width = dimens;
if (!countFontRatio)
$canvas.parent().find(".legend-val").css("font-size", dimens / value.toString().length);
else
$canvas.parent().find(".legend-val").css("font-size", dimens * countFontRatio);
_ctx = canvas.getContext("2d");
var _draw = function() {
_ctx.clearRect(0, 0, dimens, dimens);
_ctx.beginPath();
_ctx.arc(dimens / 2, dimens / 2, (dimens / 2) - padding, startingPoint * Math.PI, 1.5 * Math.PI);
_ctx.strokeStyle = "#ddd";
_ctx.lineWidth = 2;
_ctx.lineCap = "square";
_ctx.stroke();
_ctx.beginPath();
_ctx.arc(dimens / 2, dimens / 2, (dimens / 2) - padding, startingPoint * Math.PI, currentPoint * Math.PI);
_ctx.strokeStyle = color;
_ctx.lineWidth = width;
_ctx.lineCap = "round";
_ctx.stroke();
currentPoint += 0.1;
if (currentPoint > pointValue) {
clearInterval(timer)
}
};
timer = setInterval(_draw, 100);
};
_render();
$(window).resize(function() {
_render();
});
});
})
body {
font-family: 'Open Sans', sans-serif;
color: #757575;
}
.chart-total {
position: relative;
margin: 0 auto;
}
.chart-total-legend {
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translateY(-50%) translateX(-50%);
-o-transform: translateY(-50%) translateX(-50%);
-moz-transform: translateY(-50%) translateX(-50%);
-moz-transform: translateY(-50%) translateX(-50%);
transform: translateY(-50%) translateX(-50%);
}
.legend-val {
font-size: 4em;
display: block;
text-align: center;
font-weight: 300;
font-family: 'Roboto', sans-serif;
}
.legend-desc {
display: block;
margin-top: 5px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto:300,400" rel="stylesheet">
<div class="chart-total" style="max-width: 256px;">
<canvas height="256" width="256"></canvas>
<div class="chart-total-legend">
<span class="legend-val" value="3933" style="font-size: 64px;">3,933</span>
<span class="legend-desc">Total Progress</span></div>
</div>
I don't think you can do it with javascript/jquery/css alone. You need to render different images, for each step one and display the proper one.
It could be made with flash (probably there are ready made components) or with svg or html5 canvas element or an api which uses one of the above backends.
Related
I am trying to create a parallax background effect with some knockout text. I am facing two issues:
The parallax effect does not work at all when background-size: contain; is set.
The parallax effect, for whatever reason, does not work outside of Codepen - when scaled up fully in chrome, the effect disappears and behaves exactly as if the background is stuck to your mouse...I am not sure if this is a scaling issue or issue with chrome and my method.
Here is my code:
(function() {
// Add event listener
document.addEventListener("mousemove", parallax);
const elem = document.querySelector("#text");
// Magic happens here
function parallax(e) {
let _w = window.innerWidth / 2;
let _h = window.innerHeight / 2;
let _mouseX = e.clientX;
let _mouseY = e.clientY;
let _depth1 = `${50 - (_mouseX - _w) * 0.01}% ${50 - (_mouseY - _h) * 0.01}%`;
let _depth2 = `${50 - (_mouseX - _w) * 0.02}% ${50 - (_mouseY - _h) * 0.02}%`;
let _depth3 = `${50 - (_mouseX - _w) * 0.06}% ${50 - (_mouseY - _h) * 0.06}%`;
let x = `${_depth3}, ${_depth2}, ${_depth1}`;
console.log(x);
elem.style.backgroundPosition = x;
}
})();
.background {
background: #000;
}
#text {
background: url("https://images.unsplash.com/photo-1465101162946-4377e57745c3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1957&q=80");
/*background-size: contain;*/
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 8vw;
}
<body class="background">
<h1 id="text"><b>Galaxy</b></h1>
</body>
The solution turned out to be that it depends on the size of the image, which it seems must be smaller than the container (in this case the entire screen/body) in order for this to work.
The image I was using in the above codepen was different to the image I was using in my local instance. To make it behave correctly, I simply applied background-size: 50%; to my much larger local background image so that it behaves more like the smaller background image used in the codepen.
I would like to clip an animated canvas as background to a <h1 />. The requirements are:
Use an actual <h1 /> tag instead of rendered heading in canvas.
Use of images to be rendered with ctx.drawImage().
h1 {
color: transparant;
background-image: <some-canvas>;
background-clip: text;
}
There are several approaches I've tried so far with varying success:
Creating a regular canvas and setting it as background of the <h1 />-tag using -webkit-canvas and -moz-element. This approach ticked all of my requirements but unfortunatly -webkit-canvas was deprecated along with document.getCSSCanvasContext("2d") in Chromium. Safari is the only working browser.
Using the CSS Paint API (Houdini). Using a requestAnimationFrame() to update a css var I can keep ticking the animation and do the animation I would like to implement. However, in Chromium, passing in images has to be done using a workaround (instead of creating a property of type image, images have to be passed in using background-image, making me unable to use the background-image to tell CSS Paint to use my worklet as background. The spec is not entirely implemented.
Creating an inline svg as background-image: url("data:image/svg+xml;utf8,<svg><foreignObject><canvas id='..'/></foreignObject></svg>"); and trying to update that canvas using requestAnimationFrame. Does not work at all.
Are there any other methods I could try?
If it doesn't have to be a background-image, you could put the canvas element inside the h1 element, match the canvas width and height to that of the h1 element, give it a lower z-index than the text in the h1 element so that it appears to be behind the text, acting like a background.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
/*
Set the dimensions of the canvas to
match the parent h1 element
----------------------------------------------------------*/
setCanvasSize();
// (and for demonstrative purposes, scale on window resize)
window.addEventListener('resize', setCanvasSize, false);
function setCanvasSize () {
var _w = canvas.parentNode.clientWidth;
var _h = canvas.parentNode.clientHeight;
canvas.width = _w;
canvas.height = _h;
canvas.style.width = "'" + _w + "px'";
canvas.style.height = "'" + _h + "px'";
}
/*--------------------------------------------------------*/
/*--------------------------------------------------------
All this code below is just a ball animation borrowed from MDN
to illustrate what I'm suggesting.
Source: MDN
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Advanced_animations
*/
var raf;
var running = false;
var ball = {
x: 100,
y: 100,
vx: 5,
vy: 1,
radius: 50,
color: 'blue',
draw: function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
}
};
function clear() {
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.fillRect(0,0,canvas.width,canvas.height);
}
function draw() {
clear();
ball.draw();
ball.x += ball.vx;
ball.y += ball.vy;
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
ball.vy = -ball.vy;
}
if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
ball.vx = -ball.vx;
}
raf = window.requestAnimationFrame(draw);
}
if (!running) {
raf = window.requestAnimationFrame(draw);
running = true;
}
ball.draw();
/*--------------------------------------------------------*/
h1 {
/* Important for positioning the span element */
position: relative;
/* Cosmetic/demonstrative */
border: 2px solid red;
height: 100%;
text-align: center;
color: red;
font-size: 32px;
font-family: Roboto,sans-serif;
margin: 0 auto;
}
h1 span {
/* Vertically and horizontally center the text */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
/*
Text will appear above canvas as long as its
z-index > canvas' z-index
*/
z-index: 2;
}
h1 canvas {
/* this will make the canvas appear behind the text */
position: relative;
z-index: 1;
}
<h1>
<span>Lorem Ipsum etc.</span>
<canvas id="canvas"></canvas>
</h1>
Just a thought anyway, maybe you can try it out and expand on the idea to suit your needs. I'm not 100% sure what you're working on so apologies if it's not helpful.
How can I get Text object font size after modifying object in fabric.js?
Below is my code.
var text = new fabric.Text(imgText, {
left: 10,
top: 5,
fontSize: 15,
fontFamily: 'Verdana',
fill: 'white'
});
text.scaleToWidth(canvas.width * 0.5);
text.setControlsVisibility(canvasConfig);
canvas.add(text);
canvas.renderAll();
var objects = canvas.getActiveObject();
var obj = objects;
if (!obj) {
return;
}
//console.log(obj.get('fontSize') *= obj.scaleX);
var angle = obj.get('angle');
var objWidth = obj.get('width') * obj.scaleX;
var objWidthPercent = objWidth / canvas.width * 100;
var objHeight = obj.get('height') * obj.scaleY;
var objHeightPercent = objHeight / canvas.height * 100;
var bound = obj.getBoundingRect();
var objLeft = obj.get('left') / canvas.width * 100;
var objTop = obj.get('top') / canvas.height * 100;
var newfontsize = obj.fontSize * obj.scaleX;
Above I set default FontSize to 15. then I modify object I can get proper Height, Width, Left, Top, but I am not able to get FontSize.
In backend i set image and text like below screenshot.
In frontend what i get like below screenshot.
Below style for image & text on frontend.
element.style {
left: 64.37%;
top: 14.54%;
width: 28.25%;
height: 14.37%;
font-size: 63.58px;
color: #E346FF;
font-family: Times New Roman;
position: absolute;
max-width: 100%;
z-index: 996;
max-height: 100%;
}
element.style {
left: 56.5%;
top: 0.81%;
width: 42.86%;
height: 42.86%;
max-width: 100%;
max-height: 100%;
position: absolute;
z-index: 995;
display: block;
background-image: url(http://10.16.16.101/LabelExtension/pub/media/labelimageuploader/images/image/o/r/orange_38.png);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
When i add below code it working perfect but in backend object is getting blur.
this.canvas.setHeight(300);
this.canvas.setWidth(240);
this.canvas.backgroundColor = '#E8EEF1';
this.canvas.setDimensions({width: '480px', height: '600px'}, {cssOnly: true});
Here is the way to match Fabric.js font transforms to CSS transforms: https://jsfiddle.net/mmalex/evpky3tn/
The solution is to match transformations of texts, not trying to adjust font size.
Step 1 - Prepare scene, compose canvas, group text with rectangle, let user manipulate this group, rotate and scale it.
var canvas = new fabric.Canvas(document.getElementById('c'));
var rect = new fabric.Rect({
width: 50,
height: 50,
left: 90,
top: 120,
fill: 'rgba(255,0,0,0.25)'
});
var text = new fabric.Text("123", {
left: rect.left,
top: rect.top,
fontSize: 15,
fontFamily: 'Verdana',
fill: 'black'
});
text.scaleToWidth(rect.width);
canvas.add(text);
var group = new fabric.Group([rect, text], {
originX: 'center',
originY: 'center',
angle: 25,
scaleY: 1.7
});
canvas.add(group);
canvas.renderAll();
Step 2 - prepare DIV style for scaling
.scaled { // this style is applied to DIV element with text
...
font-size: 15px; // Fabric.js text is also 15px size
transform: scale(1, 1); // define initial transform
transition: all 0.25s linear; // let it animate
...
}
Step 3 - Evaluate Fabric.js transforms and apply CSS on DIV element,
for example:
element.style {
transform: rotate(25deg) scale(1.74774, 2.97116);
}
The solution (aka button handler) converts Fabric.js transform to CSS transform:
function matchCssTransform() {
let textScale = text.getTotalObjectScaling();
let pixelRatio = window.devicePixelRatio;
let styleStr = `rotate(${group.angle}deg) scale(${textScale.scaleX / pixelRatio}, ${textScale.scaleY / pixelRatio}) `;
document.getElementById("scaled").style.transform = styleStr;
}
getHeightOfLine(lineIndex) → {Number} : Computes height of character at given position and return fontSize of the character. Is it? tell me.
It's a method of text class. http://fabricjs.com/docs/fabric.Text.html#getHeightOfLine
This is the vanilla js solution.
I am not able to get FontSize.
You can achieve fontSize using the computedStyle like
let style = window.getComputedStyle(text, null).getPropertyValue('font-size');
let fontSize = parseFloat(style);
https://developer.mozilla.org/de/docs/Web/API/Window/getComputedStyle
In addition to this I recommend you to work with vw and vh
.text {
font-size: 10vw;
}
https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/
All together gives us https://jsfiddle.net/a8woL1eh/
The problem is Text object does not change its fontSize property when it is modified or transformed unless set fontSize property manually. It's the reason why you get blurred text because despite changed the transform size the main fontSize remaining same. So possible solution will be somehow changing fontSize property dynamically.
http://jsfiddle.net/therowf/xkhwagd8/41/
Here I have attached a jsfiddle example form your code. This code is very similar to your one.
Thanks and let me know if this is worked. (:
var canvas = new fabric.Canvas(document.getElementById('c'));
var imgText ="This is text";
var canvasConfig = true;
var text = new fabric.Text(imgText, {
left: 10,
top: 5,
fontSize: 50,
fontFamily: 'Verdana',
fill: 'black'
});
text.scaleToWidth(canvas.width * 0.5);
text.setControlsVisibility(canvasConfig);
canvas.add(text);
canvas.renderAll();
var objects = canvas.getActiveObject();
function moveHandler(evt){
//evt.target.fontSize = 10;
var fontSizeX = evt.target.scaleX;
var fontSizeY = evt.target.scaleY;
if(fontSizeX === fontSizeY){
evt.target.fontSize = fontSizeX*100;
console.log(evt.target.fontSize);
}
}
canvas.on('object:scaling', moveHandler);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.6.0/fabric.min.js"></script>
<canvas id="c" width="400" height="400"></canvas>
I want to create a media control bar for a video player with the controls blurring the background. Currently I can get the glassy look but I can't get blurring to work.
I tried following this guide: https://medium.com/#AmJustSam/how-to-do-css-only-frosted-glass-effect-e2666bafab91 but it seems like it only works on static images.
Here's an example of what I want:
I also saw the webkit backdrop-filter which looks perfect but it's only stable on safari so I can't use that. Any advice for frosted glass on dynamic videos?
I was able to accomplish this by copying the bottom part of the video to a canvas every frame and blurring the canvas via CSS. It seems to work well in Chrome, but flashes sometimes in Firefox. Doing the blur programmatically in the canvas with something like Superfast Blur might be more performant, but that's an experiment for another day. Tomorrow, probably.
function initControls (player, blurRadius, controlHeight, videoWidth, videoHeight) {
// crop player to video size
let video = player.querySelector('video');
videoWidth = videoWidth || video.clientWidth;
videoHeight = videoHeight || video.clientHeight;
player.style.width = videoWidth + 'px';
player.style.height = videoHeight + 'px';
// crop control bar to video size
let controlBar = player.querySelector('.control-bar');
controlBar.style.width = videoWidth + 'px';
controlBar.style.height = controlHeight + 'px';
// canvas needs to be slightly taller than what gets displayed
// to blur cleanly
let canvas = player.querySelector('canvas');
canvas.width = videoWidth;
canvas.height = 2 * blurRadius + controlHeight;
canvas.style.filter = `blur(${blurRadius}px)`;
canvas.style.top = -2 * blurRadius + 'px';
// copy video to canvas
let ctx = canvas.getContext('2d');
let videoCropY = videoHeight - canvas.height;
function updateCanvas () {
ctx.drawImage(
video,
0, videoCropY, canvas.width, canvas.height,
0, 0, canvas.width, canvas.height
);
}
// update the canvas only when necessary
let hovering = false;
function renderLoop () {
updateCanvas();
if (hovering && !video.paused) {
window.requestAnimationFrame(renderLoop);
}
}
// no point in rendering to a canvas you can't see
player.addEventListener('mouseenter', () => {
hovering = true;
renderLoop();
});
player.addEventListener('mouseleave', () => { hovering = false; });
video.addEventListener('play', renderLoop);
}
document.addEventListener('DOMContentLoaded', event => {
// do the magic
initControls(document.querySelector('.player'), 4, 50, 320, 240);
// basic play button functionality
document.querySelector('.play-button').addEventListener('click', event => {
let v = event.target.closest('.player').querySelector('video');
if (v.ended) v.currentTime = 0;
if (v.paused) {
v.play();
} else {
v.pause();
}
});
});
/* styling required for blurred control background */
.player {
position: relative;
}
.player > video {
margin: 0;
display: block;
}
.control-bar > canvas {
margin: 0;
display: block;
left: 0;
position: absolute;
}
.control-bar {
margin: 0;
overflow: hidden;
position: absolute;
bottom: 0;
/* height of control bar is specified in javascript, sorry about that */
}
/* simple control-hiding mechanism; other methods also work */
/* javascript relies on mouseover and mouseout to decide whether to update canvas */
.player > .control-bar {
display: none;
}
.player:hover > .control-bar {
display: block;
}
/* styling actual controls; adjust to taste */
.play-button {
height: 30px;
line-height: 30px;
width: 100px;
color: white;
border: 1px solid white;
position: absolute;
top: 10px;
left: 50%;
margin-left: -50px;
text-align: center;
}
<div class="player">
<video src="https://archive.org/download/MedicalA1950/MedicalA1950_512kb.mp4"></video>
<div class="control-bar">
<canvas></canvas>
<div class="play-button">PLAY/PAUSE</div>
</div>
</div>
I am looking to select items in a web page using the LeapMotion and I am struggling with programming this interaction.
Using this code as a base (but updating the link so it connects to the current SDK) I can get my cursor to move around the window based on where my hand is in space. However, I do not know how to make the equivalent of the event listener "click" using the LeapMotion. I am using Leap.js and have built a crude GUI using svg.js.
How do I program an event listener that selects using the LeapMotion in Javascript?
I have working code with Leap motion. I did quize software. Here cursor is a div element which styled as:
#cursor {
width: 60px;
height: 60px;
position: fixed;
margin-left: 20px;
margin-top: 20px;
z-index: 99999;
opacity: 0.9;
background: black;
border-radius: 100%;
background: -webkit-radial-gradient(100px 100px, circle, #f00, #ff6a00);
background: -moz-radial-gradient(100px 100px, circle, #f00, #ff6a00);
background: radial-gradient(100px 100px, circle, #f00, #ff6a00);
}
and Java script at bottom. What I did, I get HTML element by position and triggering click event on it by tap gestures.
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
// Setting cursor and output position
window.cursor = $('#cursor');
var controller= Leap.loop(function(frame) {
if (frame.pointables.length > 0) {
try
{
var position = frame.pointables[0].stabilizedTipPosition;
var normalized = frame.interactionBox.normalizePoint(position);
var cx = w * normalized[0];
var cy = h * (1 - normalized[1]);
$('#cursor').css('left', cx);
$('#cursor').css('top', cy);
}catch(e){
console.error(e);
}
}
});
controller.use('screenPosition', {
scale: 1
});
controller.on('gesture', onGesture);
function onGesture(gesture,frame)
{
try
{
// If gesture type is keyTap
switch(gesture.type)
{
case 'keyTap':
case 'screenTap':
var position = frame.pointables[0].stabilizedTipPosition;
var normalized = frame.interactionBox.normalizePoint(position);
//Hiding cursor for getting background element
cursor.hide();
// Trying find element by position
var cx = w * normalized[0];
var cy = h * (1 - normalized[1]);
var el = document.elementFromPoint(cx, cy);
cursor.show();
console.log(el);
if (el) {
$(el).trigger("click");
}
break;
}
}
catch (e) {
console.info(e);
}
}