I have completed 2048 clone and its can be played on pc's and laptops but not on phones. I want to make it playble on both the devices is it possible to add touch event handler with keystrokes handler to the same version Or I have to make a complete different version for phone? if it can be done in the same version please tell how it can be done.
Thanks.
//Export Grid js
const GRID_SIZE = 4
const CELL_SIZE = 20
const CELL_GAP = 2
class Grid {
//making cells private is so that it can be only accesible in grid class
#cells
constructor(gridElement) {
gridElement.style.setProperty("--grid-size", GRID_SIZE)
gridElement.style.setProperty("--cell-size", `${CELL_SIZE}vmin`)
gridElement.style.setProperty("--cell-gap", `${CELL_GAP}vmin`)
this.#cells = createCellElements(gridElement).map((cellElement, index) => {
return new Cell(
cellElement,
index % GRID_SIZE,
Math.floor(index / GRID_SIZE)
)
})
}
get cells() {
return this.#cells
}
get cellsByRow() {
return this.#cells.reduce((cellGrid, cell) => {
cellGrid[cell.y] = cellGrid[cell.y] || []
cellGrid[cell.y][cell.x] = cell
return cellGrid
}, [])
}
get cellsByColumn() {
return this.#cells.reduce((cellGrid, cell) => {
cellGrid[cell.x] = cellGrid[cell.x] || []
cellGrid[cell.x][cell.y] = cell
return cellGrid
}, [])
}
get #emptyCells() {
return this.#cells.filter(cell => cell.tile == null)
}
// it will return which ever cell is empty
randomEmptyCell() {
const randomIndex = Math.floor(Math.random() * this.#emptyCells.length)
return this.#emptyCells[randomIndex]
}
}
class Cell {
#cellElement
#x
#y
#tile
#mergeTile
constructor(cellElement, x, y) {
this.#cellElement = cellElement
this.#x = x
this.#y = y
}
get x() {
return this.#x
}
get y() {
return this.#y
}
get tile() {
return this.#tile
}
set tile(value) {
this.#tile = value
if (value == null) return
this.#tile.x = this.#x
this.#tile.y = this.#y
}
get mergeTile() {
return this.#mergeTile
}
set mergeTile(value) {
this.#mergeTile = value
if (value == null) return
this.#mergeTile.x = this.#x
this.#mergeTile.y = this.#y
}
canAccept(tile) {
return (
this.tile == null ||
(this.mergeTile == null && this.tile.value === tile.value)
)
}
mergeTiles() {
if (this.tile == null || this.mergeTile == null) return
this.tile.value = this.tile.value + this.mergeTile.value
this.mergeTile.remove()
this.mergeTile = null
}
}
function createCellElements(gridElement) {
const cells = []
for (let i = 0; i < GRID_SIZE * GRID_SIZE; i++) {
const cell = document.createElement("div")
cell.classList.add("cell")
cells.push(cell)
gridElement.append(cell)
}
return cells
}
//Export Tile js
class Tile {
#tileElement
#x
#y
#value
// randomly set 2 or 4
constructor(tileContainer, value = Math.random() > 0.5 ? 2 : 4) {
this.#tileElement = document.createElement("div")
this.#tileElement.classList.add("tile")
tileContainer.append(this.#tileElement)
this.value = value
}
get value() {
return this.#value
}
set value(v) {
this.#value = v
this.#tileElement.textContent = v
// to determine how many times a number has be raised to power of 2
const power = Math.log2(v)
const backgroundLightness = 100 - power * 9
this.#tileElement.style.setProperty("--background-light", `${backgroundLightness}%`)
this.#tileElement.style.setProperty("--text-light", `${backgroundLightness <= 50 ? 90 : 10}%`)
}
set x(value) {
this.#x = value
this.#tileElement.style.setProperty("--x", value)
}
set y(value) {
this.#y = value
this.#tileElement.style.setProperty("--y", value)
}
remove() {
this.#tileElement.remove()
}
waitForTransition(animation = false) {
return new Promise(resolve => {
this.#tileElement.addEventListener(
animation ? "animationend" : "transitionend",
resolve,
{
once: true,
}
)
})
}
}
//brain js
//import Grid from "./Grid.js";
//import Tile from "./Tile.js";
const board = document.getElementById("holder");
const grid = new Grid(board)
grid.randomEmptyCell().tile = new Tile(board)
grid.randomEmptyCell().tile = new Tile(board)
setupInput()
function setupInput() {
window.addEventListener("keydown", handleInput, { once: true })
}
async function handleInput(e) {
switch (e.key) {
case "ArrowUp":
if (!canMoveUp()) {
setupInput()
return
}
await moveUp()
break
case "ArrowDown":
if (!canMoveDown()) {
setupInput()
return
}
await moveDown()
break
case "ArrowLeft":
if (!canMoveLeft()) {
setupInput()
return
}
await moveLeft()
break
case "ArrowRight":
if (!canMoveRight()) {
setupInput()
return
}
await moveRight()
break
default:
setupInput()
return
}
grid.cells.forEach(cell => cell.mergeTiles())
const newTile = new Tile(board)
grid.randomEmptyCell().tile = newTile
if (!canMoveUp() && !canMoveDown() && !canMoveLeft() && !canMoveRight()) {
newTile.waitForTransition(true).then(() => {
alert("You lose")
})
return
}
setupInput()
}
function moveUp() {
return slideTiles(grid.cellsByColumn)
}
function moveDown() {
return slideTiles(grid.cellsByColumn.map(column => [...column].reverse()))
}
function moveLeft() {
return slideTiles(grid.cellsByRow)
}
function moveRight() {
return slideTiles(grid.cellsByRow.map(row => [...row].reverse()))
}
function slideTiles(cells) {
return Promise.all(
cells.flatMap(group => {
const promises = []
for (let i = 1; i < group.length; i++) {
const cell = group[i]
if (cell.tile == null) continue
let lastValidCell
for (let j = i - 1; j >= 0; j--) {
const moveToCell = group[j]
if (!moveToCell.canAccept(cell.tile)) break
lastValidCell = moveToCell
}
if (lastValidCell != null) {
promises.push(cell.tile.waitForTransition())
if (lastValidCell.tile != null) {
lastValidCell.mergeTile = cell.tile
} else {
lastValidCell.tile = cell.tile
}
cell.tile = null
}
}
return promises
})
)
}
function canMoveUp() {
return canMove(grid.cellsByColumn)
}
function canMoveDown() {
return canMove(grid.cellsByColumn.map(column => [...column].reverse()))
}
function canMoveLeft() {
return canMove(grid.cellsByRow)
}
function canMoveRight() {
return canMove(grid.cellsByRow.map(row => [...row].reverse()))
}
function canMove(cells) {
return cells.some(group => {
return group.some((cell, index) => {
if (index === 0) return false
if (cell.tile == null) return false
const moveToCell = group[index - 1]
return moveToCell.canAccept(cell.tile)
})
})
}
*,
*::before,
*::after {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
body {
background-color: black;
display: flex;
margin: 0;
justify-content: center;
align-items: center;
height: 100vh;
font-size: 7.5vmin;
}
#holder {
display: grid;
background-color: #ccc;
position: relative;
grid-template-columns: repeat(var(--grid-size), var(--cell-size));
grid-template-rows: repeat(var(--grid-size), var(--cell-size));
gap: var(--cell-gap);
padding: var(--cell-gap);
border-radius: 1vmin;
}
.cell {
background-color: #aaa;
border-radius: 1vmin;
}
.tile {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: var(--cell-size);
height: var(--cell-size);
border-radius: 1vmin;
top: calc(var(--y) * (var(--cell-size) + var(--cell-gap)) + var(--cell-gap));
left: calc(var(--x) * (var(--cell-size) + var(--cell-gap)) + var(--cell-gap));
font-weight: bold;
background-color: hsl(271, 50%, var(--background-light));
color: hsl(200, 25%, var(--text-light));
animation: wow 200ms ease-in-out;
transition: 100ms ease-in-out;
}
#keyframes wow {
0% {
opacity: .5;
transform: scale(0);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2048</title>
<link rel="stylesheet" href="game.css">
<script src="brain.js" type="module"></script>
</head>
<body>
<div id="holder">
</div>
</body>
</html>
Related
I need to link these two codes so that when the "isElementInViewport" function returns true to trigger the "inviewport" event:
let inViewportEvent = document.createEvent("Event");
inViewportEvent.initEvent("inviewport", true, true);
document.addEventListener("inviewport", (e) => {
console.log(`${e.target} in viewport!`)
}, false);
document.dispatchEvent(inViewportEvent);
and this function to detect if a element are in viewport:
const isElementInViewport = el => {
let rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
We must use CustomEvent constructor to create a new custom event, and then use dispatchEvent to trigger it...
const inViewportCustomEvent = new CustomEvent('inviewport', {
detail: {
/* put the data to be carried here*/
}
});
document.dispatchEvent(inViewportCustomEvent);
Illustration
const isElementInViewport = (el) => {
let rect = el.getBoundingClientRect();
// console.log(rect);
const isIn = (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
console.log('[isElementInViewport]', isIn, {
top: rect.top,
right: rect.right,
left: rect.left,
bottom: rect.bottom,
innerHeight: window.innerHeight,
clientHeight: document.documentElement.clientHeight,
innerWidth: window.innerWidth,
clientWidth: document.documentElement.clientWidth
});
return isIn;
};
const observer_callback = (entries, observer) => {
entries.filter(entry => isElementInViewport(entry.target))
.forEach(entry => {
console.log("We got something");
const inViewportCustomEvent = new CustomEvent('inviewport', {
detail: {
target: entry
/* put the data to be carried here*/
}
});
document.dispatchEvent(inViewportCustomEvent);
});
};
function create_observer() {
let options = {
root: document,
rootMargin: "5px"
};
return new IntersectionObserver(observer_callback, options);
}
const outermost = document.querySelector("#outermost");
const fill_counter = document.querySelector("#fill_counter");
const filler = document.querySelector("#filler");
const fill_clearer = document.querySelector("#fill_clearer");
const highlighted_index = document.querySelector("#highlighted_index");
function fill_squares(num_squares) {
outermost.append(...new Array(num_squares).fill(0).map((_, index) => create_square(index)));
function create_square(index) {
const divEle = document.createElement("div");
divEle.setAttribute("data-index", index);
divEle.classList.add("square");
divEle.onclick = (event) => {
event.target.classList.toggle("square");
event.target.classList.toggle("highlighted_square");
}
return divEle;
}
}
function highlight_square(index) {
const selected_square = outermost.querySelector(`[data-index="${index}"]`);
if (selected_square) {
if (!selected_square.classList.contains("highlighted_square")) {
selected_square.classList.toggle("square");
selected_square.classList.toggle("highlighted_square");
}
}
}
function highlight_squares(indexes) {
if (indexes && indexes.length) {
indexes.forEach(index => highlight_square(index));
}
}
function clear_children(parentElement) {
var e = parentElement;
var first = e.firstElementChild;
while (first) {
first.remove();
first = e.firstElementChild;
}
}
resetter.onclick = (event) => {
fill_counter.value = outermost.getAttribute("data-fill-count");
highlighted_index.value = +outermost.getAttribute("data-highlight-index");
reset();
}
filler.onclick = (event) => {
reset();
}
highlighter.onclick = (event) => {
const highlightedIndex = +highlighted_index.value < +event.target.min ? +event.target.value : +highlighted_index.value;
if (!isNaN(highlightedIndex)) {
highlight_square(highlightedIndex);
}
}
fill_counter.onchange = (event) => {
let current_value = +event.target.value;
if (!isNaN(current_value)) {
if (current_value < +event.target.min) {
event.target.value = +event.target.min;
}
}
}
highlighted_index.onchange = (event) => {
let current_value = +event.target.value;
if (!isNaN(current_value)) {
if (current_value < +event.target.min) {
event.target.value = +event.target.min;
}
if (+event.target.value === +event.target.min) {
event.target.value = +event.target.min;
}
}
}
function reset() {
clear_children(outermost);
fill_squares(+fill_counter.value);
}
function setup_listener() {
document.addEventListener("inviewport", (e) => {
console.log(`${e.detail.target} in viewport!`)
}, false);
}
reset();
highlight_squares([19, 50, 35]);
setup_listener();
const observer = create_observer();
outermost.querySelectorAll('.highlighted_square').forEach(square => observer.observe(square));
.input_region {
margin: 5px;
}
.input_region label {
display: inline-block;
}
.action_input {
padding: 10px;
}
.highlighted_square {
background: yellow
}
.num_input {
height: 30px;
width: 50px;
padding: 5px;
}
.square {
background: magenta
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr));
grid-auto-rows: 1fr;
}
.grid::before {
content: '';
width: 0;
padding-bottom: 100%;
grid-row: 1 / 1;
grid-column: 1 / 1;
}
.grid>*:first-child {
grid-row: 1 / 1;
grid-column: 1 / 1;
}
/* Just to make the grid visible */
.grid>* {
// background: rgba(0, 0, 0, 0.1);
border: 1px white solid;
}
<section>
<div class="input_region">
<input class="num_input" id="fill_counter" type="number" value="1000" min="10" />
<button id="filler" class="action_input">FILL</button>
</div>
<div class="input_region">
<input class="num_input" id="highlighted_index" type="number" value="10" min="0" />
<button id="highlighter" class="action_input">HIGHLIGHT</button>
</div>
<div class="input_region">
<button class="action_input" id="resetter">RESET</button>
</div>
</section>
<section>
<div id="outermost" class="grid" data-fill-count="1000" data-highlight-index="100"></div>
</section>
How do I perform an animated transformation on text while performing a fade in effect during the animated transformation?
// ——————————————————————————————————————————————————
// TextScramble
// ——————————————————————————————————————————————————
class TextScramble {
constructor(elm, numWords) {
this.el = el
this.numWords = numWords;
this.chars = '!<>-_\\/[]{}—=+*^?#1234567890________'
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({ from, to, start, end })
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let { from, to, start, end, char } = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
}
else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}
// ——————————————————————————————————————————————————
// Example
// ——————————————————————————————————————————————————
const phrases = {
'Coding' : 'none',
'With' : 'none',
'Muhammad': 'none',
'Coding With Muhammad' : 'fade'
}
let phraseValues = Object.keys(phrases);
const el = document.querySelector('.text')
const fx = new TextScramble(el, phraseValues.length)
let counter = 0
let animation = phraseValues[0];
let animate = () => {
return function(callback) {
document.querySelector(".text").animate([
// keyframes
{ opacity: '0' },
{ opacity: '1' }
], {
// timing options
duration: 3500,
iterations: 1
});
callback();
}
}
const next = () => {
fx.setText(phraseValues[counter]).then(() => {
if (counter <= phraseValues.length)
setTimeout(next, 800)
else {
animation = phrases[phraseValues[counter]]
setTimeout(animate(next), 800)
}
})
counter = (counter + 1) % phraseValues.length
}
next()
html, body {
font-family: 'Roboto Mono', monospace;
background: #212121;
height: 100%;
}
.container {
height: 100%;
width: 100%;
justify-content: center;
align-items: center;
display: flex;
}
.text {
font-weight: 100;
font-size: 28px;
color: #FAFAFA;
}
.dud {
color: #757575;
}
.fadeIn {
animation: fade 10s;
}
<div class="container">
<div class="text"></div>
</div>
I was very close:
I moved the callback invocation statement above the closure return statement below it. I left the animation keyframes as is.
Finally I modified the setTimeout in the phrase to be animated, to be as follows:
I placed a next and animate as callbacks in the setTimeout together to be called back in cascade sequence.
I used a anonymous function definition using arrow notation.
On animate (the function I wrote) I passed in the fx.update function definition as the callback, and invoked the closure function returned animate as the Higher Order Function, like so.
See Results!
// ——————————————————————————————————————————————————
// TextScramble
// ——————————————————————————————————————————————————
class TextScramble {
constructor(elm, numWords) {
this.el = el
this.numWords = numWords;
this.chars = '!<>-_\\/[]{}—=+*^?#1234567890________'
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({ from, to, start, end })
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update = () => {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let { from, to, start, end, char } = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="span">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
}
else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}
// ——————————————————————————————————————————————————
// Example
// ——————————————————————————————————————————————————
const phrases = {
'Coding' : 'none',
'With' : 'none',
'Muhammad': 'none',
'Coding With Muhammad' : 'fade'
}
let phraseValues = Object.keys(phrases);
const el = document.querySelector('.text')
const fx = new TextScramble(el, phraseValues.length)
let counter = 0
let animation = phraseValues[0];
let animate = (callback) => {
callback();
return function() {
document.querySelector(".text").animate([
// keyframes
{ opacity: '0' },
{ opacity: '1' }
], {
// timing options
duration: 3500
});
}
}
const next = () => {
fx.setText(phraseValues[counter]).then(() => {
if (counter < phraseValues.length-1)
setTimeout(next, 800)
else {
setTimeout(() => {next, animate(next, fx.update)()}, 800)
}
})
counter = (counter + 1) % phraseValues.length
}
next()
html, body {
font-family: 'Roboto Mono', monospace;
background: #212121;
height: 100%;
}
.container {
height: 100%;
width: 100%;
justify-content: center;
align-items: center;
display: flex;
}
.text {
font-weight: 100;
font-size: 28px;
color: #FAFAFA;
}
.dud {
color: #757575;
}
<div class="container">
<div class="text"></div>
</div>
hello i have this error : Undefined offset: 0 (View: /home/me/www/me/resources/views/contact.blade.php) i was try to create crud in admin panel for contact page. when i try to go in for edit this page, i have this error
Undefined offset: 0 (View: /home/.../www/.../resources/views/contact.blade.php) and if i remplace all data by {{ dd($data) }} i have this
Address
<script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/, keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl', addEventListener = function (e, n, cb) { e.addEventListener(n, cb, false); }; (doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, function (e) { e.preventDefault = function () {e.returnValue = false;}; e.target = e.srcElement; callback(e); }); }; } function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '▼'; newClass = 'sf-dump-expanded'; } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '▶'; newClass = 'sf-dump-compact'; } else { return false; } if (doc.createEvent && s.dispatchEvent) { var event = doc.createEvent('Event'); event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false); s.dispatchEvent(event); } a.lastChild.innerHTML = arrow; s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } } } catch (e) { } } return true; }; function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function collapseAll(root) { var a = root.querySelector('a.sf-dump-toggle'); if (a) { collapse(a, true); expand(a); return true; } return false; } function reveal(node) { var previous, parents = []; while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) { parents.push(previous); } if (0 !== parents.length) { parents.forEach(function (parent) { expand(parent); }); return true; } return false; } function highlight(root, activeNode, nodes) { resetHighlightedNodes(root); Array.from(nodes||[]).forEach(function (node) { if (!/\bsf-dump-highlight\b/.test(node.className)) { node.className = node.className + ' sf-dump-highlight'; } }); if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) { activeNode.className = activeNode.className + ' sf-dump-highlight-active'; } } function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } return function (root, x) { root = doc.getElementById(root); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), options = {
options.maxDepth)) { toggle(a); } } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { s = a.nextSibling; elt.appendChild(a); s.parentNode.insertBefore(a, s); if (/^[##]/.test(elt.innerHTML)) { elt.innerHTML += ' ▶'; } else { elt.innerHTML = '▶'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '…'; elt.className = 'sf-dump-ref'; } } } } } if (doc.evaluate && Array.from && root.children.length > 1) { root.setAttribute('tabindex', 0); SearchState = function () { this.nodes = []; this.idx = 0; }; SearchState.prototype = { next: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0; return this.current(); }, previous: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1); return this.current(); }, isEmpty: function () { return 0 === this.count(); }, current: function () { if (this.isEmpty()) { return null; } return this.nodes[this.idx]; }, reset: function () { this.nodes = []; this.idx = 0; }, count: function () { return this.nodes.length; }, }; function showCurrent(state) { var currentNode = state.current(), currentRect, searchRect; if (currentNode) { reveal(currentNode); highlight(root, currentNode, state.nodes); if ('scrollIntoView' in currentNode) { currentNode.scrollIntoView(true); currentRect = currentNode.getBoundingClientRect(); searchRect = search.getBoundingClientRect(); if (currentRect.top < (searchRect.top + searchRect.height)) { window.scrollBy(0, -(searchRect.top + searchRect.height + 5)); } } } counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count(); } var search = doc.createElement('div'); search.className = 'sf-dump-search-wrapper sf-dump-search-hidden'; search.innerHTML = '
0 of 0<\/span> '+h+' ◀'+ ''+elt.innerHTML+' ▶'; } } } catch (e) { } }; })(document);
Illuminate\Database\Eloquent\Collection {#1218
#items: []
}
contact blade
<?php
/**
* Created by PhpStorm.
* User: abhi
* Date: 10/20/2020
* Time: 5:54 PM
*/?>
#extends('layouts.app')
<style>
body {
font-family: "Lato", sans-serif;
}
.sidenav {
height: 100%;
width: 160px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
padding-top: 20px;
}
.sidenav a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
}
.sidenav a:hover {
color: #f1f1f1;
}
.main {
margin-left: 160px; /* Same as the width of the sidenav */
font-size: 28px; /* Increased text to enable scrolling */
padding: 0px 10px;
}
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
</style>
#section('content')
<!-- CSS only -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
{{--<div class="sidenav">--}}
{{--Post--}}
{{--Categories--}}
{{--Footer--}}
{{--Society--}}
{{--</div>--}}
<section style="padding-top:60px;">
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-header">
Update Contact Details...
</div>
<div class="card-body">
#if(Session::has('status'))
<div class="alert alert-success" role="alert">
{{Session::get('status')}}
</div>
#endif
<form id="insert" method="POST" action="{{url('updatecontact')}}"
enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="h1">Address</label>
<input type="text" value="{{$data[0]->address}}" name="address" class="form-control"/>
<label for="h2">Contact(1)</label>
<input type="tel" value="{{$data[0]->contact1}}" name="contact1" class="form-control"/>
<label for="h2">Contact(2)</label>
<input type="tel" value="{{$data[0]->contact2}}" name="contact2" class="form-control"/>
<label for="h2">Fax</label>
<input type="tel" value="{{$data[0]->fax}}" name="fax" class="form-control"/>
<label for="h2">E-mail</label>
<input type="email" value="{{$data[0]->email}}" name="email" class="form-control"/>
<br>
<input type="hidden" value="{{$data[0]->id}}" name="rowid">
</div>
<button type="submit" class="btn btn-primary">Update Details</button>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- JS, Popper.js, and jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"
crossorigin="anonymous"></script>
<script>
function previewFile1(input) {
var file1 = $(input).get(0).files[0];
if (file1) {
var reader = new FileReader();
reader.onload = function () {
$('#previewImg1').attr("src", reader.result);
}
reader.readAsDataURL(file1);
}
}
</script>
#endsection
controller
<?php
namespace App\Http\Controllers;
use App\Mail\ContactMail;
use App\Models\Contact;
use App\Models\ContactDetails;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class ContactController extends Controller
{
function index(){
$this->middleware('auth');
$data['data'] = Contact::all();
return view('contact', $data);
}
function updateContact(Request $request){
$this->middleware('auth');
$data['address'] = $request->address;
$data['contact1'] = $request->contact1;
$data['contact2'] = $request->contact2;
$data['fax'] = $request->fax;
$data['email'] = $request->email;
$affected = DB::table('contacts')
->where('id', '=', $request->rowid)
->update($data);
return back()->with('status', 'Contact Details are Updated');
}
function sendContact(Request $request){
$contact = new ContactDetails();
$contact->name = $request->name;
$contact->email = $request->email;
$contact->phone = $request->phone;
$contact->msg = $request->message;
$contact->save();
$dataObject = new \stdClass();
$dataObject->name = $request->name;
$dataObject->email = $request->email;
$dataObject->phone = $request->phone;
$dataObject->msg = $request->message;
Mail::to('mokoch.web#gmail.com')->send(new ContactMail($dataObject));
return back()->with('status', 'Contact Details are Updated');
}
}
i try to create update for contact and i was hosted this but i have this i dont know how resolve... because crud for footer and other work whithout problem. it's in laravel 8
Honestly I would refactor the following
$data['data'] = Contact::all();
to
$contacts = Contact::all();
Remember that Contact::all(); is going to return an array of collections so you would need to loop through $contacts on your index view.
if you are trying to update a contact you need to get the specific contact first for example:
$contact = Contact::find($id);
Then in your blade you can simply use $contact->email instead of $data[0]->email
So in your situation you need to create a show method that accepts an id as a parameter then you can find the record you want to update and use the example above.
A good resource if you are new CodersTape
CSS
.btnMusic {
background-color: #4CAF50;
/* Green */
border: none;
color: white;
padding: 50px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
width: 130px;
height: 130px;
margin-bottom: 5px;
}
.btnMusic:hover {
background-color: darkgreen;
cursor: pointer;
border: 1px solid black;
}
#options {
margin-top: 20px;
}
JS
var boolean_loop = false;
var sound_highhat = new Audio("sound/sound_highhat.mp3");
var sound_lowhat = new Audio("sound/sound_lowhat.mp3");
var sound_synth = new Audio("sound/sound_synth.mp3");
var sound_beat = new Audio("sound/sound_beat.mp3");
function sound_loop() {
if (boolean_loop === false) {
document.getElementById("loopoption").innerHTML = "Loop (Active)";
boolean_loop = true;
} else if (boolean_loop === true) {
document.getElementById("loopoption").innerHTML = "Loop";
boolean_loop = false;
}
}
function audiostop() {
sound_highhat.pause()
sound_highhat.currentTime = 0.0;
sound_lowhat.pause()
sound_lowhat.currentTime = 0.0;
sound_synth.pause()
sound_synth.currentTime = 0.0;
sound_beat.pause()
sound_beat.currentTime = 0.0;
}
function play_highhat() {
if (boolean_loop === true) {
sound_highhat.addEventListener("ended", function() {
this.currentTime = 0;
this.play();
}, false);
sound_highhat.play();
} else if (boolean_loop === false) {
sound_highhat.play();
}
}
function play_lowhat() {
if (boolean_loop === true) {
sound_lowhat.addEventListener("ended", function() {
this.currentTime = 0;
this.play();
}, false);
sound_lowhat.play();
} else {
sound_lowhat.play();
}
}
function play_synth() {
if (boolean_loop === true) {
sound_synth.addEventListener("ended", function() {
this.currentTime = 0;
this.play();
}, false);
sound_synth.play();
} else {
sound_synth.play();
}
}
function play_beat() {
if (boolean_loop === true) {
sound_beat.addEventListener("ended", function() {
this.currentTime = 0;
this.play();
}, false);
sound_beat.play();
} else {
sound_beat.play();
}
}
HTML
<div id="musicboard">
<button class="btnMusic" onclick="play_highhat()">High Hat</button>
<button class="btnMusic" onclick="play_lowhat()">Low Hat</button>
<br>
<button class="btnMusic" onclick="play_synth()">Synth</button>
<button class="btnMusic" onclick="play_beat()">Beat</button>
</div>
<div id="options">
<button id="loopoption" onclick="sound_loop()">Loop</button>
<button onclick="audiostop()">Stop Music</button>
</div>
For a school task i've made a small soundboard with 4 sounds. I also have a button triggering a boolean to loop the sounds. The loop works fine, but whenever i stop all the sounds, if i click a sound that has been looped once before; it will loop again no matter the state of the boolean.
When you play a sound with looping option true what your code does is, is adds an event listener if loop condition is true. What you probably want to have is to check for the looping condition inside your listener.
Example of adding listener to one of the buttons.
sound_beat.addEventListener("ended", function() {
if (boolean_loop === true) {
this.currentTime = 0;
this.play();
}
}, false);
So, your code might look like this:
var boolean_loop = false;
var sound_highhat = new Audio("sound/sound_highhat.mp3");
var sound_lowhat = new Audio("sound/sound_lowhat.mp3");
var sound_synth = new Audio("sound/sound_synth.mp3");
var sound_beat = new Audio("sound/sound_beat.mp3");
function aListener = function() {
if (boolean_loop === true) {
this.currentTime = 0;
this.play();
}
};
// once you add listeners to the audio objects, those listeners stay there until they are removed so every "ended" event will trigger a listener
sound_highhat.addEventListener("ended", aListener, false);
sound_lowhat.addEventListener("ended", aListener, false);
sound_synth.addEventListener("ended", aListener, false);
sound_beat.addEventListener("ended", aListener, false);
function sound_loop() {
if (boolean_loop === false) {
document.getElementById("loopoption").innerHTML = "Loop (Active)";
boolean_loop = true;
} else if (boolean_loop === true) {
document.getElementById("loopoption").innerHTML = "Loop";
boolean_loop = false;
}
}
function audiostop() {
sound_highhat.pause()
sound_highhat.currentTime = 0.0;
sound_lowhat.pause()
sound_lowhat.currentTime = 0.0;
sound_synth.pause()
sound_synth.currentTime = 0.0;
sound_beat.pause()
sound_beat.currentTime = 0.0;
}
function play_highhat() {
sound_highhat.play();
}
function play_lowhat() {
sound_lowhat.play();
}
function play_synth() {
sound_synth.play();
}
function play_beat() {
sound_beat.play();
}
I have a parallax function for a slide section of my page with 3 background images. For some reasons it is appearing quite laggy and slow when I scroll and sometimes it's hard to scroll to the 3rd background image or if I'm already at 3rd background I can't seem to scroll up again. If I scrolled up to the first background I seem to be stuck on this section and I can't go to the section above it. Not sure where I went wrong.
Here's my js:
(function ($) {
var types = ['DOMMouseScroll', 'mousewheel'];
if ($.event.fixHooks) {
for (var i = types.length; i;) {
$.event.fixHooks[types[--i]] = $.event.mouseHooks;
}
}
$.event.special.mousewheel = {
setup: function () {
if (this.addEventListener) {
for (var i = types.length; i;) {
this.addEventListener(types[--i], handler, false);
}
} else {
this.onmousewheel = handler;
}
}
, teardown: function () {
if (this.removeEventListener) {
for (var i = types.length; i;) {
this.removeEventListener(types[--i], handler, false);
}
} else {
this.onmousewheel = null;
}
}
};
$.fn.extend({
mousewheel: function (fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
}
, unmousewheel: function (fn) {
return this.unbind("mousewheel", fn);
}
});
function handler(event) {
var orgEvent = event || window.event
, args = [].slice.call(arguments, 1)
, delta = 0
, returnValue = true
, deltaX = 0
, deltaY = 0;
event = $.event.fix(orgEvent);
event.type = "mousewheel";
if (orgEvent.wheelDelta) {
delta = orgEvent.wheelDelta / 120;
}
if (orgEvent.detail) {
delta = -orgEvent.detail / 3;
}
deltaY = delta;
if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {
deltaY = 0;
deltaX = -1 * delta;
}
if (orgEvent.wheelDeltaY !== undefined) {
deltaY = orgEvent.wheelDeltaY / 120;
}
if (orgEvent.wheelDeltaX !== undefined) {
deltaX = -1 * orgEvent.wheelDeltaX / 120;
}
args.unshift(event, delta, deltaX, deltaY);
return ($.event.dispatch || $.event.handle).apply(this, args);
}
})(jQuery);
var Parallax = {
utils: {
doSlide: function (section) {
var top = section.position().top;
$('#section-wrapper').stop().animate({
top: -top
}, 600, 'linear', function () {
section.addClass('slided').siblings('div.section').removeClass('slided');
});
}
}
, fn: {
setHeights: function () {
$('div.section').height($(window).height());
}
, onSiteScroll: function () {
var section = null;
$('#section-wrapper').mousewheel(function (event, delta) {
event.preventDefault();
if (delta < 0) {
section = ($('.slided').length) ? $('.slided') : $('#section-1');
var next = (section.next().length) ? section.next() : $('#section-1');
Parallax.utils.doSlide(next);
} else if (delta > 0) {
section = ($('.slided').length) ? $('.slided') : $('#section-1');
var prev = (section.prev().length) ? section.prev() : $('#section-1');
Parallax.utils.doSlide(prev);
}
});
}
},
init: function () {
for (var prop in this.fn) {
if (typeof this.fn[prop] === 'function') {
this.fn[prop]();
}
}
}
};
Parallax.init();
The css here:
#site {
width: 100%;
height: 100%;
min-height: 100%;
}
#section-wrapper {
position: relative;
width: 100%;
height: 100%;
min-height: 100%;
}
div.section {
width: 100%;
position: relative;
height: 100%;
min-height: 100%;
}
#section-1 {
background: url("../img/teavana/slide1.png");
}
#section-2 {
background: url("../img/teavana/slide2.png");
}
#section-3 {
background: url("../img/teavana/slide3.png");
}
And this is the html for the section:
<div id="site">
<div id="section-wrapper">
<div class="section" id="section-1"></div>
<div class="section" id="section-2"></div>
<div class="section" id="section-3"></div>
</div>
</div>