Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Grid and Snap

I would like to display the Map Grid without having the snap-to feature.  I see a five year old thread on this but I would like to know if there is a work around?  Besides, holding the Alt key while moving the image.
1576286009
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Other than uploading a gridded map image, I do not think so. Hmmm, it should be possible to upload a transparent grid image that could be sized and overlaid on any map image.
1576293884
The Aaron
Roll20 Production Team
API Scripter
You can do this with an API script.  Use the command !grid to make a grid on the map layer out of drawn lines.  By default, it will copy your page's existing grid information (leave the grid on for this if you have changed Cell Width): !grid --make You can specify the size of the grid (in pixels, 70 pixels == the default grid size): !grid --make --size 140 You can specify the width of the lines (default 1): !grid --make --width 3 You can specify the color: !grid --make --color #ff0000 You can provide the color with or without the #, in 3 number, 6 number, and 8 number format: !grid --make --color f00 !grid --make --color #f00 !grid --make --color ff0000 !grid --make --color #ff0000 !grid --make --color ff000099 !grid --make --color #ff000099 The last 2 digits are the transparency (00 == fully transparent, you can't see it, ff = fully opaque, you can't see through it).  Upper or lower case is fine (#FF0000 == #ff0000). And you can specify all parameters together: !grid --make --color #ff000099 --size 140 --width 3 (Order doesn't matter). If you throw more things on the map and the grid is now hidden, you can pull it to the front with: !grid --front Finally, you can delete the grid on the current page with: !grid --clear Since this is just creating drawings, you can create multiple grids if you want, which might be nice for major and minor grids: Note: if you resize the page, you'll need to clear the grid and recreate it. Source code: on('ready', () => { const API_MARK = "MakeGrid:GridLine"; const TO_FRONT_TIME = 500; const GRID_MIN = 10; const GRID_MAX = 1000; const getPageForPlayer = (playerid) => { let player = getObj('player',playerid); if(playerIsGM(playerid)){ return player.get('lastpage'); } let psp = Campaign().get('playerspecificpages'); if(psp[playerid]){ return psp[playerid]; } return Campaign().get('playerpageid'); }; const getGridsOnPage = (pageid) => findObjs({ type: "path", pageid: pageid, layer: "map" }).filter(o=>o.get('controlledby').split(/\s*,\s*/).includes(API_MARK)); const toFrontArrayAsync = (objs) => { let items = [...objs]; const burndown = () => { if( items.length) { let i = items.shift(); toFront(i); setTimeout(burndown, TO_FRONT_TIME); } }; burndown(); }; const parseColor = (color) => { let match = color.match(/^#?([a-fA-F0-9]{3}(?:[a-fA-F0-9]{3}(?:[a-fA-F0-9]{2})?)?)$/); if(match){ let c = match[1]; switch(c.length){ case 3:{ let cs = c.split(''); c=`${cs[0]}${cs[0]}${cs[1]}${cs[1]}${cs[2]}${cs[2]}`; } /* break; // intentional dropthrough */ /* falls through */ case 6: c = `${c}99`; /* break; // intentional dropthrough */ /* falls through */ case 8: return `#${c}`; } } }; const asAlpha = (percent) => Math.min(256,Math.max(0,Math.round(256*percent))).toString(16); const makeGrid = (page,params,GridOffset) => { let height = page.get('height')*70; let width = page.get('width')*70; let rows = Math.floor(height/GridOffset); let cols = Math.floor(width/GridOffset); let path = []; for(let i = 1; i<rows; ++i){ path.push(['M',0,(i*GridOffset)]); path.push(['L',width,(i*GridOffset)]); } for(let i = 1; i<cols; ++i){ path.push(['M',(i*GridOffset),0]); path.push(['L',(i*GridOffset),height]); } let grid = createObj('path',{ pageid: page.id, path: JSON.stringify(path), fill: "transparent", stroke: params.stroke, rotation: 0, layer: 'map', stroke_width: params.stroke_width, width: width, height: height, top: (height/2), left: (width/2), scaleX: 1, scaleY: 1, controlledby: params.controlledby }); toFront(grid); }; on('chat:message', (msg) => { if('api'===msg.type && /^!grid/i.test(msg.content) && playerIsGM(msg.playerid)){ // !grid --clear // !grid --make --size 70 --width 5 --color #ff000099 // !grid --front let pageID = getPageForPlayer(msg.playerid); let page = getObj('page',pageID); let isMake = false; let params = { stroke: `${page.get('gridcolor')}${asAlpha(page.get('grid_opacity'))}`, stroke_width: 1, controlledby: API_MARK }; let GridOffset = (parseInt(page.get('snapping_increment'))*70)||70; let args = msg.content.split(/\s+--/); args.slice(1).forEach( a => { let cmd = a.split(/\s+/); switch(cmd[0].toLowerCase()){ case 'clear': getGridsOnPage(pageID).forEach(p=>p.remove()); break; case 'front': toFrontArrayAsync(getGridsOnPage(pageID)); break; case 'make': isMake = true; break; case 'width': params.stroke_width = parseInt(cmd[1]) || params.stroke_width; break; case 'color': params.stroke = parseColor(cmd[1]) || params.stroke; break; case 'size': GridOffset = parseInt(cmd[1]) || GridOffset; break; } }); if(isMake){ GridOffset = Math.min(Math.max(GridOffset,GRID_MIN),GRID_MAX); makeGrid(page,params,GridOffset); } } }); });
Cool!  Thanks.  I'll give this script a try.
1576372248
The Aaron
Roll20 Production Team
API Scripter
No worries! =D