What Ember Add-on do I need for this situation? - javascript

I am wondering if there is an ember add-on that I can implement to do the following.
|-----------------------------------------------v----|
green yellow red
Color gradient bar of green > yellow > red and the v represents a value that lands there. Also where green, yellow, red start is based on values, so green could be 0-20 and yellow 21-40 and red 41+
I don't know what something like this would be called, but if anyone can let me know and help point me in the right direction, I would be much obliged.

Here you go:
var min = 0;
var max = 60;
function set(x) {
var left = (x - min) / (max - min) * 100;
document.getElementById("V").style.left = left + "%";
}
set(50);
#gauge {
background: linear-gradient(to right, green 0%, yellow 50%, red 100%);
height: 2em;
position: relative
}
#V {
width: 0;
height: 2.4em;
border: 1px solid black;
position: absolute;
top: -0.2em
}
<div id="gauge">
<div id="V"></div>
</div>

Related

CSS / JS - calculate angle and spacing for div

I am working on the mobile version of my website. I positioned one element below another (red below blue).
These elements are shaped with: clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 100% 62%, 50% 85%, 0% 62%).
They also got an overlay, which got a text positioned inside. My goal is to fix this text block in the lower right corner for every display resolution.
How it should look on every device:
How it looks, when I change the viewport width:
First I wrote several #media (...) queries, to position the text blocks.
I noticed that I would have to write a query for almost every device individually, since the required top-spacing and angle of the text blocks are always changing.
So I tried to calculate the needed angle and the needed value for top. I found a method on stackoverflow that looks like that:
function calculate() {
const deviceWidth = screen.width;
const viewportWidth = window.innerWidth;
const currentRatio = viewportWidth / deviceWidth;
const angle = currentRatio * ...; // I don't know
const top = ...; // I don't know
document.querySelector('.text-container').style.transform = `rotate(${angle}deg)`;
document.querySelector('.text-container').style.top = `${top}vh`;
}
calculate();
window.addEventListener('resize', calculate);
I'm pretty sure, that this method is a helpful fundamental, but I don't know how to move on.
Thanks.
I would do this differently using gradient and mask:
.box {
padding-top: 200px; /* this will control the overal height */
overflow:hidden;
position:relative;
}
.box div {
padding: 10px 0 10px 100%; /* padding-left:100% to push the text to the center */
color: #fff;
font-size:25px;
background: #248a8a;
transform-origin:bottom;
transform:rotate(-20deg); /* control the rotation of the text */
margin:0 -50% 0; /* negative margin to create some overlow and avoid the bad effect of rotation */
}
.one {
background:cyan;
}
.one::before {
content:"";
position:absolute;
z-index:9;
pointer-events:none;
inset:0;
background:
linear-gradient(to bottom right,#0000 49.8%,#dc143c 50%) bottom 0 right calc(50% - 500px),
linear-gradient(to bottom left ,#0000 49.8%,#dc143c 50%) bottom 0 left calc(50% - 500px);
/* keep the 1000px a random but big value
adjust 363px based on the angle you will be using
The formula is tan(20deg) = 363/1000
*/
background-size:1000px 363px;
background-repeat:no-repeat;
}
.two {
background:#dc143c;
-webkit-mask:
linear-gradient(to bottom right,#000 49.8%,#0000 50%) bottom 0 right calc(50% - 500px),
linear-gradient(to bottom left ,#000 49.8%,#0000 50%) bottom 0 left calc(50% - 500px);
/* same logic as above */
-webkit-mask-size:1000px 363px;
-webkit-mask-repeat:no-repeat;
}
.two div {
background:#7c2c3c;
}
<div class="box one">
<div>Text block 1</div>
</div>
<div class="box two">
<div>Text block 1</div>
</div>

How to adjust the mouse position after rotating an object?

I am trying to create an eye that follows cursor movement.
I got the horizontal and vertical coordinate of the mouse and the browser width and height.
Everything works perfectly. Except that I used rotate(45 deg) on the design of the eye so now the ball is not moving in the right position.
I was thinking about a math equation that finds the distance between the old and new coords, but I am not sure how to implement it.
Here is the full code:
https://jsfiddle.net/Mr_MeS/3ym6kuec/3/
so this is the .eye where its rotated
.eye {
width: 37.5px;
height: 37.5px;
background: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(45deg);
border-radius: 75% 0;
overflow: hidden;
cursor: pointer;
}
.ball {
width: 7.5px;
height: 7.5px;
background: #222f3e;
border-radius: 50%;
border: 5px solid #576574;
position: relative;
top: 50%;
left: 50%;
}
and here is the JS that does the work and needs to be edited.
var balls = document.getElementsByClassName("ball");
document.onmousemove = function () {
var x = event.clientX * 100 / window.innerWidth + "%";
var y = event.clientY * 100 / window.innerHeight + "%";
//event.clientX => get the horizontal coordinate of the mouse
//event.clientY => get the Vertical coordinate of the mouse
//window.innerWidth => get the browser width
//window.innerHeight => get the browser height
for (var i = 0; i < 2; i++) {
balls[0].style.left = x;
balls[0].style.top = y;
balls[0].style.transform = "translate(-" + x + ",-" + y + ")";
}
}
Now, if I remove the rotation from the .eye, it works perfectly, expect that the whole shape doesn't look to be in position.
If I keep the 45deg rotation, the shape is good, but the ball moves wrongly.
You could try to put the eye-background (the white part that needs to rotate 45 degrees) into a div (or pseudo-element) that's inside the .eye element. In that way you don't need to rotate the container element, so the coordination of the ball element stays the same.
Another point, why are you using that for-loop? I think running the code once will be sufficient :)
EDIT: I've been playing around with your example a bit and fixed it. What happens is that if you rotate an element, the direction in which things will transform (and top/left positioning) will also change. So moving the element 10px to the left, will go 10px to the left, under a 45 degree angle, because it's rotated 45 degrees.
What I did now was to put an element (.inner) inside the eye div, which I gave a counter-rotation of -45 degrees. In this way, the container element of the ball has the correct orientation again, which fixes the problem: https://jsfiddle.net/bxprjvgL/
HTML:
<div class="eye">
<div class="inner">
<div class="shut"><span></span></div>
<div class="ball"></div>
</div>
</div>
CSS:
.inner {
width: 100%;
height: 100%;
transform: rotate(-45deg);
}

moving div to left on scroll while its child stay fixed

I have a parent div. I want it to moves to left smoothly while scrolling down and moves to right while scrolling up. it has a p tag inside itself and I want the p tag stay fixed while the parent moves.
I wrote some codes but its not working at all. the sample codes are on fiddle
var p1 = document.getElementById('parallax1')
function parallaxbubbles() {
var scrolltop = window.pageYOffset
var scrollamount = (scrolltop / (scrollheight - windowheight)) * 100
p1.style.left = 35 + (scrollamount / 3) - 35 + '%'
}
window.addEventListener('scroll', function() {
requestAnimationFrame(parallaxbubbles)
}, false)
#parallax1 {
height: 100px;
width: 2539px;
top: 300px;
position: relative;
background: -webkit-linear-gradient(left top, red, yellow);
background: -o-linear-gradient(bottom right, red, yellow);
background: -moz-linear-gradient(bottom right, red, yellow);
background: linear-gradient(to bottom right, red, yellow);
}
#no1 {
height: 1000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="no1">
<div id="parallax1">
<h3>This is some text</h3>
<p>This is some text .</p>
</div>
</div>
You were missing some variables. I guess scrollheight is the window.scrollY . So i have declared the variable like that and the div moves to left when scroll down and to right when scroll up.
The amount of pixels it moves and other custom styling is up to you.
One weird thing in your calculation is that you have 35 + something - 35 . That's useless :) . I removed that.
I wrapped the text inside a container paraContent , which on scroll moves from left equal to the distance the parallax1 div moves to left. So it stays in the same initial position
See below
( i suggest you don't copy code from other sources before you understand how it works and how it can be edited )
var p1 = document.getElementById('parallax1')
var p1text = document.querySelector('.paraContent')
function parallaxbubbles() {
var scrolltop = window.pageYOffset,
scrollheight = window.scrollY,
windowheight = window.innerHeight,
scrollamount = (scrolltop / (scrollheight - windowheight)) * 100
p1.style.left = (scrollamount / 3) + '%'
p1text.style.left = -(scrollamount / 3) + '%'
}
window.addEventListener('scroll', function() {
requestAnimationFrame(parallaxbubbles)
}, false)
#parallax1 {
height: 100px;
width: 2539px;
top: 300px;
position: relative;
background: -webkit-linear-gradient(left top, red, yellow);
background: -o-linear-gradient(bottom right, red, yellow);
background: -moz-linear-gradient(bottom right, red, yellow);
background: linear-gradient(to bottom right, red, yellow);
}
#parallax1 .paraContent {
position: relative;
width: 100%;
}
#no1 {
height: 1000px;
}
<div id="no1">
<div id="parallax1">
<div class="paraContent">
<h3>This is some text</h3>
<p>This is some text .</p>
</div>
</div>
</div>
var p1 = $("#parallax1")
function parallaxbubbles() {
var scrolltop = window.pageYOffset;
var scrollheight = 100;
var windowheight = window.innerHeight;
var scrollamount = (scrolltop / (scrollheight - windowheight)) * 100;
p1.css("background-position", scrollamount + "px");
}
window.addEventListener('scroll', function() {
requestAnimationFrame(parallaxbubbles)
}, false)
#parallax1 {
height: 100px;
width: 100%;
top: 300px;
position: relative;
background: -webkit-linear-gradient(left top, red, yellow);
background: -o-linear-gradient(bottom right, red, yellow);
background: -moz-linear-gradient(bottom right, red, yellow);
background: linear-gradient(to bottom right, red, yellow);
}
#no1 {
height: 1000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="no1">
<div id="parallax1">
<h3>This is some text</h3>
<p>This is some text .</p>
</div>
</div>
You had some variables that were not defined. I couldn't really figure out what scrollheightis supposed to be based upon, but when you define the variables that are missing ( scrollheight and windowheight) you get the desired result.

CSS Box Shadow Overlap

I made a sliding puzzle in CSS, which you can view in this fiddle
The issue is that I wanted the tiles to have a drop shadow onto the gray background, but I didn't want the shadows to overlap other tiles, since they're all on the same level.
I've seen this question on StackOverflow, which is really asking the same thing, but I can't seem to get any of the solutions working.
I cannot cover the overlap with a pseudo-element, because they have background images whose background positions are set in JavaScript. While I could set them using complex CSS selectors that use nth-child, I'd rather keep it in JS for now.
I cannot put the shadow on a pseudo-element underneath the tile, because I don't know, actually. I tried it in the Fiddle I linked, but it's not working.
Any help would be appreciated. Thanks!
// This is the location of the empty square. At the start it's at 2, 2
var emptyRow = 2;
var emptyCol = 2;
// i and j, as passed in, are the tiles' original coordinates
var makeMoveHandler = function (tile, i, j) {
// row and col, as made here in closure, are the tiles up-to-date coordinates
var row = i;
var col = j;
// The click handler
return function () {
var rowOffset = Math.abs(emptyRow - row);
var colOffset = Math.abs(emptyCol - col);
// Move the tile to the vacant place next to it
if (rowOffset == 1 && colOffset == 0 || rowOffset == 0 && colOffset == 1) {
tile.style.transform = `translate(${emptyCol * 200}px, ${emptyRow * 200}px)`;
// Swap the two coordinates
[row, emptyRow] = [emptyRow, row];
[col, emptyCol] = [emptyCol, col];
}
}
};
var initTiles = function () {
// Get all of the rows
var rows = document.querySelectorAll('.row');
// Go through the rows
for (let i = 0; i < rows.length; ++i) {
var row = rows.item(i);
// Go through the tiles on each row
var tiles = row.querySelectorAll('.tile');
for (let j = 0; j < tiles.length; ++j) {
var tile = tiles.item(j);
// Add the click listener to the tile
tile.addEventListener('click', makeMoveHandler(tile, i, j));
// Set the location of the tile
tile.style.transform = `translate(${j * 200}px, ${i * 200}px)`;
// Set what part of the background to show on the tile
tile.style.backgroundPosition = `${600 - j * 200}px ${600 - i * 200}px`;
}
}
};
// Initialize the tiles
initTiles();
#puzzle {
width: 600px;
height: 600px;
display: flex;
background-color: gray;
border: 5px solid blue;
}
.tile {
width: 200px;
height: 200px;
border: 1px solid black;
background-image: url('http://www.lovethispic.com/uploaded_images/123553-Beautiful-Scene.jpg');
position: absolute;
background-size: 600px 600px;
transition: transform 300ms;
}
.tile:before {
background: transparent;
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -100;
box-shadow: 0 0 40px #000;
}
<div id="puzzle">
<div class="row">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>
<div class="row">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>
<div class="row">
<div class="tile"></div>
<div class="tile"></div>
</div>
</div>
You can use filter: drop-shadow(0 0 40px #000) on a new element which contains all your rows and tiles:
<div id="puzzle">
<div class="puzzle-inner" style="filter:drop-shadow(0 0 40px #000);">
<div class="row"> ...
This works on the accumulated 'silhouette' of it's contained elements.
This won't work on the #puzzle element itself, as it has a background set which will be included in the silhouette.
I finally found 2 methods of solving the problem, both aren't very pretty. I couldn't have a box-shadow, and I had come to terms with that. I could, however, create a pseudo-element that contained a picture of a box-shadow, so I did that.
I couldn't live with the idea that the browser would have to download an entirely separate image just for a shadow, so I made an approximation of a box-shadow using CSS3 gradients, which work (at least, in Chrome).
A snippet for the (sort of) simulated box-shadow:
div {
width: 200px;
height: 200px;
margin: 50px;
background-color: green;
position: relative;
opacity: 0.5;
}
div:before {
position: absolute;
content: '';
left: -20px;
right: -20px;
top: 0;
bottom: 0;
background: linear-gradient(90deg, transparent 220px, black 220px, transparent 240px ),
linear-gradient(-90deg, transparent 220px, black 220px, transparent 240px );
z-index: -1;
}
div:after {
position: absolute;
content: '';
top: -20px;
bottom: -20px;
left: 0;
right: 0;
background: linear-gradient(0deg, transparent 220px, black 220px, transparent 240px ),
linear-gradient(180deg, transparent 220px, black 220px, transparent 240px );
z-index: -1;
}
<div></div>
A JSFiddle with the sliding puzzle result, since it doesn't work properly in the snippets here.

Two arrows rotating inside a circle

So, the basic idea that I need to achieve is to have a simple circle that goes from 0 to 360 degrees.
Inside that circle are two arrows. I need them to rotate inside the circle.
One arrow needs to rotate degree per degree until it reaches a specified angle. The other needs to go directly to that angle.
So your arrows would both start at 0 degrees and if you specified you wanted to go to 100 degrees, one arrow would instantly jump and point towards 100 degrees, while the other would gradualy make it's way to 100 degrees.
EDIT:
Sorry about my lack of skill with stackoverflow (I just realised I never included a question into my question...). So I managed to get simple arrows down in canvas earlier through another question on stackoverflow, but when I started looking into actualy rotating the arrows, I just got lost in the code.
I guess my question was this: how can I apply rotation to my two arrows based on a degree value chosen by the user?
So here's what I managed to make my arrows with:
<html>
<head>
</head>
<body>
<canvas id="c" width="500" height="500"></canvas>
<script langauage="javascript">
<!--
ctx = document.getElementById("c").getContext("2d");
ctx.beginPath();
canvas_arrow(ctx,50,50,100,50);
canvas_arrow(ctx,50,50,10,30);
ctx.stroke();
function canvas_arrow(context, fromx, fromy, tox, toy){
var headlen = 10; // length of head in pixels
var dx = tox-fromx;
var dy = toy-fromy;
var angle = Math.atan2(dy,dx);
context.moveTo(fromx, fromy);
context.lineTo(tox, toy);
context.lineTo(tox-headlen*Math.cos(angle-Math.PI/6),toy-headlen*Math.sin(angle-Math.PI/6));
context.moveTo(tox, toy);
context.lineTo(tox-headlen*Math.cos(angle+Math.PI/6),toy-headlen*Math.sin(angle+Math.PI/6));
}
-->
</script>
</body>
</head>
The arrows are fine, but getting one of them to rotate while the other one jumps to the desired degree value is what I find hard. I can't find any examples or ideas on how to make them move based on a degree value given by a user.
With jQuery you can get the degrees depending on the mouse position -over your element, and apply the CSS3 transform rotate deg and set the animation transition time:
const $el = $('#circle'),
$cir = $el.children();
$el.on('click', evt => {
const o = $(evt.target).offset(),
rad = $el.width() / 2,
mPos = {
x: evt.pageX - o.left,
y: evt.pageY - o.top
},
a = Math.atan2(mPos.x - rad, mPos.y - rad),
d = -a / (Math.PI / 180) + 180;
$cir.css({transform: `rotate(${d}deg)`});
});
#circle {
position: relative;
width: 150px;
height: 150px;
border-radius: 50%;
font-family: arial, helvetica, sans-serif;
user-select: none; /* prevent text highlight */
cursor: pointer;
}
#circle>* {
text-align: center;
position: absolute;
border-radius: inherit;
width: inherit;
height: inherit;
}
#circle1 {
background: #eee;
transition: 1.3s;
}
#circle2 {
background: #fff;
transition: 0.3s;
top: 20px;
left: 20px;
width: calc(150px - 40px);
height: calc(150px - 40px);
}
<div id="circle">
<div id="circle1">▼</div>
<div id="circle2">▲</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

Categories

Resources