Dynamically place Unicode characters in a div with background image - javascript

I have an image that represents a weight-lifting bar:
I want to put the Full Block Unicode character (e.g. representing plates) on both the left and the right sides of the bar.
I'm trying to do this with 3 divs:
Barbell left: plates that go on the left side of the bar, right-justified
Barbell middle: nothing left blank
Barbell right: plates that go on the right side of the bar, left-justified
Here is a professional representation of the divs with a plate:
I thought I could do this with floats and percentages on div widths, but I'm not having any luck.
Here is my most recent attempt on js fiddle.
UPDATE
I got the answer I wanted, but based on the comment, I discovered that using Canvas was the better route.
I was able to achieve a better result with this html:
<div data-role="page" id="p1">
<div data-role="header"><h1>Header Page 1</h1></div>
<div data-role="content">
<div class="bar-canvas">
<canvas id="_barCanvas"></canvas>
</div>
</div>
</div>
<div data-role="footer"><h4>Footer</h4></div>
</div>
and this js:
var WIDTH_FACTOR = .8; //80% of screen size
var HEIGHT_FACTOR = .1; //10% of height size
var WEIGHT_SPACER = 2;
var ctx = $("#_barCanvas")[0].getContext("2d");
ctx.canvas.width = (window.innerWidth * WIDTH_FACTOR);
ctx.canvas.height = (window.innerHeight * HEIGHT_FACTOR);
var bar_width = ctx.canvas.width * .8;
var bar_height = ctx.canvas.height * .1;
var bar_x = (ctx.canvas.width - bar_width)
var bar_y = (ctx.canvas.height * .5)
var plate_stop_width = bar_width * .01;
var plate_stop_height = bar_height * 4;
var plate_stop_y = bar_y - ((plate_stop_height - (bar_y / 2)));
var rubber_plate_height = bar_height * 8;
var rubber_plate_y = (ctx.canvas.height / 2) - (rubber_plate_height/2) + (bar_height/2);
var small_plate_height = plate_stop_height;
var small_plate_y = plate_stop_y;
var left_plate_stop_x = bar_x + (bar_width * .3);
var right_plate_stop_x = bar_x + (bar_width * .7);
//Draw Bar
ctx.fillStyle = "black";
ctx.fillRect (bar_x, bar_y, bar_width, bar_height);
//Draw Plate stop left
ctx.fillStyle = "black";
ctx.fillRect (left_plate_stop_x, plate_stop_y, plate_stop_width, plate_stop_height);
//Draw Plate stop right
ctx.fillStyle = "black";
ctx.fillRect (right_plate_stop_x, plate_stop_y, plate_stop_width, plate_stop_height);
//Draw 45 lb Plates
var plate_width = bar_width * .04;
var current_plate_height = 0;
ctx.fillStyle = 'red';
ctx.fillRect(left_plate_stop_x - plate_width, rubber_plate_y, plate_width, rubber_plate_height);
ctx.fillStyle = 'red';
ctx.fillRect(right_plate_stop_x + plate_stop_width, rubber_plate_y, plate_width, rubber_plate_height);

I did it changing a bit your markup and css.
Demo (tested on Chrome 22 only)
HTML:
<div data-role="page" id="p1">
<div data-role="header"><h1>Header Page 1</h1></div>
<div data-role="content">
<div class="barbell-background">
<div class="barbell-left">█</div>
<div class="barbell-right">█</div>
</div>
</div>
<div data-role="footer"><h4>Footer</h4></div>
</div>
CSS:
.barbell-background
{
font-size:3em;
line-height:1.4em;
height:1.4em;
position:relative;
background-image:url('http://i.stack.imgur.com/ZmFY4.png');
background-repeat: no-repeat;
background-position: center;
}
.barbell-left, .barbell-right
{
position:absolute;
color:red;
}
.barbell-left
{
right:50%;
margin-right:146px;
}
.barbell-right
{
left:50%;
margin-left:145px;
}​
As Joachim Sauer said, it's probably easier and more consistent to just use divs for the red squares...
Another demo
HTML:
<div data-role="page" id="p1">
<div data-role="header"><h1>Header Page 1</h1></div>
<div data-role="content">
<div class="barbell-background">
<div class="barbell-left"></div>
<div class="barbell-right"></div>
</div>
</div>
<div data-role="footer"><h4>Footer</h4></div>
</div>
CSS:
.barbell-background
{
font-size:3em;
line-height:1.3em;
height:1.3em;
position:relative;
background-image:url('http://i.stack.imgur.com/ZmFY4.png');
background-repeat: no-repeat;
background-position: center;
}
.barbell-left, .barbell-right
{
position:absolute;
background:red;
width:0.5em;
height:100%;
}
.barbell-left
{
right:50%;
margin-right:146px;
}
.barbell-right
{
left:50%;
margin-left:144px;
}​
In both demos you'll see that a pixel "wobbles". Knowing the contents of the red square i could try to fix it.

Related

Change CSS of inner div when scroll reaches that div

I am attempting to implement a scroll function where the CSS of the inner div's change when it reaches a certain height from the top.
var $container = $(".inner-div");
var containerTop = $container.offset().top;
var documentTop = $(document).scrollTop();
var wHeight = $(window).height();
var minMaskHeight = 0;
var descriptionMax = 200;
var logoMin = -200;
var maskDelta = descriptionMax - minMaskHeight;
var $jobOverview = $container.find(".right");
var $jobLogo = $container.find(".left");
var curPlacementPer = ((containerTop - documentTop) / wHeight) * 100;
var topMax = 85;
var center = 20;
var bottomMax = -15;
//console.log("Placement: " + curPlacementPer);
function applyChanges(perOpen) {
var maskHeightChange = maskDelta * (perOpen / 100);
var opacityPer = perOpen / 100;
var newDescriptionLeft = descriptionMax - maskHeightChange;
var newLogoLeft = logoMin + maskHeightChange;
if (newDescriptionLeft <= 0) newDescriptionLeft = 0;
if (newLogoLeft >= 0) newLogoLeft = 0;
if (opacityPer >= 1) opacityPer = 1;
$jobOverview.css({
transform: "translate(" + newDescriptionLeft + "%,-50%)",
opacity: opacityPer
});
$jobLogo.css({
transform: "translate(" + newLogoLeft + "%,-50%)",
opacity: opacityPer
});
}
if (window.innerWidth > 640) {
$container.removeClass("mobile");
// console.log("Placement: " + curPlacementPer);
if (curPlacementPer <= topMax /*&& curPlacementPer >= center*/ ) {
var perOpen = ((topMax - curPlacementPer) / 25) * 100;
applyChanges(perOpen);
} else if (curPlacementPer < center /*&& curPlacementPer >= bottomMax*/ ) {
var perOpen = (((bottomMax - curPlacementPer) * -1) / 25) * 100;
applyChanges(perOpen);
} else {
$jobOverview.css({
transform: "translate(200%,-50%)",
opacity: "0"
});
$jobLogo.css({
transform: "translate(-300%,-50%)",
opacity: "0"
});
}
<div class="outer-div">
<div class="inner-div first">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div second">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div third">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div fourth">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
Currently, all of the inner div's gets changed at the same time.
I noticed that when I change the $container class to equal '.first' and specify it more, it works.
Is there any way to make the inner div's change separately, relative to its height from the top? Any way I can iterate the scroll function so I can add more inner div's in the future and not have to worry about changing my scroll function?
In raw JavaScript, this is my answer:
// Define the element -- The '#fooBar' can be changed to anything else.
var element = document.querySelector("#fooBar");
// Define how much of the element is shown before something happens.
var scrollClipHeight = 0 /* Whatever number value you want... */;
// Function to change an element's CSS when it is scrolled in.
const doSomething = function doSomething() {
/** When the window vertical scroll position plus the
* window's inner height has reached the
* top position of your element.
*/
if (
(window.innerHeight + window.scrollY) - (scrollClipHeight || 0) >=
element.getBoundingClientRect().top
)
// Generally, something is meant to happen here.
element.style = "/* Yay, some CSS! */"
};
// Call the function without an event occurring.
doSomething();
// Call the function when the 'window' scrolls.
addEventListener("scroll", doSomething, false)
This is the method I use. If there are other methods, I'd love to see them as well but this is my answer for now.
consider using 3rd party jQuery plugin for easier job, like one of these:
https://github.com/xobotyi/jquery.viewport
or
https://github.com/zeusdeux/isInViewport
then you can have additional element selector e.g.: ":in-viewport"
so you can:
$(window).on('scroll',function() {
$('div').not(':in-viewport').html('');
$('div:in-viewport').html('hello');
});
Check if current scroll offset from top is bigger than the element offset from the top:
$(window).scroll(function() {
var height = $(window).scrollTop();
var element = $('#changethis'); //change this to your element you want to add the css to
if(height > element.offset().top) {
element.addClass('black'); //add css class black (change according to own css)
}
});
Html:
<div id="changethis">Test</div>
Css:
body
{
height:2000px;
}
.black
{
background-color:black;
color:white;
padding:20px;
}
Demo:
https://codepen.io/anon/pen/WZdEap
You could easily implement this in your existing code.
Below is the sample snippet code, Hope it'll work for you:
$(document).ready(function(){
topMax = 100;
topMin = 25;
$(document).scroll(function(){
$('.inner-div').each(function(){
if($(this).offset().top-$(window).scrollTop()<=topMax && $(this).offset().top-$(window).scrollTop()>=topMin){
$(this).css({'background':'#c7c7c7'});
}else{
$(this).css({'background':'inherit'});
}
});
});
});
div{
width:100%;
border:1px solid red;
padding:5px;
}
div.inner-div{
border: 1px dashed green;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer-div">
<div class="inner-div first">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div second">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div third">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="inner-div fourth">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
Happy to help you! :)

Draw More Arc Canvas

Hello People I'd Like to Know How to Draw More Arc Inside My Canvas, What I Need to Draw This circles:
So I Write This Responsive Code to Make my Canvas is Responsive:
var myCanvas = document.getElementById('myCanvas');
var ctx = myCanvas.getContext('2d');
var centerX = myCanvas.width / 2;
var centerY = myCanvas.height / 2;
var borderWidth = 20;
var borderColor = '#2DC36A';
var radius = (myCanvas.width / 2) - (borderWidth / 2);
// days arc canvas background
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.lineWidth = borderWidth;
ctx.strokeStyle = borderColor;
ctx.stroke();
ctx.closePath();
// Make Canvas Responsive
function makeResponsive() {
var containerWidth = $('.progress-nested').width();
$('.progress-nested').height(containerWidth);
var canvasElements = ['#myCanvas'];
$('#myCanvas').width(containerWidth).height(containerWidth);
}
makeResponsive(); // Make Canvas Responsive in Document ready
$(window).resize(function () {
makeResponsive(); // Make Canvas Responsive in Window Resize
});
#progress {
width: 100%;
padding: 5px;
}
.progress-nested{
position:relative;
border-radius:50%;
}
canvas {
display:block;
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div id="progress">
<div class="container">
<div class="row">
<div class="col-xs-3 col-md-2 col-md-offset-2">
<div class="progress-nested">
<canvas id="myCanvas" width="250" height="250"></canvas>
</div>
</div>
</div>
</div>
</div>
Note: Please Run Code Snippet In Full Page

Javascript make an image bounce around screen

I have made code for a bouncing ball (using the arc() method on a canvas). I am wondering how to make an image bounce around the screen. Here is my previous code (note that the launchBall() function is going to be the function that runs the bouncing image):
<!DOCTYPE HTML>
<html>
<body onload="startBall()" oncontextmenu="return false;" style="cursor: none; overflow: hidden;">
<center>
<div id="div" style="width: 1600px; height: 700px; border: 2px solid #000000; background-color: grey;">
<br>
<img draggable="false"id="image" style="position: absolute;" width="50" height="50"src="http://www.clker.com/cliparts/b/a/b/0/1207156679935151925noxin_crosshairs.svg.hi.png"/>
</div>
<center>
<p>Score: <a>0</a></p>
</center>
<script>
var dx = 3;
var dy = 3;
var x = 100;
var y = 100;
var radius = 20;
var interval;
function startBall(){
interval = setInterval(launchBall, 20);
}
function launchBall(){
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, 1275, 695);
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fillStyle = "red";
ctx.fill();
document.getElementById
if(x<20 || x>1255) dx=-dx;
if(y<20 || y>675) dy=-dy;
x = x + dx;
y = y + dy;
}
document.getElementById("div").onmousemove = function(e) {
document.getElementById("image").style.top = e.pageY -25 + "px";
document.getElementById("image").style.left = e.pageX -25 +"px";
}
</script>
</body>
</html>

How to get width and height of canvas after resizing the browser

I want to get width and height of canvas which is responsive. I have 5 canvas elements on a single page.
Using Javascript before drawing I want to know the height and width of canvas to be able to draw images at the right size.
HTML Code:
<div id='container'>
<div class='all'>
<canvas id='clock1' style="border:solid">
</div>
<div class='all'>
<canvas id='clock2' style="border:solid">
</div>
<div class='all'>
<canvas id='clock3' style="border:solid">
</div>
<div class='all'>
<canvas id='clock4' style="border:solid">
</div>
<div class='all'>
<canvas id='clock5' style="border:solid">
</div>
</div>
CSS:
#container
{
width:100%;
height:100%;
position:relative;
}
.all
{
width:30%;
height:45%;
float:left;
}
canvas
{
width:100%;
height:100%;
}
Usually you don't set size of canvas using CSS but calculating the w/h and use the width and height properties.
But if you use CSS you can get the calculated size of the canvas element set by CSS using getComputedStyle():
Online demo
var cs = getComputedStyle(canvas);
var width = parseInt( cs.getPropertyValue('width'), 10);
var height = parseInt( cs.getPropertyValue('height'), 10);
the size is here returned by getPropertyValue() as a string and in pixel size (ie. "400px"), so we use parseInt() to chop of the "px" part.
Then simply set the width and height on canvas and update its content.
Full example (adjust as needed):
window.onresize = updateCanvas;
updateCanvas();
function updateCanvas() {
var cs = getComputedStyle(canvas);
var width = parseInt(cs.getPropertyValue('width'), 10);
var height = parseInt(cs.getPropertyValue('height'), 10);
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(width, height);
ctx.moveTo(0, height);
ctx.lineTo(width, 0);
ctx.stroke();
}

Jquery image hover, click and grayscale effect with tab and caption

i want my image get black white (grayscale) after i hover they will change to the color. it is already sucses, but i want if i click image they will change color, and show content in the div i already add .click .dblclick and .toogke function but always change image to the black and white here are the code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tabbed Navigation</title>
<style type="text/css">
.item {
width: auto;
margin: 0 0 0 0;
float: left;
}
.item.first {
clear: left;
margin-left: 0;
}
.item img {
opacity:0;
}
.wrapper{
float:left; /* important */
position:relative; /* important(so we can absolutely position the description div */
margin-right: 20px
}
.description{
position:absolute; /* absolute position (so we can position it where we want)*/
bottom:50px; /* position will be on bottom */
width:100%;
/* styling bellow */
background-color:black;
font-family: 'tahoma';
font-size:15px;
color:white;
opacity:0.6; /* transparency */
filter:alpha(opacity=60); /* IE transparency */
z-index: 9999;
}
p.description_content{
padding:5px;
margin:0px;
}
.item img a:active {
background-image: url(images/icondock.jpg);
}
</style>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
// $(".item img").css({"display":"none");
// On window load. This waits until images have loaded which is essential
$(window).load(function(){
// Fade in images so there isn't a color "pop" document load and then on window load
$(".item img").animate({opacity:1},500);
// clone image
$('.item img').each(function(){
var el = $(this);
el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"998","opacity":"0"}).insertBefore(el).queue(function(){
var el = $(this);
el.parent().css({"width":this.width,"height":this.height});
el.dequeue();
});
this.src = grayscale(this.src);
});
// Fade image
$('.item img').mouseover(function(){
$(this).parent().find('img:first').stop().animate({opacity:1}, 500);
})
$('.img_grayscale').mouseout(function(){
$(this).stop().animate({opacity:0}, 500);
});
});
// Grayscale w canvas method
function grayscale(src){
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var imgObj = new Image();
imgObj.src = src;
canvas.width = imgObj.width;
canvas.height = imgObj.height;
ctx.drawImage(imgObj, 0, 0);
var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
for(var y = 0; y < imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return canvas.toDataURL();
}
</script>
</head>
<body>
<div class='wrapper'>
<div class="item">
<img src="images/icondock.jpg" />
</div>
<div class="description">
<p class="description_content">The pack, the basic The pack, the basic More » </p>
</div>
</div>
<div class='wrapper'>
<div class="item">
<img src="images/koifish.jpg" />
</div>
<div class="description">
<p class="description_content">The pack, the basic The pack, the basic More » </p>
</div>
</div>
<div class='wrapper'>
<div class="item">
<img src="images/sakura.jpg" />
</div>
<div class="description">
<p class="description_content">The pack, the basic The pack, the basic More » </p>
</div>
</div>
</body>
</html>
if it is so hard you can use 2 images grayscale and color
javascript:
$(function(){
var canv = document.createElement('canvas'),
ctx = canv.getContext('2d');
canv.style.cssText = "position:absolute;left:-10000px;";
document.body.appendChild( canv );
function getGrayScale(src, el ){
$("<img src=\""+src+"\" />").appendTo("body").bind("load", function ( ) {
var w = canv.width = this.offsetWidth,
h = canv.height = this.offsetHeight;
ctx.drawImage( this, 0, 0);
var imgPixels = ctx.getImageData(0, 0, w, h);
for(var y = 0; y < imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
$("<img class = \"img_grayscale\" src=\""+ canv.toDataURL() +"\" alt=\"\" />")
.insertBefore(el)
$(this).remove();
})
}
$(".item img").each(function(){
getGrayScale(this.src, $(this));
})
$(".item").delegate( ".img_grayscale", "mouseenter", function ( ) {
$(this).stop().animate({opacity:0}, 500)
}).delegate( ".img_grayscale","mouseout", function(){
$(this).stop().animate({opacity:1}, 500);
}).delegate( ".img_grayscale","click", function(){
$(this).remove();
});
});
add css:
.img_grayscale{ position:absolute;top:0;left:0;}
remove css:
.item img {opacity:0;}
i cant figure out what's wrong but this seems work as you expect

Categories