I'm having a problem with my 'curtainX' cycle animation in jquery. The first animation seems to zoom out in the top center, instead of doing the animation it should. I can't seem to find the problem and now I don't know where to start. I tried checking the different options for the animations and can't seem to figure it out.
<!DOCTYPE html>
<html>
<head>
<style type = "text/css">img{position:absolute;}</style>
<script src = "jquery.js"></script>
<script src = "jquery-ui.js"></script>
<script src = "jquery-cycle.js"></script>
<script src = "text/javascript">
function start(){
$("#blank").cycle({
fx: 'curtainX',
sync: false,
delay: -4000
});
}
</script>
</head>
<body>
<div id = "blank" onclick = "start()">
<img src = "img/blank.gif" style = "z-index:1"/>
<img src = "img/1c.gif"/>
</div>
</body>
</html>
You can view a demo at http://vrbj.webs.com/flipTest.html
It seems to be a problem related to the absence of a width and a height.
I've rewritten the code here
Removing width and height causes your problem.
You can solve changing:
img{position:absolute;}
to
img{position:absolute; width: 59px; height: 74px;}
Consider also the way you have written your code, taking a loo at what i've written.
Your code's right but the way is written is less "plugin's compliant" than in the fiddle.
Functions in the tag are called when they are needed. Try moving your start function within the tag and put that within an $(document).ready( your function ) call
Related
I am trying to pass the canvas HTML element as a parameter, and I thought 'this' would work but I can't quite get it to. Could someone help me use the 'this' keyword to pass the canvas to main() upon page-load, please?
Doesn't work:
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body onload=main(this.firstChild)><canvas></canvas></body>
<script>
function main(canv) {
cntx = canv.getContext("2d");
cntx.rect(10, 10, 100, 100);
cntx.fill();
}
</script>
</html>
Works, but would like to use the 'this' keyword instead:
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body onload=main(document.body.firstChild)><canvas></canvas></body>
<script>
function main(canv) {
cntx = canv.getContext("2d");
cntx.rect(10, 10, 100, 100);
cntx.fill();
}
</script>
</html>
Doesn't work (onload not defined for canvas element):
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body><canvas onload=main(this)></canvas></body>
<script>
function main(canv) {
cntx = canv.getContext("2d");
cntx.rect(10, 10, 100, 100);
cntx.fill();
}
</script>
</html>
Works, and uses 'this', but want the code to run without clicking:
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body><canvas onclick=main(this)></canvas></body>
<script>
function main(canv) {
cntx = canv.getContext("2d");
cntx.rect(10, 10, 100, 100);
cntx.fill();
}
</script>
</html>
I suggest you consider a different approach as you risk complicating the expressiveness of your overall scripting logic if you're mixing it into your HTML tags. More to your point, while you can't use onload in an HTML tag context to get any this beyond the window, you can create JS functions that are defined to execute after window.onload in any fashion you want.
You're already using JavaScript to define your canvas attributes, why not create the canvas in JS at the same time!
You can also see how this could be extended to open up your options on creating/appending more canvasses on the fly.
If this doesn't work for you, let me know if this was an abstracted question for an issue that I might be able to help with more directly.
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body>
<script>
function createCanvasRect(x, y, width, height) {
var canv = document.createElement('canvas'),
cntx = canv.getContext('2d');
cntx.rect(x, y, width, height);
cntx.fill();
return canv;
}
function load() {
var canvas = createCanvasRect(10, 10, 100, 100);
document.body.appendChild(canvas);
}
window.onload = load;
</script>
</body>
</html>
Your problem is with the use of onload.
Typically, a listener attached in-line is called as if wrapped in an outer function with it's this set to the element on which the listener is called. However, that's not the case for onload listeners attached to the body element. Their execution is delayed and they are called with the global / window object set to this.
So you can't use this the way you're trying to do it.
The following demonstrates that a the body's load listener is called with this as the global object, but the div's click listener is called with the div element as this.
<script>
// Reference to global/window object
var global = this;
</script>
<body onload="console.log(this === global)">
<div onclick="console.log(this.tagName)">clickable div</div>
</body>
Try this. I put javascript out from HTML for more cleaner code.
function main() {
console.log(this);
var cntx = this.getContext("2d");
cntx.rect(10, 10, 100, 100);
cntx.fill();
}
window.onload = function() {
main.call(document.getElementById('main'));
}
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body>
<canvas id="main"></canvas>
</body>
</html>
Well so many ways to do things.
Element referencing in Javascript
To access a DOM element you need to id it by giving it a unique id.
<canvas id="myCanvas"></canvas>
Note id Must be unique, if another element has the same id the browser will enter quirks mode (see below)
You can then access it directly using its id as a variable name.
var ctx = myCanvas.getContext("2d");
There are some that prefer to use the slower and more painful.
var ctx = document.getElementById("myCanvas").getContext("2d");
Or others use
var ctx = document.querySelector("#myCanvas").getContext("2d");
Get it in order
All these methods have one problem. When a browser parses a page it adds elements to the DOM one at a time from the top down.
If you add some script above the elements you want to use, the script will not find the elements as they have not yet been created
<canvas id="topCan"></canvas>
<script> // this code is run when the browser finds it
var ctx = topCan.getContext("2d"); // works as the element has been created
var ctx1 = botCan.getContext("2d"); // no work as the element does not yet exist
</script>
<canvas id="botCan"></canvas>
So to make sure you add the script after the elements (and before the closing body tag see quirks mode below)
Sometimes its just plain inconvenient for you to put the script after the content. That is when you would put the code inside a function you call on the load event. The code in the function will not run until all the elements have been added to the page.
How you listen to that event is up to you, see below
Organizing an event
It is considered bad form to assign an event handler directly
myCanvas.onclick = function(){};
and even worse if you do
<canvas onclick = "myFuction(this)"></canvas>
with the road of enlightenment packed with those that say the following way is the way
const canvas = document.querySelector("#myCanvas");
canvas.addEventListener("click",myFunction);
function myFunction(){ /* code */}
All the above methods work, none of them are right or wrong, there are a few other ways as well. What method you use is up to you, I always recommend that you use the method you find easiest to remember and use.
Careful of the quirks
But there are some things you should not do. The reason is that some layouts make the browser think its back in the late 90's early 2000's, and you have not followed the rules (rules that nobody actually knew), to stop it's self looking stupid next to its peers it will switch to quirks mode which is not good and will generally slow everything down.
One of the things that can trigger quirks mode is placing a script tag where it should not be.
So NEVER put a script tag outside the body or head tags
The path to world peace is always put script tags where they belong.
<html>
<head>
<script></script> <!-- browser is your friend -->
</head>
<body>
<script></script> <!-- browser thinks your great -->
<p> some content </p>
<script></script> <!-- and you know everything-->
</body>
</html>
The way to darkness. Putting a script tag anywhere as follows
<script></script> <!-- wrong -->
<html>
<script></script> <!-- wrong -->
<head>
</head>
<script></script> <!-- oh so bad -->
<body>
</body>
<script></script> <!-- oh so bad -->
</html>
<script></script> <!-- just playing with fire -->
One way
How I would do depends on the tide so currently
<html>
<head>
<title>Draw on Canvas</title>
</head>
<body>
<!-- id the canvas with a unique id -->
<canvas id = myCanvas></canvas>
<script> // script after the element you are accessing
const ctx = myCanvas.getContext("2d");
ctx.rect(10, 10, 100, 100);
ctx.fill();
</script> <!-- ensure the script is inside the body tag -->
</body>
</html>
I am trying to convert a div containing some img tags to a png. After some search, it looks like the best way is to use the html2canvas library.
The problem is that it is not working for me and I don't understand why.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="lib/css/bootstrap.min.css">
<script src="lib/js/Blob.js"></script>
<script src="lib/js/canvas-to-blob.min.js"></script>
<script src="lib/js/FileSaver.js"></script>
<script src="lib/js/html2canvas.js"></script>
<script src="lib/js/jquery.min.js"></script>
<script src="lib/js/underscore-min.js"></script>
<title>Tests Only</title>
</head>
<body>
<div id="navigationButtons">
</div>
<div id="sourceScreen" style="width:200px">
<img id="lol" src="tier-icons/base_icons/bronze.png" />
</div>
<div id="targetScreen">
</div>
<script = "text/javascript">
jQuery('#navigationButtons').append('<button type="button" id="makeScreenshot">Screenshot</button>');
jQuery('#makeScreenshot').click(makeScreenshot);
function makeScreenshot(){
html2canvas(jQuery('#sourceScreen'), {
onrendered: function(canvas) {
jQuery('#targetScreen').html(canvas);
}
});
}
</script>
</body>
</html>
Here is a jsFiddle of my code:
https://jsfiddle.net/2vv79ehy/1/
I am trying to get it work with 1 img tag first on this example, the goal is to display the canvas under the real image.
I know there is a problem with cross-domain resources with this library but when I do the test with my real code, the image is hosted on my computer.
Does anyone know how to do it or if there is another way (would be great if it could bypass cross-domain problems too)?
Your JSFiddle works, except for the cross-domain problem. I've played around trying to find a quick hack around it, but the best I could come up with is just drawing onto the canvas that you're given in your onrendered event and I haven't really played with positioning and the z-order would be impossible to implement this way, but maybe this edit to your makeScreenshot function helps you find a solution that works for you:
function makeScreenshot(){
html2canvas(jQuery('#sourceScreen'), {
onrendered: function(canvas) {
var img = jQuery("#cat");
var ctx = canvas.getContext("2d");
var originalPosition = { left: 0, top: 18 };
ctx.drawImage(img[0],originalPosition.left,originalPosition.top);
jQuery('#targetScreen').html(canvas);
}
});
}
Imagine I have following html with many items:
<html><body>
<img src=http://host.com/pic1.jpg>
<img src=http://host.com/pic1.jpg>
<img src=http://host.com/pic1.jpg>
</html></body>
Site owner adds some script to the page without other modifications:
<script>
var some_super_function = ... // what can i put here?
some_super_function('host.com','ghost.com');
</script>
and during loading of this html, host.com is replaced with hgost.com, so images are loaded from another server, as if the urls were:
<html><body>
<img src=http://ghost.com/pic1.jpg>
<img src=http://ghost.com/pic1.jpg>
<img src=http://ghost.com/pic1.jpg>
</html></body>
I guess selecting $('img') and tuning .attr() is not a good idea, because this may work only after page has loaded and I don't want the browser to reference host.com at all.
I guess angularJS is doing something like that, isn't it?
Is this possible?
Thanks.
Tested in firefox:
<body>
<script>
document.write('<!--');
var body = null;
setTimeout(function() {
body = document.body.innerHTML
console.log(body)
}, 0)
</script>
Now you can extract page contents from body variable, do with them whatever you wish and then put into page (with jQuery('body').html(...) for example).
I don't know if it would work if there were comments in the page. There are other ways to stop page from loading. Something like document.write('<script>');. I also tried document.write('<style>'); in firefox, also works.
You can use angular ng-src and {{}} syntax to bind your img domain:
var superFn = function(){ $('img').attr('src','ghost'); }
superFn();
angular.module('myApp',[]).controller('myCtrl',myCtrl);
function myCtrl($scope){
$scope.domain = "a3.mzstatic.com";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<img ng-src="http://{{domain}}/us/r30/Purple69/v4/d5/9e/6d/d59e6dfa-2176-7bc1-20a8-d3a1316c7bb8/icon100x100.png" >
<img ng-src="http://{{domain}}/us/r30/Purple69/v4/d5/9e/6d/d59e6dfa-2176-7bc1-20a8-d3a1316c7bb8/icon100x100.png" >
<img ng-src="http://{{domain}}/us/r30/Purple69/v4/d5/9e/6d/d59e6dfa-2176-7bc1-20a8-d3a1316c7bb8/icon100x100.png" >
</div>
I guess I know what you need. You need to define a base, and manipulate it to serve your needs. Like:
<script type="text/javascript">
document.write("<base href='http://yourimageurl.com/' />");
</script>
You must use this code before body tag.
How can you set your image urls? This way you have to mirror file names in order to make it work. And only relative url's will work.
Can you use CSS to hide the images initially, wait until the document is ready, then change the images and display them in JS?
CSS
img {
display: hide;
}
JS
$(document).ready( function() {
// ... selecting $('img') and tuning .attr() as mentioned in question
// Show the images
$('img').show();
}
I guess angularJS is doing something like that, isn't it?
No, angular use ng-src but for that you need to change the html
Is this possible?
I don't think it's possible to do reliably, from the client side without changing the html. One issue is when the document is loading, the browser will fetch images as soon as browser hits the image src element, even if you can execute a script before that, since document is not loaded script does not have access to the element.
May be you could kick off a window.setInterval function to check for elements and change sources, still it's not going to be a good approach.
In pure Js
you can do :
<!DOCTYPE html>
<html>
<head>
<script>
some_super_function = function(orig, alt)
{
Array.prototype.forEach.call(document.querySelectorAll("img[src*='"+orig+"']"), function(img)
{
var src = img.src;
var host = src.replace(/^(.*\/\/[^\/?#]*).*$/,"$1");
img.src = "http://"+src.replace(host, alt);
});
}
</script>
</head>
<body>
<img id="ol" src="http://www.intertools.net/lib/media/img/selector.png">
<img id="io" src="http://www.intertools.net/lib/media/img/selector.png">
<script>
// callable anywhere
some_super_function("www.intertools.net", "en.intertools.net");
</script>
</body>
</html>
To avoid caching, you can even use (assuming you are using html5)
<html manifest="manifest.appcache">
If I not mistaken is it your requirement.
var some_super_function = function(old_host,new_host)
{
$('img').each( function() {
var newSrc;
newSrc = $(this).attr('src').replace(old_host, new_host);
$(this).attr('src',newSrc);
console.log($(this).attr('src'));
});
}
some_super_function('host.com','ghost.com');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<img src="http://host.com/pic1.jpg" alt="pic1"/><br/>
<img src="http://host.com/pic2.jpg" alt="pic2"/><br/>
<img src="http://host.com/pic3.jpg" alt="pic3"/><br/>
JsFiddle Demo
I am fairly new to web development. I am trying to apply jQuery to my website, such that when the page loads up, the heading is animated. But for some reason I am not able to get it working. Here is the javascript code :
$(window).ready(function() {
$("h1").animate({left:'250px'});
});
Here is the relevant HTML code:
<!DOCTYPE html>
<html>
<head>
<title> Welcome! </title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="jquery_functions.js"></script>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
CSS left only works with absolutely positioned elements. If you add position:absolute to your H1 tag, it will work.
$(window).ready(function() {
$("h1").animate({left:'250px'});
});
h1 { position: absolute; }
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<h1>Hello!</h1>
This is because h1 may have a static position. You may need to set a CSS relative or absolute position to that element like
h1 {position: relative}
and this jQuery code will work
$(document).ready(function () {
$("h1").animate({
left: 250
});
});
See JSFIDDLE
I'm new myself but it appears your animate option is missing an argument.
$('img').animate({left: "-=10px"}, 'fast'); is an example. yours tells it how much to move, but you left off the how.
You can try changing
$("h1").animate({left:'250px'});
to
$("h1").animate({marginLeft:'250px'});
maybe $(doucment).ready()
I think it will be work ))
I am trying to make a page of tiled images which each have a three state roll over effect. I got it to work for the first image but cannot get it to effect the other images. I know it has something to do with me using getElementById but haven't been able to figure out a solution
Current Code:
<!DOCTYPE html>
<html>
<head><link rel="stylesheet" type="text/css"
href="test4.css"/>
<script>
var clicked = false;
function onClick()
{
clicked = true;
document.getElementById("myImage").src="images/in.jpg";
}
function onMouseover() {
if(!clicked)
document.getElementById("myImage").src="images/half.jpg";
}
function onMouseout(obj) {
if(!clicked)
obj.src="images/out.jpg";
}
</script>
</head>
<body>
<img onmouseover="onMouseover()" onmouseout="onMouseout(this)" onclick="onClick()"
id="myImage" src="images/out.jpg" width="167" height="230">
</body>
</html>
PLEASE && THANKS
Your explanation implies that there are many <img/> on your page but your code only shows one. I will assume that your explanation is correct and that are many <img/> for the purposes of this answer.
There can be only one element on the page with a given id. Any more than 1 and the page is invalid and you will see issues like the one you see. Instead of retrieving by id, give all the elements the same class and retrieve with document.getElementsByClassName