About
A basic JavaScript syntax structure highlighter to be utilized when offer code in a html page. Exceptionally simple to add new standards or to change the saved words or techniques.
How to use it
Add the record syntax.min.js
to the furthest limit of your code and it will naturally feature each <code>
label that you have in your page. Or then again utilize the concede attribute:
let canvas, c, w, h, scale, game, tileSize, moves, status
const init = () => {
moves = 0
tileSize = 96
createGame(3)
canvas = document.createElement('canvas')
updateCanvas()
const options = document.createElement('div')
const scrambleBtn = document.createElement('button')
scrambleBtn.innerText = "Scramble"
scrambleBtn.addEventListener('click', () => scramble(Math.floor(Math.random()*100)))
const cubeSize = document.createElement('select')
for(let i = 3; i < 6; i++){
const opt = document.createElement('option')
opt.value = i
opt.innerText = i
cubeSize.appendChild(opt)
}
cubeSize.addEventListener('change', function(){
const value = parseInt(this.value)
tileSize = 96 - (value-3) * 16
createGame(value)
updateCanvas()
scramble(100)
})
status = document.createElement('div')
status.id = 'status'
options.appendChild(cubeSize)
options.appendChild(scrambleBtn)
document.body.appendChild(status)
document.body.appendChild(canvas)
document.body.appendChild(options)
scramble(1000)
}
const updateCanvas = () => {
scale = window.devicePixelRatio
w = game[0].length * tileSize
h = game.length * tileSize
canvas.width = w * scale
canvas.height = h * scale
canvas.style.width = `${w}px`
canvas.style.height = `${h}px`
c = canvas.getContext('2d')
c.scale(scale, scale)
c.textAlign = "center"
c.textBaseline = "middle"
const fontSize = 24
c.font = `${fontSize}px Arial`
canvas.addEventListener('click', move)
}
const createGame = num => {
game = Array(num).fill().map(_ => Array(num).fill(0))
for(let i = 0; i < num; i++){
for(let j = 0; j < num; j++){
game[i][j] = (i * num + j + 1) % (num*num)
}
}
}
const getPos = e => {return {x: Math.floor(e.offsetX / tileSize), y: Math.floor(e.offsetY / tileSize)}}
const draw = () => {
c.clearRect(0,0,w,h)
c.strokeStyle = "black"
for(let i = 0; i < game.length; i++){
for(let j = 0; j < game[0].length; j++){
const piece = game[i][j]
if(!piece)
continue
const x = j * tileSize
const y = i * tileSize
c.fillStyle = "white"
c.fillRect(x, y, tileSize, tileSize)
c.strokeRect(x, y, tileSize, tileSize)
c.fillStyle = "black"
c.fillText(piece, x+tileSize/2, y+tileSize/2)
}
}
}
const findEmptyPos = () => {
for(let i = 0; i < game.length; i++){
for(let j = 0; j < game[0].length; j++){
if(!game[i][j]){
return {x: j, y: i}
}
}
}
}
const checkInvalid = (x, y, i, j) =>
(y+i < 0 || y+i > game.length-1 || x+j < 0 || x+j > game[0].length-1 || i+j === 0 || i === j)
const getNeighbour = pos => {
let n = []
for(let i = -1; i < 2; i++){
for(let j = -1; j < 2; j++){
if(checkInvalid(pos.x, pos.y, i, j))
continue
if(game[pos.y+i][pos.x+j])
n.push({x: pos.x+j, y: pos.y+i})
}
}
return n
}
const scramble = (num = 1) => {
moves = 0
for(let i = 0; i < num; i++){
const emptyPos = findEmptyPos()
const n = getNeighbour(emptyPos)
const move = n[Math.floor(Math.random() * n.length)]
tradePos(move, emptyPos)
}
draw()
if(!checkGameWin()){
status.innerText = ''
}
}
const lookEmptyPos = pos => {
for(let i = -1; i < 2; i++){
for(let j = -1; j < 2; j++){
if(checkInvalid(pos.x, pos.y, i, j))
continue
if(!game[pos.y+i][pos.x+j])
return {x: pos.x+j, y: pos.y+i}
}
}
return null
}
const tradePos = (pos, newPos) => {
if(!newPos)
return
game[newPos.y][newPos.x] = game[pos.y][pos.x]
game[pos.y][pos.x] = 0
}
const checkGameWin = () => {
for(let i = 0; i < game.length * game[0].length - 1; i++){
const x = i % game[0].length
const y = Math.floor( i / game[0].length )
if(game[y][x] != i+1)
return false
}
return true
}
const move = e => {
const pos = getPos(e)
const newPos = lookEmptyPos(pos)
tradePos(pos, newPos)
status.innerText = checkGameWin() ? `Win - ${moves} moves` : ''
draw()
moves += 1
}
init()
The script will create <spam>
tag for every reserved word, variable, methods and numbers so you can target them with CSS.
code {
font-family: Consolas,"courier new";
color: #EEE;
background-color: #333;
padding: 2px;
font-size: 105%;
display: block;
white-space: pre;
counter-reset: line;
}
code > div {
counter-increment: line;
display: block;
min-height: 1em;
}
code > div::before {
content: counter(line) 'A0';
display: inline-block;
width: 4ch;
text-align: left;
-webkit-select: none;
color: #666;
}
.reserved {
font-weight: bold;
color: #55C;
}
.methods {
font-weight: bold;
color: green;
}
.variable {
color: orange;
}
.comment {
color: gray;
}
.number {
color: red;
}
Fell free to share anything you like to more readily suit your requirements.