Canvas element not showing up - html

I'm very new to programming and am trying to make a project for class using html, canvas, and a css file. The concept is that there should be a title screen that appears in the canvas element that once you click will disappear and reveal a room where there are elements that you can hover your mouse over and get information.
I have the html, canvas, and css up to how I want it but whenever I try to put something in the canvas element it doesn't show up. Like, for the title screen I want to draw a colored box and put some text in it and then have it click away to reveal an image underneath. I used a drawCanvas but it will only show up if I put a gameLoop at the end. But when I try to add text, it disappears. Again, I'm really new to this and I'm sorry for my wall of text but any advice or suggestions would be really helpful. Here's my html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title Page</title>
<link rel="stylesheet" type="text/css" href="css.css"/>
<script src="js/modernizr.js"></script>
<script>
window.addEventListener("load",eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
function canvasSupport() {
return Modernizr.canvas;
}
function canvasApp() {
if (!canvasSupport()) {
return;
}
var theCanvas = document.getElementById("canvasOne");
var context = theCanvas.getContext("2d");
var width=1000;
var height=450;
function drawCanvas(){
context.fillStyle="teal";
context.fillRect(0,0,width,height);
setColor();
drawLines();
}
function gameLoop(){
requestAnimationFrame(gameLoop);
drawCanvas();
}
gameLoop();
}
</script>
</head>
<body>
<audio loop="loop" autoplay="autoplay" controls="controls">
<source src="themesong.mp3" type="audio/mpeg">
Your browser does not support the audio content.
</audio>
<!-- Canvas -->
<div id="canvas-container">
<canvas id="canvasOne" width="1000" height="450">
Your browser does not support canvas.
</canvas>
</div>
<!-- ^ End Canvas -->
</body>
</html>
And here's my CSS:
#canvasOne {
background-color: #cccccc;
border: 10px solid rgba(136, 128, 172, 0.9);
margin-left: 210px;
margin-right: auto;
margin-top: 130px;
#body {
background-image: url("mansion.jpg");
background-repeat: no-repeat;
}
Honestly, if someone could just help me put an image in the canvas and make it so that certain areas where the mouse hovers over a text box would appear, would be awesome. The idea is that it's a game where you "look" around the room with your mouse for clues. And once again, I'm very new to this so sorry if this is formatted weird or my question is too ridiculously long.

I'm not sure what exactly you want but i fixed the problem where the image is not coming up on the canvas.
The problem is that on your CSS you are coloring the background then you are also putting the image on it causing it to overlap.
Here is the CSS code that I have changed:
#canvasOne {
background-image: url("mansion.jpg");
background-repeat: no-repeat;
border: 10px solid rgba(136, 128, 172, 0.9);
margin-left: 210px;
margin-right: auto;
margin-top: 130px;
}
I dont know how to do the hover part but you should look into this

This is your main problem:
window.addEventListener("load",eventWindowLoaded, false);
The reason I say that is because you are calling the evenWindowLoaded function once -- when the page initially loads. Since this is the case, whatever state the drawLines() and other functions are in when the page loads for the first time, that will be draw on the canvas.
Instead you should try to use this:
var timer = setInterval(function() { eventWindowLoaded(); }, 100);
and then clear the canvas and re-draw it.
(this is for the hover effect)
that way, you can do calculate if the mouse's cursor is above a particular space on the canvas and then do whatever functions if it is... this isn't 100% going to work, but its a general idea of what you could do:
var mousePos;
var timer = setInterval(function() { eventWindowLoaded(); }, 100);
function eventWindowLoaded() {
context.clearRect(0,0,width,height);
for (var i=0; i<images.count; ++i) {
var img = images[i];
if (Math.Abs(mousePos.x - img.Pos().x)) <= img.width) {
if (Math.Abs(mousePos.y - img.Pos().y)) <= img.height) {
do_hover_event();
}
}
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function(evt) {
mousePos = getMousePos(canvas, evt);
}
Thats one thing -- here's another:
You are leaving the scope of the variable definition for the canvas/context var's, try this method for the canvas/context -- using 3 diffeerent separate functions and defining the width, height, theCanvas, and context all in the global scope
var width=1000;
var height=450;
var theCanvas = document.getElementById("canvasOne");
var context = theCanvas.getContext("2d");
function canvasApp() {
if (!canvasSupport()) {
return;
}
gameLoop();
}
function drawCanvas(){
context.fillStyle="teal";
context.fillRect(0,0,width,height);
setColor();
drawLines();
}
function gameLoop(){
requestAnimationFrame(gameLoop);
drawCanvas();
}

Related

Random cutouts with HTML5 Canvas

All I'm trying to do is to get random cutouts (different shapes) via HTML Canvas element.
On the page I have a DIV, and above it I have the canvas element. So far I was able to color the element and cut out the first piece (not random), and wipe/clean the canvas again, but when I'm trying to do the exact same thing multiple times, it wouldn't work :/
Here is the half-working example: http://plnkr.co/edit/a5UAutd2jNgHMTtPMsp4
var cutThatOut = function(coords) {
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.globalCompositeOperation = "destination-out";
coords.forEach(function(coord, i){
if (i==0) {
ctx.moveTo(coord.x, coord.y);
} else {
ctx.lineTo(coord.x, coord.y);
}
});
ctx.fill();
}
thanks for your time/help
Several fixes:
Start your new set of path commands with ctx.beginPath. Otherwise your previous sets of drawing commands will be repeated along with the newest set.
Make sure you reset compositing at the end of cutThatOut. Otherwise your next fillRect(0,0,c.width,c.height) will "erase" the whole canvas because it's still using 'destination-out'.
If you want to do a completely new cutout with each call to cutThatOut then refill the canvas with black at the start of cutThatOut
Just a note: Your random coordinates often cause intersecting sides of the polygon and often extend outside the boundaries of the canvas.
Here's example code and a Demo:
var c = document.getElementById("canvas");
var ctx = c.getContext('2d');
var cutThatOut = function(coords) {
ctx.fillStyle = "black";
ctx.fillRect(0,0,c.width, c.height);
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
coords.forEach(function(coord, i){
if (i==0) {
ctx.moveTo(coord.x, coord.y);
} else {
ctx.lineTo(coord.x, coord.y);
}
});
ctx.fill();
ctx.globalCompositeOperation = "source-over";
}
var wipeIt = function() {
ctx.clearRect(0,0,c.width,c.height);
}
var getRand = function(min, max) {return Math.round(Math.random() * (max - min) + min);}
cutThatOut([
{x:c.width/2, y:0},
{x:c.width,y:c.height/2},
{x:c.width/2,y:c.height},
{x:0, y:c.height/2}
]);
$("#btn").on("click", function(){
wipeIt();
cutThatOut([
{x:getRand(1,200), y:getRand(1,200)},
{x:getRand(1,200), y:getRand(1,200)},
{x:getRand(1,200), y:getRand(1,200)},
{x:getRand(1,200), y:getRand(1,200)}
]);
});
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
.adiv {
width: 200px;
height: 200px;
background-color: yellow;
position: relative;
}
#canvas {
width: 200px;
height: 200px;
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="adiv">
<canvas id="canvas"></canvas>
</div>
<p>
<button id="btn">NEXT!</button>
</p>

Anchor tag not clickable only in IE9

Below is the simple html file, contains an anchor, overlay by block element with certain style. After applying the styles, the link become non-clickable only in IE9. Style applied is to make the anchor muted but allow users to click, if needed. Tried different options by using Jquery, didn't worked out. Any hack for this in html/css?
<!DOCTYPE html>
<html>
<head>
<title>Trial</title>
<style>
.overlay {
display: block;
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(255,255,255,.4);
pointer-events: none;
}
</style>
</head>
<body>
<div class="overlay"></div>
ClickMe
</body>
</html>
The CSS property pointer-events is not supported in < IE11 (See: http://caniuse.com/#feat=pointer-events)
As a work-around you could use JavaScript to listen for a click on the overlay and then trigger the click on the link underneath if its under your cursor. Something like:
function simulateClick(el) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
el.dispatchEvent(evt);
};
function isOnTopOf(evt, el) {
return evt.clientX >= el.offsetLeft && evt.clientX <= el.offsetLeft+el.offsetWidth && evt.clientY >= el.offsetTop && evt.clientY <= el.offsetTop+el.offsetHeight;
};
var overlay = document.getElementById("overlay");
var clicker = document.getElementById("clicker");
overlay.addEventListener('click', function(evt) {
if(isOnTopOf(evt, clicker)){
simulateClick(clicker);
}
}, false);
http://jsfiddle.net/nxdm5x3u/
However if your entire reason for doing this is to make the link appear "muted" you could just use CSS to make it semi-transparent and not bother with the overlay:
a.muted {
opacity: 0.5;
filter: alpha(opacity=50);
}

Dart How do I create a modal page?

I have created my first web application and have .html, .dart, and .css files. I want to create a modal page that will a bit smaller than my page and be centered on it. I don't really want any visible borders. The function of this page is to allow the user to display, using clickable elements, 'Help' and 'About' pages and a page that allow the user to see a list of the data files that have been collected.
I've found a couple of examples of modal pages but they are old. One appears to be easy to understand but the Dart editor flags a couple of errors and has a line that I don't understand at the head of the .dart file.
#import('dart:html'); // OK just remove the '#"
#resource('modal.css'); // ???
This example is in a blog DartBlog that does not appear to be active and did not allow me to leave a comment.
I would appreciate an help understanding the example or pointing me to working examples.
This import statement is outdated Dart syntax.
use instead
import 'dart:html';
I never saw the #resource thing and I'm sure this is not available anymore as well.
You can either put a style tag to your HTML file like
<html>
<head>
<style>
.black_overlay{
display: block;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: block;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
</style>
</head>
<body>
</body>
</html>
or put the CSS content in a file like styles.css and import it to your HTML
<html>
<head>
<link rel='stylesheet' href='styles.css'>
</head>
<body>
</body>
</html>
I tried to update the code to current syntax (not tested though) and I added some comments
import 'dart:html';
void main() {
//setup the screen elements...
ButtonElement button = new ButtonElement();
button.text = "click me";
//add an event handler
button.onclick.listen((event) {
ModalDialog dialog = new ModalDialog("This is a <strong>message</strong>
with html formatting");
dialog.show();
});
//add the button to the screen
document.body.append(button);
//add the modal dialog stylesheet
document.head.append(getStylesheet());
}
/**
* Our modal dialog class
*/
class ModalDialog {
final DivElement _content;
final DivElement _blackOverlay;
final ButtonElement _button;
//Constructor
ModalDialog(String message) :
//constructor pre-init
_content = new DivElement(),
_blackOverlay = new DivElement(),
_button = new ButtonElement()
{
//constructor body
_content.id = "modalContent";
_content.classes.add("white_content"); //set the class for CSS
_blackOverlay.id = "modalOverlay";
_blackOverlay.classes.add("black_overlay"); //set the class for CSS
//Our message will go inside this span
SpanElement span = new SpanElement();
span.innerHTML = message;
_content.append(span);
//This is the button that will "clear" the dialog
_button.text = "Ok";
_button.onClick.listen((event) {
hide();
});
_content.append(_button);
}
//remove the modal dialog div's from the dom.
hide() {
//find the element and remove it.
//there is no list.remove(x) statement at present,
// so we have to do it manually. - UPDATE: now there is
_content.remove();
_blackOverlay.remove();
}
//add the modal dialog div's to the dom
show() {
document.body.append(_content);
document.body.append(_blackOverlay);
}
}
/**
* Utility method to get a stylesheet object
*/
getStylesheet() {
LinkElement styleSheet = new LinkElement(); // maybe
styleSheet.rel = "stylesheet";
styleSheet.type="text/css";
styleSheet.href="modal.css"; // UPDATE: you don't need to add your CSS to your HTML as shown above because it's done in this code
return styleSheet;
}

html5 - drag a canvas

I have a huge HTML5 Canvas, and I want it to work like google maps: the user can drag it and see only a small part of it (the screen's size) all the time. it renders only the part you can see on the screen.
how can I do it? do you have an idea?
2 simple steps:
place the canvas inside a div container with overflow:hidden
use any method to make your canvas draggable (I will use jQuery UI)
To follow my method you need to go to the jQuery UI website and download any version of the jQuery UI (you can create a custom version only consisting of the UI Core and Draggable Interaction for this example.)
Unpack the .zip file and move the 'js' folder to your page directory.
Inlcude the .js files contained in the folder into your page.
Place the following code between your <head></head>-tags to get your canvas draggable:
<script type="text/javacript">
$(function() {
$("#CanvasID").draggable();
});
</script>
Here's an example:
<!DOCTYPE>
<html>
<head>
<title>canvas test</title>
<script type="text/javascript" src="js/jquery-1.5.1.min.js"></script> <!-- include the jQuery framework -->
<script type="text/javascript" src="js/jquery-ui-1.8.11.custom.min.js"></script> <!-- include JQuery UI -->
<style type="text/css">
#box{
width: 400px;
height: 400px;
border:5px solid black;
overflow:hidden;
position:relative;
} /* Just some basic styling for demonstration purpose */
</style>
<script type="text/javascript">
window.onload = function() {
var drawingCanvas = document.getElementById('myDrawing');
// Check the element is in the DOM and the browser supports canvas
if(drawingCanvas.getContext) {
// Initaliase a 2-dimensional drawing context
var context = drawingCanvas.getContext('2d');
context.strokeStyle = "#000000";
context.fillStyle = "#FFFF00";
context.beginPath();
context.arc(200,200,200,0,Math.PI*2,true);
context.closePath();
context.stroke();
context.fill();
}
// just a simple canvas
$(function() {
$( "#myDrawing" ).draggable();
});
// make the canvas draggable
}
</script>
</head>
<body>
<div id="box">
<canvas id="myDrawing" width="800" height="800">
<p>Your browser doesn't support canvas.</p>
</canvas>
</div>
</body>
</html>
Hope this get's you going.
note: This is just a basic example. This will still need some editing. For example the user can drag the canvas totally out of the viewport (perhaps constraining the Canvas to the div may do the trick?). But this should be a good starting point.
I would use two canvases. Keep your huge source canvas hidden and copy portions of it to a second smaller visible canvas. Here's my quickly hacked-up proof of concept:
<!DOCTYPE HTML>
<html>
<head>
<title>canvas scroll</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
overflow: hidden;
}
#source {
display: none;
}
#coords{
position: absolute;
top: 10px;
left: 10px;
z-index: 2;
}
#coords p{
background: #fff;
}
</style>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
var $window;
var img;
var $source; var source; var sourceContext;
var $target; var target; var targetContext;
var scroll = {
x : 0,
y : 0
};
var scrollMax;
function init() {
// Get DOM elements
$window = $(window);
$source = $('canvas#source');
source = $source[0];
sourceContext = source.getContext("2d");
$target = $('canvas#target');
target = $target[0];
targetContext = target.getContext("2d");
// Draw something in source canvas
sourceContext.rect(0, 0, source.width, source.height);
var grd = sourceContext.createLinearGradient(0, 0, source.width, source.height);
grd.addColorStop(0, '#800080');
grd.addColorStop(0.125, '#4B0082');
grd.addColorStop(0.25, '#0000FF');
grd.addColorStop(0.325, '#008000');
grd.addColorStop(0.5, '#FFFF00');
grd.addColorStop(0.625, '#FFA500');
grd.addColorStop(0.75, '#FF0000');
grd.addColorStop(0.825, '#800080');
sourceContext.fillStyle = grd;
sourceContext.fill();
/*
* Setup drag listening for target canvas to scroll over source canvas
*/
function onDragging(event){
var delta = {
left : (event.clientX - event.data.lastCoord.left),
top : (event.clientY - event.data.lastCoord.top)
};
var dx = scroll.x - delta.left;
if (dx < 0) {
scroll.x = 0;
} else if (dx > scrollMax.x) {
scroll.x = scrollMax.x;
} else {
scroll.x = dx;
}
var dy = scroll.y - delta.top;
if (dy < 0) {
scroll.y = 0;
} else if (dy > scrollMax.y) {
scroll.y = scrollMax.y;
} else {
scroll.y = dy;
}
event.data.lastCoord = {
left : event.clientX,
top : event.clientY
}
draw();
}
function onDragEnd(){
$(document).unbind("mousemove", onDragging);
$(document).unbind("mouseup", onDragEnd);
}
function onDragStart(event){
event.data = {
lastCoord:{
left : event.clientX,
top : event.clientY
}
};
$(document).bind("mouseup", event.data, onDragEnd);
$(document).bind("mousemove", event.data, onDragging);
}
$target.bind('mousedown', onDragStart);
/*
* Draw initial view of source canvas onto target canvas
*/
$window.resize(draw);
$window.trigger("resize");
}
function draw() {
target.width = $window.width();
target.height = $window.height();
if(!scrollMax){
scrollMax = {
x: source.width - target.width,
y: source.height - target.height
}
}
targetContext.drawImage(source, scroll.x, scroll.y, target.width, target.height, 0, 0, target.width, target.height);
$('#x').html(scroll.x);
$('#y').html(scroll.y);
}
$(document).ready(init);
</script>
</head>
<body>
<div id="coords">
<p>Drag the gradient with the mouse</p>
<p>x: <span id="x"></span></p>
<p>y: <span id="y"></span></p>
</div>
<canvas id="source" width="4000" height="4000"></canvas>
<canvas id="target"></canvas>
</body>
</html>

dragging and dropping images into a Web page and automatically resizing them with HTML File API

I want to create Web pages that allow users to drag and drop images into boxes in various parts of the page, so that they can then print the pages with their images.
I want the image to automatically resize when it's dropped in the box. I combined some of the code at http://html5demos.com/file-api with some of the code at http://html5demos.com/file-api-simple to get something like I want.
In the current version of the code (below), the image width does not resize the first time you drop the image into the box, but it does the second time.
Any suggestions how I can get the image width to resize automatically the first time you drop the image into the box?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8 />
<meta name="viewport" content="width=620" />
<title>HTML5 Test</title>
</head>
<body>
<header>
<h1>HTML5 Test 1</h1>
</header>
<style>
#holder { border: 10px dashed #ccc; width: 300px; height: 300px; margin: 20px auto;}
#holder.hover { border: 10px dashed #333; }
</style>
<article>
<div id="holder"></div>
<p id="status">File API & FileReader API not supported</p>
<p>Drag an image from your desktop on to the drop zone above to see the browser read the contents of the file - without uploading the file to any servers.</p>
</article>
<script>
var holder = document.getElementById('holder'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.stopPropagation();
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.src = event.target.result;
// note: no onload required since we've got the dataurl...I think! :)
if (img.width > 300) { // holder width
img.width = 300;
}
holder.innerHTML = '';
holder.appendChild(img);
};
reader.readAsDataURL(file);
return false;
};
</script>
</body>
</html>
I found a simple answer that I think works really well for my needs, based on a bit of CSS in http://demos.hacks.mozilla.org/openweb/DnD/dropbox.css used for http://demos.hacks.mozilla.org/openweb/DnD/.
In the code I included in my question above, I added this to the CSS code:
#holder > * {
display: block;
margin: auto;
max-width: 300px;
max-height: 300px;
}
and I deleted this:
if (img.width > 300) { // holder width
img.width = 300;
}