Creating a grid to draw on - javascript

I would like to create a grid on my website where you can somehow draw on.
There are however a few problems:
I want it to be compatible with IE7/8 (hence no HTML5/canvas).
I would also like to be able to store the image drawn in the end.
The grid has to be able to have several sizes (from 10x10 up to 1000x1000 preferably even more). Probably with a zoom in/out function.
I also want to support all RGB colors
In addition to this the whole grid should be drawn on a fixed size (i.e. 800x600)
NO FLASH
I however have no idea how to do so, hence I would like to ask if anyone knows a way of doing so.
I have been looking at jquery myself, although I have no idea how I could implement it this way since I never used it before.
edit: added a few more requirements

if you are only wanting to save the image drawn and not the grid lines, why not use an image?
Have several images in the sizes you want. that way you arnt putting extra processing on the browser.
you can just use an image in the smalles grid size and tile/repeat it on the background. Should be a fairly small image and a fast load

If I understand correctly; you want a grid with cells, the user can select a color en drag/move over the cells to draw something. Then when the user is happy, then they must be able to save the picture to continue on it later..
I will describe what I would do if it was my project (jQuery and CSS).
I would start with a list:
<ul id="grid"></ul>
Then I would create the grid with li for the rows and div's for the cells. You can set the size and color of the cells with CSS and jQuery.
Here is a simple example of the generate grid and the event for the cell.
function createGrid() {
$('#grid').html('');
for(var row = 0; row < total_rows; row++) {
$('#grid').append('<li id="row_' + row + '"></li>');
var current_row = $('#row_' + row);
for(cell = 0; cell < total_cells; cell++) {
$(current_row).append('<div id="cell_' + cell + '" class="cell"></div>');
//set events
$('#cell_' + cell).mouseenter(paint_cell);
}
}
}
function paint_cell(event) {
//mouse down?
if(event.which==1) {
//give it a color
$(this).addClass('red');
}
}
Simple CSS:
.cell {
float: left;
width: 20px;
height: 20px;
background: white;
}
.cell .red {
background: red; //all the rgb you want ;)
}
You'll need a javascript function that loops trough all the rows and cells and saves the information in a xml file or something to be able to save the drawing. And you'll need one to read the xml and generate the grid based on the information.
For bullit 5; you can wrap the grid in a div and set the width and height to 800x600 and the CSS to overflow: scroll.
Hope this helps you in the right direction.

You can draw whatever you want with colored spans
Here is a quick demo that can be a start to develop further.

Related

Isn't there anyway to print any ag-grid size compeletely fit into A4 paper?

I have a big ag-grid looks like below
Somehow I should get PDF export of this and being able to print (both A4 paper size).I've reviewed AG-Grid documentation to find something useful here what I came up with below
onBtPrinterFriendly() {
var eGridDiv = document.querySelector('#myGrid');
eGridDiv.style.width = '';
eGridDiv.style.height = '';
this.gridApi.setDomLayout('print');
print();
}
onBtNormal() {
var eGridDiv = document.querySelector('#myGrid');
eGridDiv.style.width = '400px';
eGridDiv.style.height = '200px';
this.gridApi.setDomLayout(null);
}
These two methods can change grid size to print on desired format.But I can't make my grid smaller diagonally to fit paper size.It justs crops the right side of my grid so looks like this
Doesn't matter how small that would be ,just I wanna put it compeletely A4 paper(vertically).Isn't there anyway to achieve this?I'm also thinking about making a simple HTML table versiton without margins and paddings to fit into paper but that would be too much work so looking for better and easier way if exists.
Plunker example: https://plnkr.co/edit/rVPswsaknukOkhf5
Use the sizeColumnsToFit function on the grid API to fit all the columns within the grid, then print.
onBtPrinterFriendly() {
var eGridDiv = document.querySelector('#myGrid');
eGridDiv.style.width = '';
eGridDiv.style.height = '';
this.gridApi.sizeColumnsToFit();
this.gridApi.setDomLayout('print');
print();
}
Demo.
agGrid rows have a high line-height value in their css so they don't actually go back to line automatically. which would result in a lot of ellipses and a harder table to read and print in your case.
In the time of printing (If you don't need it somewhere else) you can add class to all cells via the defaultColDef that would force the cells to take at least 2 lines of data. this way you can make the columns less wide.
defaultColDef: {
....
cellClass: 'cell-wrap-text',
....
}
.cell-wrap-text{
white-space: normal !important;
line-height: 23px !important;
}
using that and with the sizeColumnsToFit() and setDomLayout('print') methods would give you a better result.
Also if you are not using infinite mode on agGrid you can easily set the row height to something fixed or do that programmatically via the API (based on the text content inside the cells for that row).

Set draggable bars to custom start position with javascript in Qualtrics

In Qualtrics, it is possible to set the starting position of draggable bars (i.e., their width) with a "Custom Start Position". This is done by dragging the bars to the desired width while editing the survey. However, I am looking for a way to set the width of the bars to a start position with JavaScript (or Prototype JavaScript).
Here are my attempts, first (successfully) trying to change the color of the bars (in qualtrics and on jsfiddle), then (successfully) trying to adapt these attempts to change the bar widths on jsfiddle; and then getting stuck because what works on jsfiddle does not work on Qualtrics.
In Qualtrics, I can change the color of draggable sliders with the following Prototype JavaScript (adapted from this answer):
Qualtrics.SurveyEngine.addOnload(function()
{
//change the color of all bars to red for testing
$(this.questionId).select('.bar').each(function(name, index) {
name.style.backgroundColor = "red";
});
});
The result can be seen (and inspected) here. Inspecting the survey in the link indeed shows that the background-color was set to red:
<div id="QID2~2~bar" class="bar" style="width: 103px; background-color: red;"></div>. A width argument is also present, meaning I should be able to modify the width with the following code (which indeed does work on jsfiddle when setting the library to prototype):
$("test").select('.bar').each(function(name, index) {
name.setStyle({ width: '40px'});
});
However, this code does not work on Qualtrics (when replacing $("test") with $(this.questionId) and including the code in Qualtrics addOnload function).
The following javascript also works on Qualtrics for changing bar colors (adapted from this answer):
Qualtrics.SurveyEngine.addOnload(function()
{
//change the color of all bars to red for testing
var bar = document.querySelectorAll('.bar');
for (var i=0; i < bar.length; i++) {
bar[i].setAttribute("style", "background-color:red");
}
});
With this code, I can also adjust the div width on jsfiddle:
var bar = document.querySelectorAll('.bar');
for (var i=0; i < bar.length; i++) {
bar[i].setAttribute("style", "width:40px");
}
However, again this has no effect in Qualtrics.
So, long story short: Is there a way to programmatically give the bars in Qualtrics a start position, e.g., by setting their width to 50% of the parent div?
Update:
After digging deeper into the Qualtrics Question API, I found setChoiceValue with which I can programmatically select multiple choice items. E.g.,
Qualtrics.SurveyEngine.addOnload(function()
{
this.setChoiceValue(2,true);
});
will select the 2nd radio-button by setting its value to true:
However, so far I was unable to either apply setChoiceValue to draggable bars or find a similar equivalent.
Update 2:
Qualtrics Support (who are very friendly and approachable) has suggested that setChoiceAnswerValue might be what I am looking for. However they also explained that they cannot provide customer support for JavaScript. I took a look at a more recent version of the API documentation which also lists setChoiceAnswerValue, but so far without success.
I must have made a typo in my original code, as it turns out that what I had started with actually works:
Qualtrics.SurveyEngine.addOnload(function()
{
$(this.questionId).select('.bar').each(function(name, index) {
name.setStyle({ width: '50px'});
});
});
Here is a solution for setting the custom start positions for draggable bars using the setChoiceValue method as documented in the Qualtrics Question API.
Below is an example code for a question with 10 bars using embedded data from previous questions.
var embedded = ["${e://Field/r1}", "${e://Field/r2}",
"${e://Field/r3}", "${e://Field/r4}", "${e://Field/r5}",
"${e://Field/r6}", "${e://Field/r7}", "${e://Field/r8}",
"${e://Field/r9}", "${e://Field/r10}"];
for (var i = 0; i < 11; i++) {
var index = i + 1;
var choiceInput = embedded[i];
this.setChoiceValue(index, choiceInput);
}
For setting the custom value of one bar:
Qualtrics.SurveyEngine.addOnload(function()
{
this.setChoiceValue(2, "80");
});

use JavaScript to toggle between different "crops" of a single large image

So I have been reading up on dozens upon dozens of Javascript zoom components, but none of them do what I am looking for, so I'm curious where to find such a component (if one exists) or how to code it myself.
The goal is to download a single large (1000x1000) image to the browser. Then within the browser, the image would have three presentation states within the same element container that the user can toggle between by clicking on some page element.
State 1 (default): See the entire image, but scaled down to fit within a 500x500 container (i.e. shrunk, but not cropped). For example (not to scale, but for comparison with other states):
State 2: See the middle 50%, centered, in the same container (i.e. actual size, and cropped). For example:
State 3: See the middle 25%, centered, in the same container (i.e. enlarged, and cropped quite a bit). For example:
And I would put the script that toggles between these three states in the click of some page element, such as a button.
Can any one offer a link to a component that does this, or suggestions on how the method that might accomplish it?
Thanks for any help!
I will go down on leveraging some CSS here.
For first case:
1) create a DIV which is 500x500, and set the background image to the file. Make sure you set background-size:contain property as well on the div.
2) For the second case I will remove the background-size:contain
3) The third case I will set the `background-size:200%;'
JSFiddle
If what you've described is really all you want to do it can be easily achieved with some CSS and a few lines of javascript:
var container = document.querySelector('.image-zoom'),
zoomBtn = document.getElementById('zoom-it'),
i = 0;
function clickHandler() {
if (i === 0) {
container.classList.add('zoom-2x');
i++;
} else if (i === 1) {
container.classList.add('zoom-4x');
i++;
} else {
container.classList.remove('zoom-2x');
container.classList.remove('zoom-4x');
i = 0;
}
}
zoomBtn.addEventListener('click', clickHandler);
.image-container, .image-zoom {
width: 250px;
height: 250px;
}
.image-container {
overflow: hidden;
}
.image-zoom.zoom-2x {
transform: scale(2);
}
.image-zoom.zoom-4x {
transform: scale(4);
}
<div class="image-container">
<div class="image-zoom" style="background-image:url(http://lorempixel.com/250/250)">
</div>
</div>
<button id="zoom-it">zoom image</button>
This assumes you know the dimensions of the image, which if you're using a CMS you can likely easily get and insert them inline on the .image-zoom and .image-containerelements.
jsFiddle
EDIT
jsFiddle 2
Modified the jsfiddle to be closer to what your question asked (initial state of the image is contained within the square and not cropped any amount.)

Scale images in each row to fill it 100% with JavaScript or CSS

I'm trying to build a simple responsive gallery.
Code pen here
There only a simple CSS setting for images now:
img {
height: 150px;
float: left;
margin: 2px;
}
I want my gallery rows to be 100% in width and scale the image heights in each row accordingly keeping the aspect ratio.
The scenario is something like this:
On window load and resize:
1. Wrap each row into #div
2. Calculate image height for each row (overriding the initial fixed value)
Desired result
I was trying to find a pure CSS way, but looks like I can not get away without some JavaScript here.
EDIT: I was able to make this with some jQUery "mad skills":
codepen.io/ztm/pen/NGwaEL
$(document).ready(cascade);
$(window).on('resize',cascade);
function cascade() {
$('img').css({ 'height': 150 + "px" });
var wdth = $(".box").width();
var img_width = 0;
$('img').each(function() {
img_width += $(this).outerWidth( true );
if(img_width < wdth){
$(this).addClass('active');
$('.result').html('Ratio: '+wdth/img_width);
}
});
var ratio = (wdth-24)/img_width;
$('img').css({ 'height': 150*ratio + "px" });
}
It calculates a single row of image with initial height.
And so far the best solution to my problem I found was this:
miromannino.com/projects/justified-gallery/comment-page-4/
Based on your 'Desired result' link, it looks to me like you are wanting a Google+/Google Photos style gallery layout. In this style of gallery, images are added to a row until they fit the width of the row and then a new row is started.
The reason you can't get away with just css is that some trickery is needed to get images of various sizes to fit perfectly into the width of each row. The simplest solution to this is to add images until they exceed the width of the row, then crop all those images down to fit the row perfectly, that method is outlined in detail with jQuery and CSS here: Google+ Style Image Gallery
There are other methods you can use, like adding images until it is a certain percentage under the width of the row then scaling up the size of the images on that row so they fit perfectly, but the idea remains the same: add images until they are within a range of their parent container, then grow or shrink the images to make them the exact width.
Not sure if you are looking for this solution. Works fine in Chrome.
[1]: http://codepen.io/sridharspeaks/pen/meBwNN
You may look at the Isotope or Masonry plugins that could help you with this.

change css on scroll event w/ requestAnimation Frame

I want to change the background color of in-viewport elements (using overflow: scroll)
So here was my first attempt:
http://jsfiddle.net/2YeZG/
As you see, there is a brief flicker of the previous color before the new color is painted. Others have had similar problems.
Following the HTML5 rocks instructions, I tried to introduce requestAnimationFrame to fix this problem to no avail:
http://jsfiddle.net/RETbF/
What am I doing wrong here?
Here is a simpler example showing the same problem: http://jsfiddle.net/HJ9ng/
Filed bug with Chromium here: http://code.google.com/p/chromium/issues/detail?id=151880
if it is only the background color, well why don't you just change the parent background color to red and once it scroll just change it to pink?
I change your CSS to that
#dad
{
overflow-y: scroll;
overflow-x: hidden;
width: 100px;
height: 600px;
background-color:red;
}​
I remove some of you Jquery and change it to this
dad.bind('scroll', function() {
dad.css('background-color', 'pink');
});
And I remove this line
iChild.css('backgroundColor', 'red');
But is the Red color it is important that won't work for sure http://jsfiddle.net/2YeZG/5/
I like Manuel's Solution.
But even though I don't get what you're exactly trying to do, I want to point out a few things.
In your fiddle code, I saw that you included Paul Irish's Shim for requestAnimationFrame.
But you never use it.
(It's basically a reliable setTimeOut, nothing else) it's from frame based animations.)
So since you just want to change some CSS properties, I don't see why you would need it. Even if you want transitions, you should rely on CSS transitions.
Other than that your code could look something like
dad.bind('scroll', function() {
dad.css('background-color', 'pink');
eachElemNameHere.css('background-color','randomColor');
});
Also you should ideally not use something like that if you can help it. You should just add and remove class names and add all these properties in your CSS. Makes it work faster.
Also, again I don't quite get it, but you could use the jQuery function to find out each elements' position from the top to have better control.
Your problem seems to be that you only change the background color of the elements which have already been scrolled into view. Your code expects that the browser waits for your code to handle the scroll event before the browser redraws its view. This is most probably not a guarantee given by the HTML spec. That's why it flickers.
What you should do instead is to change the elements which are going to be scrolled into view. This is related to off screen rendering or double buffering as it is called in computer games programming. You build your scene off screen and copy the finished scene to the visible frame buffer.
I modified your first JSFiddle to include a multiplier for the height of the scroll area: http://jsfiddle.net/2YeZG/13/.
dad.bind('scroll', function() {
// new: query multiplier from input field (for demonstration only) and print message
var multiplier = +($("#multiplier")[0].value);
$("#message")[0].innerHTML=(multiplier*100)-100 + "% of screen rendering";
// your original code
var newScrollY = newScrollY = dad.scrollTop();
var isForward = newScrollY > oldScrollY;
var minVal = bSearch(bots, newScrollY, true);
// new: expand covered height by the given multiplier
// multiplier = 1 is similar to your code
// multiplier = 2 would be complete off screen rendering
var newScrollYHt = newScrollY + multiplier * dadHeight;
// your original code (continued)
var maxVal;
for (maxVal = minVal; maxVal < botsLen; maxVal++) {
var nxtTopSide = tops[maxVal];
if (nxtTopSide >= newScrollYHt) {
break;
}
}
maxVal = Math.min(maxVal, botsLen);
$(dadKids.slice(minVal, maxVal)).css('background', 'pink');
});
Your code had a multiplier of 1, meaning that you update the elements which are currently visible (100% of scroll area height). If you set the multiplier to 2, you get complete off screen updates for all your elements. The browser updates enough elements to the new background color so that even a 100% scroll would show updated elements. Since the browser seldom scrolls 100% of the area in one step (depends of the operating system and the scroll method!), it may be sufficient to reduce the multiplier to e.g. 1.5 (meaning 50% off screen rendering). On my machine (Google Chrome, Mac OS X with touch pad) I cannot produce any flicker if the multiplier is 1.7 or above.
BTW: If you do something more complicated than just changing the background color, you should not do it again and again. Instead you should check whether the element has already been updated and perform the change only afterwards.

Categories