链接到存储源代码的存储库。
重现错误的步骤:
- 下载资源;
- 安装依赖项;
- 运行其中一个可用的脚本
package.json
; - 等待组装;
- 如果正在运行- 等待它在浏览器中显示构建结果
dev
的那一刻;webpack-dev-server
- 如果正在运行
build
,请自行index.html
在目录中打开dist
;
- 打开浏览器控制台。
链接到存储源代码的存储库。
package.json
;dev
的那一刻;webpack-dev-server
build
,请自行index.html
在目录中打开dist
;我知道从语义和验证的角度来看这是不好的。
但也许还有其他原因表明没有必要这样做?
我决定将计算器的类组件重写为功能性组件。
面对这样一个事实,当您尝试从键盘输入数字时,只会记录和显示最后一个字符。
想知道我做错了什么。
下面附上组件代码:
import React, {useState, useEffect, useCallback} from 'react';
import styles from './Calculator.module.css';
import Display from '../../UI/Display/Display';
import Button from '../../UI/Button/Button';
const Calculator = (props) => {
const [operation, setOperation] = useState(null);
const [currentVal, setCurrentVal] = useState(0);
const [prevVal, setPrevVal] = useState(0);
const btnsVal = [
'C', '√', 'x²', '/',
'7', '8', '9', '*',
'4', '5', '6', '-',
'1', '2', '3', '+',
'.', '0', 'Del', '='
];
const btnsArr = btnsVal.map((val, index) =>
<Button
key={`${index}-${val}`}
value={val}
onClick={() => clickEventHandler(val)}
/>
);
const calcOperations = {
'/': (prevValue, currentValue) => prevValue / currentValue,
'*': (prevValue, currentValue) => prevValue * currentValue,
'+': (prevValue, currentValue) => Number(prevValue) + Number(currentValue),
'-': (prevValue, currentValue) => prevValue - currentValue,
'=': currentValue => currentValue,
'√': currentValue => Math.sqrt(currentValue),
'x²': currentValue => currentValue**2
};
useEffect(() => {
document.addEventListener('keydown', keydownEventHandler);
return () => document.removeEventListener('keydown', keydownEventHandler);
}, []);
const keydownEventHandler = useCallback(({key}) => {
if (btnsVal.includes(key) ){
clickEventHandler(key);
}else if (key === 'Backspace'){
clickEventHandler('Del');
}else if (key === ','){
clickEventHandler('.');
}else if (key === 'Enter'){
clickEventHandler('=');
}
}, [btnsVal]);
useEffect(() => {
!currentVal && setCurrentVal('0');
!prevVal && setPrevVal('0');
}, [currentVal, prevVal]);
const writeNum = (symbol) => {
const value = (symbol === '.' || currentVal.toString() !== '0')
? currentVal + symbol
: symbol;
if (Array.from(value).filter(item => item === '.').length < 2){
setCurrentVal(value);
}
}
const choiceOperation = (symbol) => {
if (['√','x²'].includes(symbol)){
const currVal = calcOperations[symbol](Number(currentVal) || prevVal);
operation === '=' && setOperation(null);
setCurrentVal(currVal);
return;
} else if (operation){
setPrevVal(calcOperations[operation](prevVal, currentVal));
}else {
setPrevVal(currentVal);
}
setCurrentVal(0);
setOperation(symbol);
}
const clickEventHandler = (symbol) => {
if (/(\d|\.)/.test(symbol)) {
writeNum(symbol);
}else if (symbol === 'Del') {
setCurrentVal(`${currentVal}`.slice(0, -1));
}else if (symbol === 'C') {
setOperation(null);
setCurrentVal(0);
setPrevVal(0);
}else{
choiceOperation(symbol);
}
}
return (
<div className={styles.Calculator}>
<Display result={operation === '=' ? prevVal : currentVal}/>
<div className={styles.btnsBlock}>{btnsArr}</div>
</div>
);
}
export default Calculator;
其中一种应用程序方法使用以下代码:
var tpl = document.createElement('template');
tpl.innerHTML = text;
其中text
包含以下值(作为字符串):
<nf-form form-title="Тестовая форма">
<nf-input>
<nf-input-mask scale="2" max-year="2099" min-year="1899" mask="N" map-to-radix="[".", ","]" thousands-separator=" " min="-1000" max="1000"></nf-input-mask>
</nf-input>
</nf-form>
添加text
'a 作为内容后,标签<template>
如下所示:
<nf-form form-title="Тестовая форма">
<nf-input>
<nf-input-mask scale="2" max-year="2099" min-year="1899" mask="N" map-to-radix="[" .",="" ","]"="" thousands-separator=" " min="-1000" max="1000"></nf-input-mask>
</nf-input>
</nf-form>
如您所见,模板的内容现在包含符号=""
。
我想知道为什么会发生这种情况,以及如何预防?
这里有张桌子:
id |org|value|
----|---|-----|
1030| 1| 1029|
1033| 1| 1032|
1039| 1| 1029|
必须只显示该列的唯一记录value
。如果value
记录有重复,则输出最后一个。
这可以在不使用的情况下完成distinct on
吗?
假设我有一个字符串表示形式的对象数组。
我想在{或[字符之后添加换行符。
问题是该属性的值uid
可以包含字符{并且我不想在那里添加一个换行符。
转换前:
[{uid: 'ffa{jf45', name: 'Andrew', surname: 'Ivanov'}, {uid: '122', name: 'Ann', surname: 'Smith'}]
转换后:
[
{
uid: 'ffa{jf45'
name: 'Andrew',
surname: 'Ivanov'
},
{
uid: '122',
name: 'Ann',
surname: 'Smith'
}
]
在我的项目中,我express, node.js
用作后端。对于显示,我使用模板引擎pug
。我想知道如何每秒将新数据传递给页面。我将附上下面的代码。
PS 1.setInterval
不适合,因为它会给出错误。2. 该方法netInfo.getStats()
返回新数据。
app.get('/network', async (req, res)=> {
try {
const netInfo = require('./lib/net');
const netIface = await netInfo.netInterface();
setInterval(async function() {
const stats = await netInfo.getStats();
res.render('network', {
title: 'Network',
slogan: 'Get data about ip address, mask and etc.',
data: {...netIface, ...stats},
});
}, 1000);
} catch (e) {
console.error(e);
}
});
如何使用 3d 对象更改当前纹理(以编程方式设置)textureObjLoader
?
textureObjLoader = new THREE.TextureLoader(),
map = textureObjLoader.load(`./models/${allTextures[i][0]}`);
material = new THREE.MeshPhongMaterial({map: map});
objLoader = new THREE.OBJLoader();
objLoader.load(`./models/${objects[i]}`, function (obj) {
obj.traverse( node=>{if (node.isMesh) node.material = material});
obj.name = names[i];
scene.add(obj);
});
是否可以在动画期间向画布中的元素添加过渡?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speedometer</title>
<link rel="stylesheet" href="../css/common.css">
<style>
*{
background: #fff;
font-family: 'SF Pro Display',sans-serif!important;
margin: 0;
padding: 0;
}
.container{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
}
.data_about_load{
position: relative;
top: -60px;
opacity: 0;
}
.data_about_load:before{
content: "";
display: inline-block;
width: 20px;
height: 20px;
background: url(../img/svg/add/check_green.svg) center no-repeat;
background-size: contain;
position: relative;
top: 4px;
margin-right: 12px;
}
#canvas{
opacity: 0;
}
.data{
font-size: 16px;
font-weight: 600;
color: #0a0a0a;
}
.bold_time{
font-weight: 700;
}
/*animations*/
.fade-in-left {
animation: fade-in-left 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
}
.slide-in-fwd-center {
animation: slide-in-fwd-center 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@keyframes fade-in-left {
0% {
transform: translateX(-50px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-in-fwd-center {
0% {
transform: translateZ(-1400px);
opacity: 0;
}
100% {
transform: translateZ(0);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<canvas id="canvas" width="500" height="500"></canvas>
<div class="data_about_load"><span class="data">Время загрузки <span class="bold_time">0.1 сек</span></span></div>
</div>
<script>
const canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
counterClockwise = false,
proportions={
general: {
// general settings
middleX : canvas.width / 2,
middleY : canvas.height / 2,
radius : 240,
},
ticks: {
//ticks settings
tickOffsetFromArc : canvas.width / 40,
},
digits: {
digitsOffsetFromArc : canvas.width / 15,
},
indicator: {
quarterY: (canvas.height / 2)/1.7
}
},
colorPalette= {
// ticks palette
ticks: {
red: {
redTickColor: "#FF0000"
},
yellow: {
darkYellowTickColor: "#F9AF00"
},
green: {
greenTickColor: "#13B74B",
whiteFillColor: "#FFF",
greenShadowColor: "#a8bbaa"
}
},
//arrow color
arrow: {
bgBlue: "#3970eb",
shadowColor: "rgba(66,115,247,0.5)"
},
//text color
text: "#0a0a0a",
diagram:{
bg :{
gradient:[
"#e0f6e8",
"#deede4"
],
lines: "#ecedec"
}
}
},
fonts={
digitsFont: "bold 20px SF Pro Display",
indicator: "600 80px SF Pro Display",
diagramFont: "bold 10px SF Pro Display"
},
// numbers setting
digits = [0, 20, 40, 50, 60, 70, 80, 90, 100],
//zones
zonesCount = digits.length - 1;
// Arrow settings
let arrowValueIndex = -2.45,
// beginning and ending of our arc. Sets by radius*pi
startAngleIndex = .75,
endAngleIndex = 2.25,
step = (endAngleIndex - startAngleIndex) / zonesCount,
allDataDiagram=[],
forVisibleElem=true;
/*draw zones*/
let DrawZones = function () {
const greyZonesCount = zonesCount / 1.6;
greenZonesCount = zonesCount - greyZonesCount,
startAngle = (startAngleIndex - 0.02) * Math.PI,
endGreyAngle = (startAngleIndex + greyZonesCount * step) * Math.PI,
endGreenAngle = (endAngleIndex + 0.02) * Math.PI,
//zones' options
sectionOptions = [
{
startAngle: startAngle,
endAngle: endGreyAngle,
color: "#e7e7e7",
zoneLineWidth: 2
},
{
startAngle: endGreyAngle,
endAngle: endGreenAngle,
color: "#13b74b",
zoneLineWidth: 5
},
];
//draw zones
this.DrawZone = function (options) {
ctx.beginPath();
ctx.arc(proportions.general.middleX, proportions.general.middleY, proportions.general.radius, options.startAngle, options.endAngle, counterClockwise);
ctx.lineWidth = options.zoneLineWidth;
ctx.strokeStyle = options.color;
ctx.lineCap = "round";
ctx.stroke();
};
sectionOptions.forEach(options => this.DrawZone(options));
};
/*draw dots*/
let DrawTicks = function () {
startAngleIndex = .73,
endAngleIndex = 2.27,
step = (endAngleIndex - startAngleIndex) / zonesCount;
this.DrawTick = function (angle,count) {
let fromX = proportions.general.middleX + (proportions.general.radius - proportions.ticks.tickOffsetFromArc) * Math.cos(angle),
fromY = proportions.general.middleY + (proportions.general.radius - proportions.ticks.tickOffsetFromArc) * Math.sin(angle),
toX = proportions.general.middleX + (proportions.general.radius + proportions.ticks.tickOffsetFromArc) * Math.cos(angle),
toY = proportions.general.middleY + (proportions.general.radius + proportions.ticks.tickOffsetFromArc) * Math.sin(angle),
centerOfDotX=(fromX+toX)/2,
centerOfDotY=(fromY+toY)/2;
ctx.beginPath();
ctx.arc(centerOfDotX,centerOfDotY,6,0,Math.PI*2,true);
if (count<6){
switch (count) {
case 1:
case 2:
case 3:
ctx.fillStyle=colorPalette.ticks.red.redTickColor;
break;
default:
ctx.fillStyle=colorPalette.ticks.yellow.darkYellowTickColor;
break;
}
}else{
ctx.fillStyle=colorPalette.ticks.green.whiteFillColor;
ctx.strokeStyle=colorPalette.ticks.green.greenTickColor;
ctx.shadowColor = colorPalette.ticks.green.greenShadowColor;
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
}
ctx.fill();
ctx.closePath();
ctx.shadowBlur =0;
};
let count=0;
for (let i = startAngleIndex; i <= endAngleIndex; i += step) {
let angle = i * Math.PI;
count++;
this.DrawTick(angle,count);
}
};
//draw numbers
let DrawDigits = function () {
let angleIndex = startAngleIndex;
digits.forEach(function (digit) {
let angle = angleIndex * Math.PI,
x = proportions.general.middleX + (proportions.general.radius - proportions.digits.digitsOffsetFromArc) * Math.cos(angle),
y = proportions.general.middleY + (proportions.general.radius - proportions.digits.digitsOffsetFromArc) * Math.sin(angle);
angleIndex += step;
ctx.font = fonts.digitsFont;
ctx.fillStyle = colorPalette.text;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(digit, x, y);
});
};
/*draw arrow*/
let DrawArrow = function () {
ctx.beginPath();
ctx.lineCap = "round";
ctx.moveTo(proportions.general.middleX-15, proportions.general.middleY);
ctx.lineTo(proportions.general.middleX, proportions.general.middleY-150);
ctx.lineTo(proportions.general.middleX+15, proportions.general.middleY);
ctx.closePath();
ctx.strokeStyle = colorPalette.arrow.bgBlue;
ctx.fillStyle=colorPalette.arrow.bgBlue;
ctx.shadowColor=colorPalette.arrow.shadowColor;
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
ctx.fill();
ctx.shadowBlur =0;
};
let oldText=0;
/*draw indicator's number*/
let DrawIndicator=function (val) {
ctx.font = fonts.indicator;
ctx.fillStyle = colorPalette.ticks.green.whiteFillColor; // or whatever color the background is.
ctx.fillText(oldText, proportions.general.middleX, proportions.indicator.quarterY);
ctx.fillStyle = colorPalette.text;
ctx.fillText(`${val}`, proportions.general.middleX, proportions.indicator.quarterY);
ctx.font = fonts.digitsFont;
ctx.fillText('points',proportions.general.middleX,proportions.indicator.quarterY+proportions.general.middleY/5);
oldText=val;
};
let indicatorNum=0;
/*renderer*/
function renderer() {
ctx.clearRect(0,0,canvas.width,canvas.height);
DrawZones();
DrawTicks();
DrawDigits();
Diagram();
DrawIndicator(indicatorNum);
ctx.translate(proportions.general.middleX,proportions.general.middleY);
ctx.rotate(arrowValueIndex);
ctx.translate(-proportions.general.middleX,-proportions.general.middleY);
DrawArrow();
ctx.translate(proportions.general.middleX,proportions.general.middleY);
ctx.rotate(-arrowValueIndex);
ctx.translate(-proportions.general.middleX,-proportions.general.middleY);
}
function val(value) {
let sector = Math.PI*0.385;
if (value < 40)
arrowValueIndex = value/40*sector - sector*2;
else
arrowValueIndex = (value-40)/60*sector*3 - sector;
let add=(val)=>{
indicatorNum=val;
allDataDiagram.unshift(val);
allDataDiagram=allDataDiagram.slice(0,186);
};
add(value);
// document.querySelector('span').textContent = value;
renderer();
}
//кроссбраузерный requestAnimationFrame
let requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
let mainNum=0;
let max=0.5, min=-0.6;
let Engine=()=>{
if (forVisibleElem) canvas.classList.add('slide-in-fwd-center');
if (mainNum<70) mainNum+=.5;
if (mainNum>=70 && mainNum<97)mainNum+=.4;
if (mainNum>=97){
if(forVisibleElem) mainNum+=.3;
else mainNum+=.03;
}
if (mainNum>=100){
mainNum=98.7;
if (forVisibleElem) {
document.querySelector(".data_about_load").classList.add("fade-in-left");
forVisibleElem=false;
}
}
val(Math.floor(mainNum));
requestAnimFrame(Engine);
};
let Diagram=()=>{
this.drawLines=(x,y,width,height)=>{
ctx.lineWidth=1.5;
ctx.strokeStyle=colorPalette.diagram.bg.lines;
ctx.moveTo(x,y);
ctx.lineTo(width,height);
ctx.stroke();
};
this.drawCircles = (x,y,r)=>{
ctx.beginPath();
ctx.arc(x,y,r,2*Math.PI,false);
ctx.fillStyle=colorPalette.ticks.green.greenTickColor;
ctx.fill();
ctx.closePath();
};
this.writeNums = (value,x,y)=>{
ctx.font = fonts.diagramFont;
ctx.fillStyle = colorPalette.text;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(value, x, y);
};
this.drawD=()=>{
// console.log(allDataDiagram);
for (var i=0; i<=widthD; i++){
//draw bg gradient
ctx.fillRect(proportions.general.middleX/1.6+i, proportions.general.middleY*1.53+heightD, 1, -(allDataDiagram[i]*0.25-2));
ctx.fillStyle=colorPalette.ticks.green.whiteFillColor;
ctx.fillRect(proportions.general.middleX/1.6+i,proportions.general.middleY*1.53,1,4+28-allDataDiagram[i]*0.25);
ctx.fillStyle=colorPalette.ticks.green.greenTickColor;
ctx.fillRect(proportions.general.middleX/1.6+i,proportions.general.middleY*1.53+4+28-allDataDiagram[i]*0.25,1,2);
ctx.fillStyle=gradientD;
}
};
const widthD=186,
heightD=32,
gradientD=ctx.createLinearGradient(0,0,widthD/2,0);
gradientD.addColorStop(0,colorPalette.diagram.bg.gradient[0]);
gradientD.addColorStop(1,colorPalette.diagram.bg.gradient[0]);
//draw grey lines
this.drawLines(proportions.general.middleX/1.6,proportions.general.middleY*1.53,proportions.general.middleX/1.6,proportions.general.middleY*1.53+heightD);
this.drawLines(proportions.general.middleX/1.6+widthD,proportions.general.middleY*1.53,proportions.general.middleX/1.6+widthD,proportions.general.middleY*1.53+heightD);
//write numbers
this.writeNums(94,proportions.general.middleX/1.6, proportions.general.middleY*1.48);
this.writeNums(97,proportions.general.middleX/1.6+widthD, proportions.general.middleY*1.48);
//draw diagram
this.drawD();
//draw circles
this.drawCircles(proportions.general.middleX/1.6,(proportions.general.middleY*1.53)+(32-94*0.25),3);
this.drawCircles(proportions.general.middleX/1.6+widthD,(proportions.general.middleY*1.53)+(32-97*0.25),3);
};
window.onload=Engine;
</script>
</body>
</html>
我想用画布制作速度计动画。但是我需要速度计指针是三角形的,当值改变时,它指向所需的值,但它的底部始终保持在中心。告诉我你需要申请什么公式或算法。代码如下所示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
// general settings
middleX = canvas.width / 2,
middleY = canvas.height / 2,
radius = 240,
counterClockwise = false,
// ticks settings
tickWidth = canvas.width / 100,
// tickColor = "#746845";
tickOffsetFromArc = canvas.width / 40,
// Center circle settings
centerCircleRadius = canvas.width / 20,
centerCircleColor = "#ccc",
centerCircleBorderWidth = canvas.width / 100,
// Arrow settings
arrowValueIndex = .73,
arrowColor = "#464646",
arrowWidth = canvas.width / 50,
// numbers
digits = [0, 20, 40, 50, 60, 70, 80, 90, 100],
digitsColor = "#0a0a0a",
digitsFont = "bold 20px Tahoma",
digitsOffsetFromArc = canvas.width / 15,
//zones
zonesCount = digits.length - 1;
// beginning and ending of our arc. Sets by radius*pi
let startAngleIndex = .75,
endAngleIndex = 2.25,
step = (endAngleIndex - startAngleIndex) / zonesCount;
/*draw zones*/
let DrawZones = function () {
const greyZonesCount = zonesCount / 1.6;
greenZonesCount = zonesCount - greyZonesCount,
startAngle = (startAngleIndex - 0.02) * Math.PI,
endGreyAngle = (startAngleIndex + greyZonesCount * step) * Math.PI,
endGreenAngle = (endAngleIndex + 0.02) * Math.PI,
//zones' options
sectionOptions = [
{
startAngle: startAngle,
endAngle: endGreyAngle,
color: "#e7e7e7",
zoneLineWidth: 2
},
{
startAngle: endGreyAngle,
endAngle: endGreenAngle,
color: "#13b74b",
zoneLineWidth: 5
},
];
this.DrawZone = function (options) {
ctx.beginPath();
ctx.arc(middleX, middleY, radius, options.startAngle, options.endAngle, counterClockwise);
ctx.lineWidth = options.zoneLineWidth;
ctx.strokeStyle = options.color;
ctx.lineCap = "round";
ctx.stroke();
};
sectionOptions.forEach(options => this.DrawZone(options));
};
/*draw dots*/
let DrawTicks = function () {
startAngleIndex = .73,
endAngleIndex = 2.27,
step = (endAngleIndex - startAngleIndex) / zonesCount;
this.DrawTick = function (angle,count) {
let fromX = middleX + (radius - tickOffsetFromArc) * Math.cos(angle),
fromY = middleY + (radius - tickOffsetFromArc) * Math.sin(angle),
toX = middleX + (radius + tickOffsetFromArc) * Math.cos(angle),
toY = middleY + (radius + tickOffsetFromArc) * Math.sin(angle),
centerOfDotX=(fromX+toX)/2,
centerOfDotY=(fromY+toY)/2;
ctx.beginPath();
ctx.arc(centerOfDotX,centerOfDotY,6,0,Math.PI*2,true);
if (count<6){
switch (count) {
case 1:
case 2:
case 3:
ctx.fillStyle="#FF0000";
break;
default:
ctx.fillStyle="#F9AF00";
break;
}
}else{
ctx.fillStyle="#FFF";
ctx.strokeStyle="#13B74B";
ctx.shadowColor = "#a8bbaa";
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
}
ctx.fill();
ctx.closePath();
ctx.shadowBlur =0;
};
let count=0;
for (let i = startAngleIndex; i <= endAngleIndex; i += step) {
let angle = i * Math.PI;
count++;
this.DrawTick(angle,count);
}
};
//draw numbers
let DrawDigits = function () {
let angleIndex = startAngleIndex;
digits.forEach(function (digit) {
let angle = angleIndex * Math.PI,
x = middleX + (radius - digitsOffsetFromArc) * Math.cos(angle),
y = middleY + (radius - digitsOffsetFromArc) * Math.sin(angle);
angleIndex += step;
ctx.font = digitsFont;
ctx.fillStyle = digitsColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(digit, x, y);
});
};
/*draw arrow РИСОВАНИЕ СТРЕЛКИ*/
let DrawArrow = function () {
let arrowAngle = arrowValueIndex * Math.PI;
let toX = middleX + (radius) * Math.cos(arrowAngle)+50;
let toY = middleY + (radius) * Math.sin(arrowAngle)-50;
ctx.beginPath();
ctx.moveTo(middleX, middleY);
ctx.lineTo(toX, toY);
ctx.strokeStyle = arrowColor;
ctx.lineWidth = arrowWidth;
ctx.stroke();
ctx.closePath();
};
window.onload=()=>{
DrawZones();
DrawTicks();
DrawDigits();
DrawArrow();
};
</script>
</body>
</html>
此查询应加载有关其 id 不在另一个表中的路由的数据。相反,这些记录只是重复的。
SELECT tRoutes.ID_Route, tRoutes.sNameOfRoute from tRoutes
INNER JOIN tGroupsRoutes ON tRoutes.ID_Route <> tGroupsRoutes.ID_Route
我正在尝试实现跟踪的消失。方式,但不透明度立即变为0
window.onload = function() {
const loader = document.getElementById('page-preloader');
setInterval(() => loader.style.opacity -= 0.01, 1000);
if (loader.style.opacity==0) clearInterval();
};
样式文件未添加到 dist
包.json
{
"name": "jelly-effect",
"version": "1.0.0",
"description": "Jelly Effect on Canvas",
"main": "index.js",
"scripts": {
"build": "webpack --mode production",
"watch": "webpack-dev-server --mode development --open"
},
"author": "CreativeRusBear",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-3": "^6.24.1",
"css-loader": "^2.1.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"path": "^0.12.7",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"
}
}
webpack.config.js
let path = require('path'),
ExtractTextPlugin = require('extract-text-webpack-plugin');
let conf = {
entry: './src/js/script.js',
output: {
path: path.resolve(__dirname,'./dist/js'),
filename: 'app.js',
publicPath: 'dist/js/'
},
devServer: {
overlay: true
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader'
},{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('css/styles.css'),
]
};
module.exports=(env, options)=>{
let prod = options.mode === 'production';
conf.devtool = prod ? 'source-map' : 'eval-sourcemap';
return conf;
};
最近发现gulp已经完全从版本3切换到了4。我决定试试新版本的新特性,但是调用watch和build任务的时候出现了问题。
给出以下错误:“以下任务未完成您是否忘记发出异步完成信号?”
编码:
var gulp = require('gulp'),
uglify = require('gulp-uglifyjs'),
autoprefixer = require('gulp-autoprefixer'),
del = require('del'),
cssnano = require('gulp-cssnano'),
rename = require('gulp-rename'),
imagemin = require('gulp-imagemin'),
pngquant = require('imagemin-pngquant'),
cache = require('gulp-cache');
//добавление префикса и минифицирование css файла
gulp.task('styles', function() {
return gulp.src('src/css/style.css')
.pipe(autoprefixer(['last 15 versions', '> 1%', 'ie 8', 'ie 7'], {
cascade: true /*для читабельности кода*/
})) //автоматическое добавление префиксов
.pipe(cssnano())
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest('src/css'));
});
/*сжатие js файлов*/
gulp.task('scripts', function() {
return gulp.src('src/js/*.js')
.pipe(uglify())
.pipe(gulp.dest('src/js/min'));
});
//удаление директории
gulp.task('clean', function() {
return del.sync('dist');
});
//очистка кэша
gulp.task('clear-cache', function() {
return cache.clearAll();
});
//сжатие изображений
gulp.task('img', function() {
return gulp.src('src/img/**/*')
.pipe(cache(imagemin({
interlaced: true,
progressive: true,
svgoPlugins: [{
removeViewBox: false
}],
une: [pngquant()]
})))
.pipe(gulp.dest('dist/img'));
});
gulp.task('watch', function() {
gulp.watch('src/css/style.css', gulp.parallel('styles'));
gulp.watch('src/js/*.js', gulp.parallel('scripts'));
});
gulp.task('build', gulp.series('clean', 'img', 'styles', 'scripts'), function() {
var buildCss = gulp.src(['src/css/style.min.css'])
.pipe(gulp.dest('dist/css'));
var buildJs = gulp.src('src/js/min/*.js')
.pipe(gulp.dest('dist/js'));
var buildHtml = gulp.src('src/*.html')
.pipe(gulp.dest('dist'));
var buildHtmlPages = gulp.src('src/pages/*.html')
.pipe(gulp.dest('dist/pages'));
var buildAudio = gulp.src('src/audio/**/*')
.pipe(gulp.dest('dist/audio'));
});
gulp.task('default', gulp.parallel('watch','styles ','scripts'));
有一个添加新组的表格(截图附在下面)。当您单击保存按钮时,此记录将保存到 tGroup 表中(成功)。保存后,应该从tGroup中取出这个组的id(主键),并转移到另一个表中(这就是sql查询出错的地方)。
void LoadIdGroup(string name)
{
adapter = new SqlDataAdapter("SELECT ID_Group from tGroups where sName="+name, connection);
dtGroup = new DataTable();
adapter.Fill(dtGroup);
bsGroup = new BindingSource();
bsGroup.DataSource = dtGroup;
}
private void saveBtn_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand commandInsert = new SqlCommand("INSERT INTO [tGroups]" +
" VALUES(@Name, @Count)", connection);
commandInsert.Parameters.AddWithValue("@Name", tbName.Text);
commandInsert.Parameters.AddWithValue("@Count", tbCount.Text);
commandInsert.ExecuteNonQuery();
connection.Close();
connection.Open();
SqlCommand commandInsertRoutes = new SqlCommand("INSERT INTO [tGroupsRoutes]" +
" VALUES (@ID_Group, @ID_Route)", connection);
commandInsertRoutes.Parameters.AddWithValue("@ID_Route", Convert.ToInt32(cbRoutes.SelectedValue));
LoadIdGroup(tbName.Text);
commandInsertRoutes.Parameters.AddWithValue("@ID_Group", Convert.ToInt32(((DataRowView)this.bsGroup.Current).Row["ID_Group"]));
commandInsertRoutes.ExecuteNonQuery();
connection.Close();
this.Dispose();
}
adapter = new SqlDataAdapter("SELECT tRoutesPuncts.ID_Punct, tPuncts.sPunct FROM dbo.tRoutesPuncts INNER JOIN tRoutes ON dbo.tRoutesPuncts.ID_Route = dbo.tRoutes.ID_Route" +
" inner join tPuncts ON dbo.tRoutesPuncts.ID_Punct = dbo.tPuncts.ID_Punct WHERE tRoutesPuncts.ID_Route=" + id.Text, connection);
dtForAddPuncts = new DataTable();
adapter.Fill(dtForAddPuncts);
bsForAddPuncts= new BindingSource();
bsForAddPuncts.DataSource = dtForAddPuncts;
cbAddPuncts.DataSource = bsForAddPuncts;
cbAddPuncts.ValueMember = "ID_Punct";
cbAddPuncts.DisplayMember = "sPunct";
}
错误出现在这里:“adapter.Fill(dtForAddPuncts);”
调用Input方法时,出现“对象引用不指向对象的实例”的错误,它引用了一个数组。带有错误的代码和屏幕截图如下所示。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarAndBus
{
class tCar
{
public double x { get; set; }
public double y { get; set; }
public double r { get; set; }
public tCar(double x, double y)
{
this.x = x;
this.y = y;
//Output();
}
public virtual void Move(double ed, double a)
{
this.r = a * Math.PI / 180;
this.x = this.x + ed * Math.Cos(r);
this.y = this.y + ed * Math.Sin(r);
Output();
}
public virtual void Output()
{
Console.WriteLine($"x= {this.x,2:f2} y= {this.y,2:f2}");
}
}
class tBus : tCar
{
public string[] passengers { get; set; }
public double money { get; set; }
public double moneyPassengers { get; set; }
public int capacity { get; set; }
public tBus(double x, double y, int capacity) : base(x,y)
{
this.money = 0;
this.capacity = capacity;
string[] passengers = { };
}
public override void Move(double ed, double a)
{
this.r = a * Math.PI / 180;
this.x = this.x + ed * Math.Cos(r);
this.y = this.y + ed * Math.Sin(r);
for (int i=0; i<this.passengers.Length; i++)
{
switch (this.passengers[i])
{
case "обычный":
this.money+= 2*ed;
break;
case "студент":
this.money= 1.25*ed;
break;
}
}
this.Output();
}
public override void Output()
{
Console.WriteLine($"x= {this.x,2:f2} y= {this.y,2:f2}\nКол-во пассажиров: {this.passengers.Length}\nКол-во полученных денег: {this.money,6:f2}\nВместимость автобуса: {this.capacity}");
}
public void Input(int people)
{
if (this.passengers.Length + people <= this.capacity)
{
for (int i = 0; i < people; i++)
{
Console.Write($"Выберите тип {i + 1}-го вошедшего пассажира: 1-обычный 2-студент ");
int type = Convert.ToInt32(Console.ReadLine());
int countOfArr = this.passengers.Length;
switch (type)
{
case 1:
this.passengers[countOfArr] = "обычный";
break;
case 2:
this.passengers[countOfArr] = "студент";
break;
}
}
this.Output();
}
else
{
Console.Write("Недостаточно мест в автобусе");
}
}
public void Exit(int passengers)
{
if (this.passengers.Length - passengers > 0)
{
for (int i = 0; i < passengers; i++)
{
int []indexes = { this.passengers.Length - i };
this.passengers = (from x in this.passengers where !(from y in indexes select this.passengers.ElementAt(y)).Contains(x) select x).ToArray();
}
this.Output();
}else
{
Console.Write("Количество человек в автобусе меньше, чем то значение, которое вы передаете в параметре");
}
}
}
class Program
{
static void Main(string[] args)
{
tBus Bus = new tBus(0, 0, 50);
Bus.Input(2);
Bus.Move(20, 45);
Bus.Exit(3);
Bus.Exit(1);
Bus.Move(20, 135);
Bus.Move(20, 225);
Bus.Move(20, 315);
Console.ReadKey();
}
}
}