I wanted to make a rectangle move in 4 directions with a click of a button on JavaScript. Only the Right and Down works and the other two does not work. I tried finding it on internet and so far had not have any luck.
var currentXpos = 0;
function moveRectRight() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginRight = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginBottom = currentXpos + 'px'; // re-draw rectangle
}
function moveRectDown() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}
#rectangle {
background-color: red;
width: 200px;
height: 100px;
margin-left: 0px;
}
<div id='rectangle'></div>
<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />
Your problem lies on this code
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginRight = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginBottom = currentXpos + 'px'; // re-draw rectangle
}
when you move left you tried to add the margin right and when you move up you add margin bottom. This is a wrong concept, you shouldn't imagine it like the box is being pushed from 4 side like this image
When you code in HTML & CSS, try to imagine that in coordinate, the 0,0 (x and y) is on your upper left corner of browser, and to move them you can only move them away or closer to the 0,0, like below
I suggest you to learn/debug using the developer tools you can see where it goes wrong,
So the answer is just changing the code to marginLeft and marginTop
That aside, I made my own version maybe you want to check it out
<html>
<head>
<style>
#rectangle {
background-color: red;
width: 200px;
height: 100px;
position: fixed;
}
</style>
</head>
<body>
<div id='rectangle' style="top:100px;left:100px;"></div>
<input type="button" value="Right" onclick="moveRect(this)" />
<input type="button" value="Left" onclick="moveRect(this)" />
<input type="button" value="Up" onclick="moveRect(this)" />
<input type="button" value="Down" onclick="moveRect(this)" />
<script>
const distance = 10;
const directionMap = {
'Up': {
'prop': 'top',
'value': -1
},
'Down': {
'prop': 'top',
'value': 1
},
'Left': {
'prop': 'left',
'value': -1
},
'Right': {
'prop': 'left',
'value': 1
},
}
const parsePosition = (prop) => parseFloat(rectangle.style[prop]) || 0;
const moveRect = (element) => {
let {
prop,
value
} = directionMap[element.value];
rectangle.style[prop] = (parsePosition(prop) + (value * distance)) + "px";
}
</script>
</body>
</html>
Because margins in the HTML, depend on having a neightbor. So, you'll not see margin-right and margin-bottom working, hence you'll not see the box going up or left.
Instead, what you can do, is affect the same property with addition and substraction. For Y affect only margin-top and for X affect only margin-left
CSS Documentation
<html>
<head>
<style>
#rectangle {
background-color: red;
width: 200px;
height: 100px;
margin-left: 0px;
}
</style>
</head>
<body>
<div id='rectangle'>
</div>
<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />
<script>
var currentXpos = 0;
function moveRectRight() {
var rect = document.getElementById('rectangle');
console.log(rect)
currentXpos += 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos -= 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentXpos -= 100; // move by 100 px to the right
rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}
function moveRectDown() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}
</script>
</body>
</html>
Thremulant gave a very good solution but there was something missed something the "current position" variable should be different for X and Y axis. This way it will not show abnormal behaviour.
<html>
<head>
<style>
#rectangle {
background-color: red;
width: 200px;
height: 100px;
margin-left: 0px;
}
</style>
<script>
var currentXpos = 0;
var currentYpos = 0;
function moveRectRight() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos -= 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentYpos -= 100; // move by 100 px to the right
rect.style.marginTop = currentYpos + 'px'; // re-draw rectangle
}
function moveRectDown() {
var rect = document.getElementById('rectangle');
currentYpos += 100; // move by 100 px to the right
rect.style.marginTop = currentYpos + 'px'; // re-draw rectangle
}
</script>
</head>
<body>
<div id='rectangle'></div>
<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />
</body>
</html>
I'm hoping someone can help. I'm doing a drawing app. I'm working on
adjusting the line width on the canvas using the slider. If a user
selects 2 on the slider then line width should be thin, 40 would be a
very thick line.
Many thanks in advance,
Filipe
This is my HTML
<div id="theLineWidthSection" style="float:right; margin-right:170px;
margin-top:-42px; position:relative;z-index:9999; cursor:pointer;
overflow:hidden;">
Size: <input type="range" id="theLineWidth" min="2" max="40"
value="2" title="Line width">
</div>
This is my Javascript
$('#theLineWidth').change(function () {
var canvas = document.getElementById('drawingCanvas');
var lineSize = document.getElementById('theLineWidth');
var mySize = lineSize.value;
lineSize.addEventListener('change', changeLineWidth);
function changeLineWidth(){
mySize = lineSize.value;
context.lineWidth = mySize;
context.lineWidth = lineSize.value;
}
});
When the slider is changed the linewidth doesn't change.
The problem is that you are not taking the canvas context before applying the line-width change. This should fix it:
var canvas = document.getElementById('drawingCanvas');
var context = canvas.getContext("2d")
var lineSize = document.getElementById('theLineWidth');
var mySize = lineSize.value;
$('#theLineWidth').change(function () {
mySize = lineSize.value;
context.lineWidth = mySize;
});
Also, take your variables out of the function. There is no need of redefining them each time the change event is fired.
This is a demo where I'm changing the linewidth on canvas using slider.
The event I'm using is input that fires when the value of input changes.
I hope it helps.
var canvas = document.getElementById('drawingCanvas');
var context = canvas.getContext("2d");
var mySize = 2;
//draw something on the canvas
draw();
theLineWidth.addEventListener("input",function () {
var mySize = theLineWidth.value;
// change the line width
context.lineWidth = mySize;
draw();
});
// a function that is drawing something on the canvas
function draw(){
//first clear the context
context.clearRect(0,0,canvas.width,canvas.height);
// next draw
context.beginPath();
context.moveTo(10,75);
context.lineTo(290,75);
context.stroke();
}
#theLineWidthSection {
float: right;
margin-right: 170px;
/* margin-top: -42px;*/
position: relative;
z-index: 9999;
cursor: pointer;
outline:1px solid;
/*overflow: hidden;*/
}
canvas{border:1px solid}
<div>
Size: <input type="range" id="theLineWidth" min="2" max="40"
value="2" title="Line width">
</div>
<canvas id="drawingCanvas"></canvas>
I am trying to draw quadratic curve on movement of slider. So as slider moves curve will be drawn. I want to do this for quadratic curve and also for bezier curve. This is my code it will work only in chrome
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
.wrapper {
margin: 0 auto;
width: 1000px;
}
.canHdr {
float: left;
width: 450px;
height: 400px;
border: 1px solid red;
}
</style>
</head>
<body>
<form>
<!-- wrapper -->
<div class="wrapper">
<!-- canHdr -->
<div id="canHdr" class="canHdr" >
<p>
This is my 1st div with quadratic curve I want to draw this curve as I move the slider. I want to make it dynamic so when I should be able to change the curve points. Also I want to move an object on that curve as I am doing in my 3rd div.
</p>
<div class="canOuterHdr" >
<canvas id="myCanvas1" width="300" height="195" style="position: relative;">
[No canvas support]
</canvas>
</div>
<div id="slider1" class="newBg">
<input id="slide1" type="range" min="0" max="100" step="1" value="0" onchange="counterSlider('slide1');" />
</div>
</div>
<!--/ canHdr -->
<!-- canHdr2 -->
<div id="canHdr2" class="canHdr" >
<p>
This is my 2nd div. I have bezier curve. I want to make it dynamic so when I should be able to change the curve points. Also I want to move an object on that curve as I am doing in my 3rd div.
</p>
<div class="canOuterHdr" >
<canvas id="myCanvas2" width="300" height="195" style="position: relative;">
[No canvas support]
</canvas>
</div>
<div id="slider2" class="newBg">
<input id="slide2" type="range" min="0" max="100" step="1" value="0" onchange="counterSlider('slide2');" />
</div>
</div>
<!-- canHdr2 -->
</div>
<!-- /wrapper -->
<script type="text/javascript">
// newSprite('myCanvas3', 16, 170);
quadraticCurve('myCanvas1', 18.8, 45, 28, 160, 228, 165);
bezierCurve('myCanvas2', 20, 75, 55.2, 150.0, 200,100, 228, 165)
function counterSlider(sID) {
var slideVal = document.getElementById(sID).value;
/*if (maxValue ==100){
slideVal=slideVal/100;
}*/
slideVal = slideVal / 100;
if (slideVal == 0) {
/* erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');*/
//newSprite('myCanvas1b', 18.8, 45);
// newSprite('myCanvas3', 16, 170);
} else if (slideVal > 0 && slideVal <= 34) {
/*erase('myCanvas1');
//erase('myCanvas1b');
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');*/
} else if (slideVal > 34 && slideVal <= 67) {
/*erase('myCanvas1');
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');*/
} else if (slideVal > 67 && slideVal <= 100) {
/*erase('myCanvas1');
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');*/
}
}
function erase(canvasId) {
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.beginPath();
context.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = canvas.width;
}
/**********for backgroundImage********************/
function quadraticCurve(canId, spx, spy, cpx, cpy, endx, endy) {
var canvas = document.getElementById(canId);
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(spx, spy);
ctx.quadraticCurveTo(cpx, cpy, endx, endy);
ctx.strokeStyle = "#eaca2d";
ctx.stroke();
}
function bezierCurve(canId, spx, spy, cpx1, cpy1, cpx2, cpy2, endx, endy) {
var canvas = document.getElementById(canId);
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(spx, spy);
ctx.quadraticCurveTo(cpx1, cpy1, cpx2, cpy2, endx, endy);
ctx.strokeStyle = "#eaca2d";
ctx.stroke();
}
function newSprite(canId, mvx, mvy) {
var canvas = document.getElementById(canId);
var ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = 'source-over';
//ctx.globalCompositeOperation = "destination-over";
ctx.beginPath();
ctx.fillStyle = "#0077c1";
ctx.arc(mvx, mvy, 6, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
</script>
</form>
</body>
</html>
This is the link for jsfiddle: http://jsfiddle.net/Y5yYD/1/
Here’s how to incrementally draw quad & cubic bezier curves with a slider
Example Fiddle: http://jsfiddle.net/m1erickson/auFam/
This function will return an XY point at the specified percentage of a Quad curve:
// quadratic bezier: percent is 0-1
function getQuadraticBezierXY(percent,startPt,controlPt,endPt) {
var x = Math.pow(1-percent,2) * startPt.x + 2 * (1-percent) * percent * controlPt.x + Math.pow(percent,2) * endPt.x;
var y = Math.pow(1-percent,2) * startPt.y + 2 * (1-percent) * percent * controlPt.y + Math.pow(percent,2) * endPt.y;
return( {x:x,y:y} );
}
This function will return an XY point at the specified percentage of a Cubic curve:
// cubic bezier pct is 0-1
function getCubicBezierXY(pct,startPt,controlPt1,controlPt2,endPt){
var x=CubicN(pct,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(pct,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic formula at percent distance
function CubicN(pct, a,b,c,d) {
var t2 = pct * pct;
var t3 = t2 * pct;
return a + (-a * 3 + pct * (3 * a - a * pct)) * pct
+ (3 * b + pct * (-6 * b + b * 3 * pct)) * pct
+ (c * 3 - c * 3 * pct) * t2
+ d * t3;
}
Here is example code and a Fiddle: http://jsfiddle.net/m1erickson/auFam/
<!doctype html>
<html lang="en">
<head>
<style>
body{ background-color: ivory; }
#wrapper{ position:relative; }
canvas{ position:absolute; left:40px; top:5px; border:1px solid blue;}
#amount{ position:absolute; left:1px; top:5px; margin-bottom:15px; width:23px; border:0; color:#f6931f; font-weight:bold; }
#slider-vertical{ position:absolute; left:5px; top:40px; width:15px; height:225px; border:0px; color:#f6931f; font-weight:bold; }
</style>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
$(function() {
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// starting value
var startingSliderValue=50;
drawBoth(startingSliderValue);
$( "#slider-vertical" ).slider({
orientation: "vertical",
range: "min",
min: 0,
max: 100,
value: startingSliderValue,
slide: function( event, ui ) {
$( "#amount" ).val( ui.value );
drawBoth( $("#amount").val() );
}
});
$( "#amount" ).val( $( "#slider-vertical" ).slider( "value" ) );
function drawBoth(sliderValue){
ctx.clearRect(0,0,canvas.width,canvas.height);
drawQuadBezier(sliderValue/100);
drawCubicBezier(sliderValue/100);
}
function drawQuadBezier(pct){
var startPt={ x:18.8, y:45 };
var controlPt={ x:28, y:160};
var endPt={ x:228, y:165 };
ctx.beginPath();
ctx.moveTo(startPt.x,startPt.y);
for(var p=0;p<=pct;p+=.01){
var pt=getQuadraticBezierXY(p,startPt,controlPt,endPt)
ctx.lineTo(pt.x,pt.y);
}
ctx.strokeStyle="green";
ctx.stroke();
var pt=getQuadraticBezierXY(pct,startPt,controlPt,endPt)
drawDot(pt.x,pt.y,"#0077c1");
}
function drawCubicBezier(pct){
var startPt={ x:20, y:75 };
var controlPt1={ x:55.2, y:150};
var controlPt2={ x:200, y:100};
var endPt={ x:228, y:165 };
ctx.beginPath();
ctx.moveTo(startPt.x,startPt.y);
for(var p=0;p<=pct;p+=.01){
var pt=getCubicBezierXY(p,startPt,controlPt1,controlPt2,endPt);
ctx.lineTo(pt.x,pt.y);
}
ctx.strokeStyle="red";
ctx.stroke();
var pt=getCubicBezierXY(pct,startPt,controlPt1,controlPt2,endPt);
drawDot(pt.x,pt.y,"#0077c1");
}
// just draw a dot at xy
function drawDot(x,y,color){
ctx.fillStyle=color;
ctx.beginPath();
ctx.arc(x,y,6,0,Math.PI*2,false);
ctx.closePath();
ctx.fill();
}
// quadratic bezier: percent is 0-1
function getQuadraticBezierXY(percent,startPt,controlPt,endPt) {
var x = Math.pow(1-percent,2) * startPt.x + 2 * (1-percent) * percent * controlPt.x + Math.pow(percent,2) * endPt.x;
var y = Math.pow(1-percent,2) * startPt.y + 2 * (1-percent) * percent * controlPt.y + Math.pow(percent,2) * endPt.y;
return( {x:x,y:y} );
}
// cubic bezier pct is 0-1
function getCubicBezierXY(pct,startPt,controlPt1,controlPt2,endPt){
var x=CubicN(pct,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(pct,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic formula at percent distance
function CubicN(pct, a,b,c,d) {
var t2 = pct * pct;
var t3 = t2 * pct;
return a + (-a * 3 + pct * (3 * a - a * pct)) * pct
+ (3 * b + pct * (-6 * b + b * 3 * pct)) * pct
+ (c * 3 - c * 3 * pct) * t2
+ d * t3;
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="wrapper">
<input type="text" id="amount" />
<div id="slider-vertical"></div>
<canvas id="canvas" width=300 height=300></canvas>
</div>
</body>
</html>
I want to rotate a div in 20 degrees in below opera 10.50 versions
below is my Javascript code for rotate the div:
<script type="text/javascript">
function rotator(value) {
document.getElementById('divId').style.webkitTransform = "rotate(" + value + "deg)";
document.getElementById('divId').style.msTransform = "rotate(" + value + "deg)";
document.getElementById('divId').style.MozTransform = "rotate(" + value + "deg)";
document.getElementById('divId').style.OTransform = "rotate(" + value + "deg)";
document.getElementById('divId').style.transform = "rotate(" + value + "deg)";
document.getElementById('span1').innerHTML = value + " deg";
}
</script>
HTML Code:
<body>
<div id="divId" style="height: 150px; width: 150px background-color:red; border: 1px solid #000;">
This is Rotator Div
</div>
<br />
Rotate:
<input type="range" min="-360" max="360" value="0" onchange="rotator(this.value)" /><br />
Rotate Div in <span id="span1">Zero deg</span>
</body>
How can I resolve my problem?
CSS rotate transforms are not supported in Opera versions below 10.5, that's why this JavaScript method of you doesn't work.
See: http://caniuse.com/#feat=transforms2d
What you can do is rotate your image in photoshop and then upload that image with a transparent background, but then the image would be static of course and I doubt that's what you desire.
I am using jcrop for the first time. ANd I have a problem with image size and cropping. When user upload image 1366x768 or larger I preview it on my page. I also have crop selection preview and it works fine. When I submit positions it crops fine (it's when I use original image size).
But I don't want to display so large original images on page. User must see original image, preview and submit buttons in one view. So I need to make image smaller if image is 1366x768 I wan't to display it like 683x368. But here is the problem. When I set width and height on image tag crop not works fine anymore. I paste my code and image preview of my problem:
jQuery(window).load(function () {
jQuery('#cropbox').Jcrop({
onChange: showPreview,
onSelect: showPreview,
setSelect: [0, 0, 540, 300],
allowResize: true,
aspectRatio: 2
});
});
function showPreview(coords) {
if (parseInt(coords.w) > 0) {
var rx = 540 / coords.w;
var ry = 300 / coords.h;
jQuery('#preview').css({
width: Math.round(rx * 683) + 'px',
height: Math.round(ry * 368) + 'px',
marginLeft: '-' + Math.round(rx * coords.x) + 'px',
marginTop: '-' + Math.round(ry * coords.y) + 'px'
});
}
$('#x').val(coords.x);
$('#y').val(coords.y);
$('#w').val(coords.w);
$('#h').val(coords.h);
}
</script>
</head>
<body>
<div>
<p style="width: 540px; height: 300px; overflow: hidden; float:left;">
<img id="preview" src="../../Content/Images/Full/Leopard.jpg" />
</p>
<p style="float:left;">
<img id="cropbox" width="683px" height="368px" src="../../Content/Images/Full/Leopard.jpg" />
</p>
<p>
#using (#Html.BeginForm("PostPicture", "Home"))
{
<input type="hidden" id="x" name="x" />
<input type="hidden" id="y" name="y" />
<input type="hidden" id="w" name="w" />
<input type="hidden" id="h" name="h" />
<button type="submit">
Send</button>
}
</p>
This is second error: After I multiply X and Y with 2.
This is asp.net back end code:
public ImageResult PostPicture(int x, int y, int h, int w)
{
x = x * 2;
y = y * 2;
Image image = Image.FromFile(Path.Combine(this.Request.PhysicalApplicationPath, "Content\\Images\\Full\\Leopard.jpg"));
Bitmap cropedImage = new Bitmap(w, h, image.PixelFormat);
Graphics g = Graphics.FromImage(cropedImage);
Rectangle rec = new Rectangle(0, 0,
w,
h);
g.DrawImage(image, rec, x, y, w, h, GraphicsUnit.Pixel);
image.Dispose();
g.Dispose();
string savedFileName = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Content", "Images", "Full",
Path.GetFileName("cropped.jpg"));
cropedImage.Save(savedFileName);
return new ImageResult { Image = cropedImage, ImageFormat = ImageFormat.Jpeg };
}
Maybe try setting the image size in css style attribute:
<img id="cropbox" style="width:683px;height:368px" src="../../Content/Images/Full/Leopard.jpg" />
Perhaps a better solution is to resize the image on the server to your desired dimensions, then display the resized image to the user instead of the full original image. This will also reduce download time for the browser since the image will be smaller.
You'll have to adjust the crop coordinates that are passed. You need to adjust them according to the ratio by which you resized your image for preview. So if you shrank your image preview to 50% of what it was originally, the actual coordinates of the crop will be twice what they come in as or (x*2, y*2).