Making an image spin with css and jQuery - javascript

I'm trying to make a roulette wheel spin when clicking a button, but I can't seem to pass the random number generated from my js file to css
JS
function roulette_spin(btn){
var rand = Math.floor(Math.random() * 720) + 540;
$('.roulette_wheel').css('transform','rotate('+rand+'deg)');
}
HTML
<body>
<div class="roulette_wheel" style="z-index: 0;">
<img src="ayy.jpg" width="500px" height="500px" />
<button value="spin" onclick="roulette_spin(this)">SPIN</button>
</div>

Here is a working example with some updates to your code.
Like #H.Figueiredo suggests, I've changed the rotation selector to the img to avoid the rotation of the button.
HTML
<div class="roulette_wheel" style="z-index: 0;">
<img src="https://picsum.photos/200/300" width="500px" height="500px" />
<button class="spin" value="spin">SPIN</button>
</div>
CSS
function roulette_spin(btn){
var rand = Math.floor(Math.random() * 720) + 540;
$('.roulette_wheel img').css('transform','rotate('+rand+'deg)');
}
$('.spin').click(function(){
roulette_spin($(this).siblings('img'));
});
See this fiddle

I'd say the roulette_wheel class is not assigned to the proper element, the image.
Besides setting the rotate transform won't make the wheel spin, but will just change its rotation angle once (and here without any transition).
Below you will find a working example of assigning a transform style in an animation process.
JQuery calls were replaced by vanilla selectors (getElementsByClassName, getElementById) and style object manipulation instead of JQuery's css method.
Also, look into documentation for requestAnimationFrame
(OK I was a little bored here :) )
var force = 0;
var angle = 0;
var inertia = 0.985;
var minForce = 15;
var randForce = 15;
var rouletteElem = document.getElementsByClassName('roulette_wheel')[0];
var scoreElem = document.getElementById('score');
var values = [
0,27,10,25,29,12,8,19,31,18,6,21,33,16,4,
23,35,14,2,0,28,9,26,30,11,7,20,32,17,5,
22,34,15,3,24,36,16,1
].reverse();
function roulette_spin(btn){
// set initial force randomly
force = Math.floor(Math.random() * randForce) + minForce;
requestAnimationFrame(doAnimation);
}
function doAnimation() {
// new angle is previous angle + force modulo 360 (so that it stays between 0 and 360)
angle = (angle + force) % 360;
// decay force according to inertia parameter
force *= inertia;
rouletteElem.style.transform = 'rotate('+angle+'deg)';
// stop animation if force is too low
if (force < 0.05) {
// score roughly estimated
scoreElem.innerHTML = values[Math.floor(((angle / 360) * values.length) - 0.5)];
return;
}
requestAnimationFrame(doAnimation);
}
<body>
<div style="z-index: 0; position: relative">
<img class="roulette_wheel" src="http://pngimg.com/uploads/roulette/roulette_PNG14.png" width="300px" height="300px" />
<div style="position: absolute; top: 0px; left: 150px; background-color: red; width: 1px; height: 40px;"></div>
<button value="spin" onclick="roulette_spin(this)">SPIN</button>
<span id="score"></span>
</div>

Try this:
<html>
<body>
<div class="roulette_wheel" style="z-index: 0;">
<img src="ayy.jpg" width="500px" height="500px" />
<button value="spin" onclick="roulette_spin()">SPIN</button>
</div>
<script>
function roulette_spin(){
var rand = Math.floor(Math.random() * 720) + 540;
document.querySelector('.roulette_wheel').style.transform = 'rotate('+rand+'deg)';
}
</script>
</body>
</html>

Related

How to zoom an img in javascript and html

I'd like to zoom an img with a range button in javascript. However, I don't know how to control the last value the user inputs.
This is my html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Img Zoom</title>
<link rel="stylesheet" type="text/css" href="./css/style.css" />
</head>
<body>
<div id="divImg">
<img id="img" src="./img/rose.jpg" width="200px" height="200"" />
</div>
<div class="slidecontainer">
<label for="myRangeZ">Zoom</label>
<input type="range" min="1" max="100" value="20" class="slider" id="myRangeZ" onclick="jsZoom()">
</div>
</body>
<script src="./js/script.js">
</script>
</html>
and this my .js
var z, zoom;
function jsZoom() {
z = document.getElementById("myRangeZ").value;
console.log(z);
img = document.getElementById("img");
console.log(img.width);
console.log(img.height);
if (z > 20) {
zoom = 1.5;
}
else {
zoom = 0.5;
}
document.getElementById("img").style.width = (img.width * zoom) + "px";
document.getElementById("img").style.height = (img.height * zoom) + "px";
}
When the user goes from 20% to 100% the img is getting bigger, but if the range goes from 100% to 20% the img is not decreasing and it's still getting bigger. I can solve this issue with 2 bottons ( ) but I want it with a range button.
You read the width every time it changes. So you are basing the width off at that moment in time, not the time when the image was added to the page. You need to store the initial value. You can then alter the zoom code however you like to change the size based on the original dimensions.
var z, zoom;
function jsZoom() {
z = document.getElementById("myRangeZ").value;
img = document.getElementById("img");
if (!img.dataset.width) {
img.dataset.width = img.width;
img.dataset.height = img.height;
}
const width = +img.dataset.width;
const height = +img.dataset.height;
img.style.width = (width * z/100 + width) + "px";
img.style.height = (height * z/100 + height) + "px";
}
jsZoom();
img {
transition: 0.2s;
}
<div id="divImg">
<img id="img" src="https://placekitten.com/300/300" width="200px" height="200"" />
</div>
<div class="slidecontainer">
<label for="myRangeZ">Zoom</label>
<input type="range" min="1" max="100" value="20" class="slider" id="myRangeZ" oninput="jsZoom()">
Here's a simpler way:
Wrap everything in a <form>. You'll have complete control of all form controls within it.
Place <img> in a block level tag. In the example the <img> is inside a <fieldset> which is not only a block level tag, it's also a form control.
Assign the following ruleset to <img>:
img { object-fit: contain; width: 100% }
This CSS ruleset will ensure that the <img> will conform to it's container (ex. <fieldset>) and maintain aspect ratio as well.
Details are commented in example
// Bind input event on <form>
document.forms.UI.oninput = scaleFrame;
function scaleFrame(e) {
// Reference all form controls
const IO = this.elements;
/*
If the user is interacing with <input>...
...get the value of <input> and convert it into a number...
...set <fieldset> CSS transform:scale() property to the value of <input>...
...display value of <input> with <output>
*/
if (e.target.id === 'scale') {
let size = parseFloat(e.target.value);
IO.frame.style.cssText = `transform: scale(${size})`;
IO.view.value = size;
}
}
html {
font: 300 2ch/1 Consolas;
}
#frame {
width: 200px;
height: 200px;
transform-origin: top left;
}
label {
display: flex;
align-items: center;
}
img {
object-fit: contain;
width: 100%;
}
input,
output {
display: inline-block;
}
#scale {
margin-right: 1rem;
cursor: pointer;
}
<form id='UI'>
<label>
<input id='scale' type='range' min='.1' max='2.5' step='any' value='1'>
x<output id='view'>1.0</output>
</label>
<fieldset id='frame'>
<img src="https://i.ibb.co/hZj77BZ/lena01.jpg" alt="Lena Forsén (Söderberg) 1972">
</fieldset>
</form>
The image can become bigger in size after decreasing the slider because it is set to become 1.5 larger than itself every time the slider is set to a value above 20.
To fix this, simply store the original width and height of the image in a variable so the previous resizing events don't affect additional scaling.
var z, zoom;
var originalWidth = document.getElementById("img").width;
var originalHeight = document.getElementById("img").height;
function jsZoom() {
z = document.getElementById("myRangeZ").value;
img = document.getElementById("img");
if (z > 20) {
zoom = 1.5;
}
else {
zoom = 0.5;
}
document.getElementById("img").style.width = (originalWidth * zoom) + "px";
document.getElementById("img").style.height = (originalHeight * zoom) + "px";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Img Zoom</title>
<link rel="stylesheet" type="text/css" href="./css/style.css" />
</head>
<body>
<div id="divImg">
<img id="img" src="https://cdn.commercev3.net/cdn.edmundsroses.com/images/popup/23703.jpg" width="200px" height="200"" />
</div>
<div class="slidecontainer">
<label for="myRangeZ">Zoom</label>
<input type="range" min="1" max="100" value="20" class="slider" id="myRangeZ" onclick="jsZoom()">
</div>
</body>
<script src="./js/script.js">
</script>
</html>
The problem here is that your function is using the width and height from the image, which is obviously being changed by your function. The issue should be solved by saving the initial width and height and referencing those in the last two lines of your function.
These are just "by-the-ways", but I also refactored the if/else statement and moved the width and height console.log statements to the end for the dimensions to be printed after they're updated.
var z, zoom;
var img = document.getElementById("img");
var width = img.width;
var height = img.height;
function jsZoom() {
z = document.getElementById("myRangeZ").value;
console.log(z);
zoom = z > 20 ? 1.5 : 0.5;
img.style.width = (width * zoom) + "px";
console.log(img.width);
img.style.height = (height * zoom) + "px";
console.log(img.height);
}
EDIT: The width and height variables should remain outside the function to prevent them from being updated by it and affecting the zoom as a result.

Trying to keep the random placement of my folders within the window. At the moment it seems to overflow on the x and y axis

I am trying to keep the random placement of my folders within the window. At the moment it seems to overflow on the x-axis and y-axis. Are you able to help? I'm sure this is a simple fix.
The goal is to have the set of folders randomly placed on the screen, but never be placed outside of the screen height and width.
<style>
/* Background Color */
body {
background-color: lightcoral;
}
/* Div position and placement */
div {
position: absolute;
top: 100px;
left: 100px;
}
</style>
<body>
<div class="container">
<div><img src="/images/folder.png" width="100px" /></div>
<div><img src="/images/folder.png" width="100px" /></div>
<div><img src="/images/folder.png" width="100px" /></div>
<div><img src="/images/folder.png" width="100px" /></div>
<div><img src="/images/folder.png" width="100px" /></div>
<div><img src="/images/folder.png" width="100px" /></div>
<div><img src="/images/folder.png" width="100px" /></div>
</div>
</body>
<script>
// collect all the div folders
var folderDivs = document.getElementsByTagName("div");
// get window width and height
var winWidth = window.innerWidth;
var winHeight = window.innerHeight;
// i stands for "index". you could also call this banana or haircut. it's a variable
for (var i = 0; i < folderDivs.length; i++) {
// shortcut! the current div in the list
var thisDiv = folderDivs[i];
// get random numbers for each element
randomTop = getRandomNumber(0, winHeight);
randomLeft = getRandomNumber(0, winWidth);
// update top and left position
thisDiv.style.top = randomTop + "px";
thisDiv.style.left = randomLeft + "px";
}
// function that return a random number between a min and max
function getRandomNumber(min, max) {
return Math.random() * (max - min) + min;
}
</script>
Do not use getElementsByTagName("div") because this applies also to
div class="container"
Instead use
var folderDivs = document.querySelectorAll(".container div");
Subtract image size from allowed place
In your style part you have set top and left position to each div. This rule applies to container div too.
Notice: Your images are in div with class "container" but this div is positioned 100px left and 100px top.
So all your images have 100px left and top offset.
200 = 100 (for image size) + 100 (for container offset)
var imgSizeWithOffset = 200;
// get random numbers for each element
randomTop = getRandomNumber(0, winHeight-imgSizeWithOffset);
randomLeft = getRandomNumber(0, winWidth-imgSizeWithOffset);
If you decide you don't need this container offset you can set your style like this and use 100
<style>
/* Background Color */
body {
background-color: lightcoral;
}
/* Div position and placement */
.container div {
position: absolute;
}
</style>

how to fix issue with youtube player not showing up with full width & height?

Below is sample of my code im trying to use playlist where the player will be in full width and height but for some reason it's not working. So what i'm trying to accomplish is the player will be on full page without anything else. Nothing else will show up example link here is link for fiddle any help will be appreciated.
COPY of code
<html>
<head>
</head>
<body onload="load()" style="background-color:white">
<script type="text/javascript">
var playlisturl = "http://gdata.youtube.com/feeds/api/playlists/PL704DA9FE5E10160C?v=2";
var playlisturls = ["http://gdata.youtube.com/feeds/api/playlists/PL704DA9FE5E10160C?v=2"];
var pause_playlist_text = "Pause playlist (loop current video)";
var embed = true;
var autoplay = true;
var vwidth = 400;
var vheight = 500;
</script>
<script type="text/javascript" src="http://youtube-playlist-randomizer.valami.info/seedrandom.js"></script>
<script type="text/javascript" src="http://youtube-playlist-randomizer.valami.info/playlist2-min.js"></script>
<div id="control_buttons" style="display:none">
<button style="display:none" id="nextbutton" onclick="next()">Play next</button> <span style="display:none" id="videosleft"></span> <button style="display:none" id="previousbutton" onclick="previous()">Play previous</button>
<button style="display:none" id="pauseplaylist" onclick="pause_playlist()">Pause playlist (loop current video)</button> <button style="display:none" onclick="reshuffle()">Reshuffle</button>
</div>
<script type="text/javascript">
document.getElementById('pauseplaylist').style.display = "none"
</script>
<div id="video">
<p>Loading playlist...</p>
</div>
<div class="videowrapper">
<div id="myytplayer"></div>
</div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var ytplayer;
function onYouTubeIframeAPIReady()
{
ytplayer = new YT.Player('myytplayer', {
height: vheight,
width: vwidth,
videoId: '8tPnX7OPo0Q',
events: {
'onReady': onYouTubePlayerReady,
'onStateChange': onytplayerStateChange,
'onError': onytplayerError
}
});
}
</script>
</body>
</html>
Make the container width and height 100%, Check this out :
#myytplayer {
width:100%;
height:100%;
}
.videowrapper {
width:100%;
height:100%;
}
Hi, you could use tubular: http://www.seanmccambridge.com/tubular/
as tubular is quite suffisticated, i extracted the necessary code
for you. (renders the video in full width and height, NOT stetched, similar to a css cover image)
html code:
<div id="player-container" style="overflow: hidden; position: absolute; width: 100%; height: 100%;">
<div id="player" style="position: absolute">
</div>
here comes the complete youtube API cover style stuff, extracted from
tubular. jquery is needed. Also the standard youtube html5 iframe api
code must be included - as given here:
https://developers.google.com/youtube/iframe_api_reference#Getting_Started
var ratio = 16 / 9;
window.onPlayerReady = function (e) {
resize();
}
$(window).on('resize', function () {
resize();
})
var resize = function () {
console.log("resize");
var heightcorrection = 0,
width = $(window).width(),
pWidth, // player width, to be defined
height = $(window).height() - heightcorrection,
pHeight, // player height, tbd
$videoPlayer = $('#player');
if (width / ratio < height) { // if new video height < window height (gap underneath)
pWidth = Math.ceil(height * ratio); // get new player width
$videoPlayer.width(pWidth).height(height).css({
left: (width - pWidth) / 2,
top: 0
}); // player width is greater, offset left; reset top
} else { // new video width < window width (gap to right)
pHeight = Math.ceil(width / ratio); // get new player height
$videoPlayer.width(width).height(pHeight).css({
left: 0,
top: (height - pHeight) / 2
}); // player height is greater, offset top; reset left
}
}

Why can't I get the proper y position in JavaScript?

When I run the function spin() for the first time, it works. I get the y coordinate of the image called num, which is 470. In every run that follows, it stays 470, even though you can see the image move!
<p id="demo">Click the button to display the y position.</p>
<div style="position:absolute; top:450px; width:300px; height:140px; overflow:hidden; background-color:black;">
<div style="position:relative; top:20px; left:30px; width:80px; height:100px; overflow:hidden; background-color:white;">
<img id="numbers" src="numbers.png" style="position: absolute; left: 8px;">
</div>
<button id="spinButton" style="position: relative; left: 200px; width: 80px;" onclick="spin();">SPIN</button>
</div>
var num = document.getElementById("numbers");
var spn_btn = document.getElementById("spinButton");
function spin() {
//generate a random offset value divisible by 100
var newNumber = (randomNumber() * 100) + 300;
//Debug
document.getElementById("demo").innerHTML = num.y;
TweenMax.to(num, 2, {
y: -newNumber
});
}
function randomNumber() {
var rand = Math.floor(Math.random() * 10);
return rand;
}
(Uses TweetMax)
It looks like the problem is with this line:
TweenMax.to(num, 2, {y:-newNumber});
I'm not familiar with this library so I don't know if it's doing what it's supposed to. Also I don't see the image popping up on my screen anywhere. Can you expand on what the desired functionality is?

Javascript slideshow, image skips on first playthrough?

I have created the following slideshow in javascript. But for some reason on the first slide through of images, the first image just moves off and the second image does the "sliding". Any help would be appreciated. I have included comments to help make the code more readable.
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
img.pic {
position: absolute;
height: 768px;
width: 1024px;
}
html, body {
background-color:#3b3b35;
width: 1024px;
height: 768px;
margin: 0;
padding: 0;
overflow:hidden;
}
</style>
</head>
<body onload="startImages()">
<img class="pic" id="slide0" src="1.jpg" alt="pic1" />
<img class="pic" id="slide1" src="2.jpg" alt="pic2" />
<img class="pic" id="slide2" src="3.jpg" alt="pic3" />
<img class="pic" id="slide3" src="4.jpg" alt="pic4" />
<img class="pic" id="slide4" src="5.jpg" alt="pic5" />
<img class="pic" id="slide5" src="6.jpg" alt="pic6" />
<img class="pic" id="slide6" src="7.jpg" alt="pic7" />
<img class="pic" id="slide7" src="8.jpg" alt="pic8" />
<img class="pic" id="slide8" src="9.jpg" alt="pic9" />
<img class="pic" id="slide9" src="10.jpg" alt="pic10" />
<script type="text/javascript">
// Define the x start variable
var xstart = 0;
// Constructor for an image object:
function Image(obj, x) {
this.object = obj;
this.xpos = x;
}
// Image array
var Images = [];
// Sets up the images
function startImages() {
for (var Imageamount = 0; Imageamount < 10; Imageamount++) {
var Imgstore = document.getElementById("slide" + Imageamount);
// Puts image in the array
Images[Imageamount] = new Image(Imgstore, xstart);
xstart = xstart - 1024;
}
// Controlls the delays
setInterval(function () {
var val = 0;
var Interval = setInterval(function () {
imSlide();
val++;
if (val == 16) clearInterval(Interval); // 16*64 = 1024, ie image size
}, 30);
}, 5000);
}
function imSlide() { // Controlls sliding
for (var Slide = 0; Slide < Images.length; Slide++) {
var image = Images[Slide];
// Update + 64 to give a smooth slide. Updates 16 times so 16*64=1024
var x = image.xpos + 64;
// Move image from far right back to front of image stack
if (x == 5120) {
x = -5120;
}
// Store position back in array
image.xpos = x;
// Move the image
image.object.style.left = x + "px";
}
}
</script>
</body>
</html>
The reason that your slide show skips on the first interval is because you aren't setting the image's position when you first create your Image objects; you're only setting a variable that you have named 'xpos'. This causes all your images to overlap each other and display the last image, #slide9, on top of the others on page load.
modify your Image object declaration to this:
function Image(obj, x) {
this.object = obj;
this.xpos = x;
this.object.style.left = x + "px"; //<--- this is the new part
}
here is the jsfiddle: http://jsfiddle.net/w9qQx/4/

Categories