外文翻译 | 你以为你会用Math.random() ? 不,你不会……
文章目录
- 制造动画效果
- HTML
- CSS
- JavaScript
- 电子音乐
- HTML
- SCSS
- CoffeeScript
- 随机显示图片
- HTML
- CSS
- JavaScript
- 随机背景颜色
- Pug
- SCSS
- Babel
- 艺术效果
- HTML
- CSS
- JavaScript
- 文字效果
- Slim
- Sass
- JavaScript
- API密钥生成器
- HTML
- CSS
- JavaScript
- 打乱文本
- HTML
- Stylus
- Babel
- 石头剪刀布
- HTML
- SCSS
- JavaScript
- 密码生成器
- HTML
- SCSS
- JavaScript
- 值得关注的事情
- Math.random()真的是随机的吗?
- 如何处理重复值?
- Math.random()与WebCrypto相同吗?
原文来源:https://css-tricks.com/lots-of-ways-to-use-math-random-in-javascript/
Math.random()
是JavaScript中的一个API。能够为您提供一个随机数的功能。 返回的数字将介于0(包括0)和1(不包括1)之间。
Math.random()//返回一个小于1的随机数(不包含1)
Math.random()
函数对于游戏,动画,随机数据,艺术效果,随机文本生成等许多方面非常有用! 它可以用于Web开发,移动应用程序,计算机程序和视频游戏。
每当我们在工作中需要使用随机数据时,就可以使用此功能! 让我们看一下我们使用它的八种不同方式。 这些示例均来自不同的作者,利用这一API进行了一些有趣的创作。
制造动画效果
HTML
<canvas id=c></canvas>
CSS
canvas { position: absolute;top: 0;left: 0;
}
JavaScript
var w = c.width = window.innerWidth,h = c.height = window.innerHeight,ctx = c.getContext( '2d' ), opts = { len: 20,count: 50,baseTime: 10,addedTime: 10,dieChance: .05,spawnChance: 1,sparkChance: .1,sparkDist: 10,sparkSize: 2, color: 'hsl(hue,100%,light%)',baseLight: 50,addedLight: 10, // [50-10,50+10]shadowToTimePropMult: 6,baseLightInputMultiplier: .01,addedLightInputMultiplier: .02, cx: w / 2,cy: h / 2,repaintAlpha: .04,hueChange: .1},tick = 0,lines = [],dieX = w / 2 / opts.len,dieY = h / 2 / opts.len, baseRad = Math.PI * 2 / 6;ctx.fillStyle = 'black';
ctx.fillRect( 0, 0, w, h );function loop() {window.requestAnimationFrame( loop );++tick;ctx.globalCompositeOperation = 'source-over';ctx.shadowBlur = 0;ctx.fillStyle = 'rgba(0,0,0,alp)'.replace( 'alp', opts.repaintAlpha );ctx.fillRect( 0, 0, w, h );ctx.globalCompositeOperation = 'lighter';if( lines.length < opts.count && Math.random() < opts.spawnChance )lines.push( new Line );lines.map( function( line ){ line.step(); } );
}
function Line(){this.reset();
}
Line.prototype.reset = function(){this.x = 0;this.y = 0;this.addedX = 0;this.addedY = 0;this.rad = 0;this.lightInputMultiplier = opts.baseLightInputMultiplier + opts.addedLightInputMultiplier * Math.random();this.color = opts.color.replace( 'hue', tick * opts.hueChange );this.cumulativeTime = 0;this.beginPhase();
}
Line.prototype.beginPhase = function(){this.x += this.addedX;this.y += this.addedY;this.time = 0;this.targetTime = ( opts.baseTime + opts.addedTime * Math.random() ) |0;this.rad += baseRad * ( Math.random() < .5 ? 1 : -1 );this.addedX = Math.cos( this.rad );this.addedY = Math.sin( this.rad );if( Math.random() < opts.dieChance || this.x > dieX || this.x < -dieX || this.y > dieY || this.y < -dieY )this.reset();
}
Line.prototype.step = function(){++this.time;++this.cumulativeTime;if( this.time >= this.targetTime )this.beginPhase();var prop = this.time / this.targetTime,wave = Math.sin( prop * Math.PI / 2 ),x = this.addedX * wave,y = this.addedY * wave;ctx.shadowBlur = prop * opts.shadowToTimePropMult;ctx.fillStyle = ctx.shadowColor = this.color.replace( 'light', opts.baseLight + opts.addedLight * Math.sin( this.cumulativeTime * this.lightInputMultiplier ) );ctx.fillRect( opts.cx + ( this.x + x ) * opts.len, opts.cy + ( this.y + y ) * opts.len, 2, 2 );if( Math.random() < opts.sparkChance )ctx.fillRect( opts.cx + ( this.x + x ) * opts.len + Math.random() * opts.sparkDist * ( Math.random() < .5 ? 1 : -1 ) - opts.sparkSize / 2, opts.cy + ( this.y + y ) * opts.len + Math.random() * opts.sparkDist * ( Math.random() < .5 ? 1 : -1 ) - opts.sparkSize / 2, opts.sparkSize, opts.sparkSize )
}
loop();window.addEventListener( 'resize', function(){ w = c.width = window.innerWidth;h = c.height = window.innerHeight;ctx.fillStyle = 'black';ctx.fillRect( 0, 0, w, h );opts.cx = w / 2;opts.cy = h / 2;dieX = w / 2 / opts.len;dieY = h / 2 / opts.len;
});
生成一个对象并使其动画化,我们使用Math.random
。霓虹灯线形成自发的六边形,同时利用随机化产生火花效果。
电子音乐
HTML
<header><h1>Random Music</h1><p>Using the characteristics of <em>Auld Lang Syne</em></p>
</header>
<section id="staff">
</section>
<div class="triggers"><a id="play"><span class="play"></span><span class="stop"></span></a><a id="new">New Song</a>
</div>
SCSS
import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300italic|Inconsolata);
$c-primary: #545454;
$c-dark: darken($c-primary,10%);
$c-black: darken($c-dark,20%);
$c-med: lighten($c-primary,10%);
$c-gray: #c0c0c0;
$c-light: #f0f0f0;
$c-white: #ffffff;
$c-off-white: transparentize($c-white, 0.8);
$c-barely-white: transparentize($c-white, 0.9);$clef_h: 100px;
#staff {height: $clef_h * 2;width: 95%;margin: 4em auto;position: relative;.clef {height: $clef_h;width: 100%;position: relative;margin-bottom: 24px;.beat {display: block;position: absolute;top: 0; bottom: 0; transition: background 200ms;&.sus {z-index: 1;}&.chord {z-index: 2;font-size: 10px;$note-di: 4px;.note {transition: transform 500ms, background 100ms;position: absolute;left: 50%;transform: translate3d(-50%, -50%, 0) scale(1);background-color: $c-white;width: $note-di;height: $note-di;border-radius: 50%;@for $i from 0 through 36 {&.note-#{$i} {$ratio: $i / 36;top: $ratio * 100%;background-color: hsl($ratio * 360, 50%, 40%); }}}}&.active {transition-duration: 50ms;
/* background: $c-barely-white; */z-index: 9;.note {transform: translate3d(-50%, -50%, 0) scale(2);@for $i from 0 through 36 {&.note-#{$i} {$ratio: $i / 36;background-color: hsl($ratio * 360, 100%, 60%); }} }}}}
}.triggers {width: 100%;text-align: center;$button-di: 40px;a {color: $c-white;font-weight: 100;cursor: pointer;display: block;margin: 0 auto;text-transform: uppercase;opacity: 0.8;width: 100px;transition: opacity 200ms;font-size: 2em;&.inactive {opacity: 0.3; pointer-events: none; }&:hover, &:active {opacity: 1;}&#play { width: $button-di;height: $button-di;line-height: $button-di;border-radius: 50%;background-color: $c-off-white;margin-bottom: 12px;position: relative;.play, .stop {display: block;position: absolute;top: 50%;left: 50%;}.play { border-left: 8px solid $c-white;border-top: 8px solid transparent;border-bottom: 8px solid transparent;transform: translate3d(-40%, -50%, 0);} .stop {background-color: $c-white;height: 10px;width: 10px;transform: translate3d(-50%, -50%, 0);display: none;} &.playing {.play { display: none;} .stop { display: block;}}}&#new {font-size: 0.875em;}}
}body {background-color: $c-black;font-family: 'Source Sans Pro';font-weight: 300;color: $c-white;header, article, #staff {transition: opacity 300ms;}#staff {opacity: 0.5;}&.playing {header, article {opacity: 0.4;}#staff {opacity: 1;}}
}
pre {font-family: 'Inconsolata';font-size: 0.9em;background-color: $c-barely-white;box-sizing: border-box;padding: 12px;em {font-style: normal;color: darken($c-white,70%);}
}
code {font-family: 'Inconsolata';font-size: 0.9em;padding: 6px;white-space: nowrap;background-color: $c-off-white;
}
h1, h2, h3 {font-weight: 300;text-transform: uppercase;letter-spacing: 0.125em;
}
h1 {margin-bottom: 0.25em;
}
h1 { font-size: 1.4em; }
h2 { font-size: 1.1em; }
h3 { font-size: 0.9em; }
h1, h2 {text-align: center;
}header {text-align: center; margin-top: 4em;h1, p {margin: 0;}p {margin-top: 0.5em;color: $c-light;}
}article {width: 90%;max-width: 600px;margin: 8em auto;line-height: 1.8;text-align: justify;text-justify: inter-word;h1,h2 {margin-top: 1em;}h1, h2, h3 {margin-bottom: 0;& + p {margin-top: 0;}}a {color: $c-white;}
}
CoffeeScript
###
///
random music generator
jake albaugh
///
###
###
# globals
###
# generate a package of chances and values based on an object containing multiple possible zero values
ChancePkg = (vals) -># generating vals and their chances of occuringnew_vals = []# get total number of vals vals_count = 0for value of valsif vals.hasOwnProperty(value) && vals[value] > 0vals_count += vals[value]new_vals.push [value, vals[value]]# go through new vals and generate chance for each valuenew_vals_chances = [] total = 0 for val, i in new_vals# relative amount for random selection amount = total + ( (val[1] / vals_count ) * 100000)# push amount into chances array new_vals_chances.push amount # set value to be the value, no longer an array of data new_vals[i] = parseInt(val[0])# increase base total total = amount # return package which has array for both non-zero vals and their corrosponding chancereturn {chances: new_vals_chances, vals: new_vals}# get the sound to silence ratio at the smallest scale
getSoundRatio = (measures, beats, values) -># generating vals and their chances of occuringnew_values = []# get total number of vals values_count = 0for value of valuesif values.hasOwnProperty(value) && values[value] > 0values_count += values[value]new_values.push [value, values[value]] # resolution is the smallest sized note resolution = (beats * (new_values[new_values.length - 1][1] / 4))# possible is how many resolution sized notes are in the piece possible = measures * (beats * (resolution / 4))# usage to be used in the loop usage = 0 for value in new_values# how many resolution values are in a single value? (ie. how many sixteenth notes are in a quarter note) res_value = (1 / value[0]) * resolution# use resolution value * occurances usage += res_value * value[1] return usage / possible# generate clef values based on data
Piece = (piece) ->{measures, beats, treble_clef, bass_clef, composition} = piecethis.treble_clef = {# sound ratio is the presence of sound divided by the presenece of silence in the analyzed piece sound_ratio: getSoundRatio(measures, beats, treble_clef.values)# value package has array for both non-zero values and their corrosponding chancevalues_pkg: new ChancePkg(treble_clef.values)# interval package has array for both non-zero intervals and their corrosponding chanceintervals_pkg: new ChancePkg(treble_clef.intervals)# octaves package has array for both non-zero octaves and their corrosponding chanceoctaves_pkg: new ChancePkg(treble_clef.octaves)# chords package has array for both non-zero chords and their corrosponding chancechords_pkg: new ChancePkg(treble_clef.chords)# setting the base octavebase_octave: 5# tonewave: 'sine'# gaingain: 0.3}this.bass_clef = {# sound ratio is the presence of sound divided by the presenece of silence in the analyzed piece sound_ratio: getSoundRatio(measures, beats, bass_clef.values)# value package has array for both non-zero values and their corrosponding chancevalues_pkg: new ChancePkg(bass_clef.values)# interval package has array for both non-zero intervals and their corrosponding chanceintervals_pkg: new ChancePkg(bass_clef.intervals)# octaves package has array for both non-zero octaves and their corrosponding chanceoctaves_pkg: new ChancePkg(bass_clef.octaves)# chords package has array for both non-zero chords and their corrosponding chancechords_pkg: new ChancePkg(bass_clef.chords)# setting the base octavebase_octave: 3# tonewave: 'sine'# gaingain: 0.3}this.composition = compositionreturn# initiate audio context
audio_context = undefined
(init = (g) ->try# "crossbrowser" audio context.audio_context = new (g.AudioContext or g.webkitAudioContext)catch econsole.log "No web audio oscillator support in this browser"return
) window# oscillator prototype
Oscillator = (tone) ->max_gain = tone.gainthis.tone = tonethis.play = () -># capturing current time for play start and stopcurrent_time = audio_context.currentTime# create oscillator o = audio_context.createOscillator()# create gain gn = audio_context.createGain() # set waveform o.type = this.tone.wave# set frequency if this.tone.frequencyo.frequency.value = this.tone.frequency# connect oscillator to gain o.connect gn# connect gain to outputgn.connect audio_context.destination# set gain amountgn.gain.value = (max_gain / this.tone.vol) / 1# play it o.start(current_time)# stop after sustain o.stop(current_time + this.tone.sustain)return this# note frequencies array of octave arrays that start on c (our root note)
freqs = [[16.351, 17.324, 18.354, 19.445, 20.601, 21.827, 23.124, 24.499, 25.956, 27.5, 29.135, 30.868][32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55, 58.27, 61.735][65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110, 116.541, 123.471][130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220, 233.082, 246.942][261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 466.164, 493.883][523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880, 932.328, 987.767][1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760, 1864.655, 1975.533][2093.005, 2217.461, 2349.318, 2489.016, 2637.021, 2793.826, 2959.955, 3135.964, 3322.438, 3520, 3729.31, 3951.066][4186.009, 4434.922, 4698.636, 4978.032, 5274.042, 5587.652, 5919.91, 6271.928, 6644.876, 7040, 7458.62, 7902.132][8372.018, 8869.844, 9397.272, 9956.064, 10548.084, 11175.304, 11839.82, 12543.856, 13289.752, 14080, 14917.24, 15804.264]
]# get random val from chance package
randomVal = (chance_pkg) ->random = Math.random() * 100000for chance, i in chance_pkg.chancesreturn chance_pkg.vals[i] if random < chancereturn# get sequence function
getSequence = (clef, composition) -># get the duration in smallest resolution amountduration = composition.measures * (composition.beats * (composition.resolution / 4)) # note sequencesequence = []# while there is still durationwhile duration > 0# random hitrandom = Math.random()# if a hit if random < clef.sound_ratio # random chord note countchord = randomVal(clef.chords_pkg)# random length for the chord value = randomVal(clef.values_pkg)# if there isnt enough spaceif ((1 / value) / (1 / composition.resolution)) >= duration# make it the length of remaining value = ((1 / duration) / (1 / composition.resolution))# the new chordnew_chord = {length: (1 / value), notes: []}# for each note in the chord for note in [1..chord]# get a random intervalinterval = randomVal(clef.intervals_pkg)# get the random octave octave = randomVal(clef.octaves_pkg)# make intervale relative to keyinterval += composition.root# if key pushes interval into new octaveif interval > 12interval -= 12# make the octave relative to the clef's octavenew_octave = clef.base_octave + ((2 - octave) * -1)# the frequency of the notenote = freqs[new_octave - 1][interval]# if note doesnt already exist in chordif new_chord.notes.indexOf(note) == -1# push the frequency into the chord's notes new_chord.notes.push {freq: note, int: interval, octave: octave}else# duplicate note in chord, ignoring it for now.console.log 'duplicate note in chord, ignoring it for now.'# push the chord into the sequence sequence.push new_chord# get values resolution-relative value res_value = Math.floor((1 / value) / (1 / composition.resolution))# if we need to add sustain notes if res_value > 1# add blank values for blank in [1..res_value - 1] sequence.push 'sus'# subtract from the duration duration -= res_valueelse# it was a miss, add a zero to the sequencesequence.push 0# subtract tick from duration duration--return sequence
Note = (tone) ->this.osc = () ->return new Oscillator(tone)returns
###
# data (to be derived from an analyzed piece of music)
###piece = {# piece data (auld lang syne)measures: 16 # measures in analyzed piecebeats: 4 # beats per measure in analyzed piece# all our analysis will be relative to each cleftreble_clef: { # note values are the duration of the note / chord. # this is a map of how many times each value appears in the analyzed datavalues: {1: 0 # whole1.5: 4 # dotted half2: 5 # half3: 12 # dotted quarter4: 28 # quarter6: 0 # dotted eighth8: 12 # eighth12: 0 # dotted sixteenth16: 0 # sixteenth32: 0 # thirty-second}# relative to the key, the intervals are steps between notes and the root (no octaves)# this includes all single notes and instances of a note in a chord# this is a map of how many times each interval appears in the analyzed dataintervals: {0: 32 # root / perfect unison (F)1: 0 # minor second (F#)2: 9 # major second (G)3: 0 # minor third (G#)4: 13 # major third (A)5: 0 # perfect fourth (A#)6: 6 # tritone (B)7: 13 # perfect fifth (C)8: 0 # minor sixth (C#)9: 15 # major sixth (D)10: 0 # minor seventh (D#)11: 12 # major seventh (E)}# octaves are how many times a note appears in each octave (relative to the key)octaves: {1: 37 # clef - 12: 67 # clef3: 1 # clef + 1}# instead of using proper chords (dyad, triad, 7th, 9th, and 11th), we only analyze how many notes are in the chord# this is a map of how many times each chord size appears in the analyzed datachords: {1: 9 # 1 note2: 47 # 2 notes3: 0 # 3 notes4: 0 # 4 notes5: 0 # 5 notes}}bass_clef: { # note values are the duration of the note / chord. # this is a map of how many times each value appears in the analyzed datavalues: {1: 0 # whole1.5: 4 # dotted half2: 5 # half3: 12 # dotted quarter4: 28 # quarter6: 0 # dotted eighth8: 12 # eighth12: 0 # dotted sixteenth16: 0 # sixteenth32: 0 # thirty-second}# relative to the key, the intervals are steps between notes and the root (no octaves)# this includes all single notes and instances of a note in a chord# this is a map of how many times each interval appears in the analyzed dataintervals: {0: 25 # root / perfect unison (F)1: 0 # minor second (F#)2: 1 # major second (G)3: 0 # minor third (G#)4: 17 # major third (A)5: 2 # perfect fourth (A#)6: 0 # tritone (B)7: 38 # perfect fifth (C)8: 1 # minor sixth (C#)9: 4 # major sixth (D)10: 0 # minor seventh (D#)11: 2 # major seventh (E)}# octaves are how many times a note appears in each octave (relative to the key)octaves: {1: 2 # clef - 12: 53 # clef3: 50 # clef + 1}# instead of using proper chords (dyad, triad, 7th, 9th, and 11th), we only analyze how many notes are in the chord# this is a map of how many times each chord size appears in the analyzed datachords: {1: 9 # 1 note2: 46 # 2 notes3: 0 # 3 notes4: 0 # 4 notes5: 0 # 5 notes}}# defining the desired output composition datacomposition: {measures: 32 # bars to generatebeats: 4 # beats per measuretempo: 120 # temporesolution: 16 # resolution scale of piece root: 5 # root of key (0-11), 0 is 'C'}
}# lets analyze our piece data!
p = new Piece(piece)# sequence stores
trebleSequence = undefined
bassSequence = undefined
# get sequences
getSequences = () -># creating our treble cleftrebleSequence = getSequence(p.treble_clef, p.composition)bassSequence = getSequence(p.bass_clef, p.composition)draw_sequences()getSequenceHtml = (name, composition, sequence) ->$seq_html = $('<div class="' + name + ' clef"></div>')beats = composition.measures * (composition.beats * (composition.resolution / 4)) width_increment = 1 / beats * 100left = 0 for chord in sequenceif typeof chord == "object" width = width_increment * (chord.length / (1 / composition.resolution)) width = width_incrementclassname = 'chord value-' + Math.round( (1 / chord.length) * 100) / 100classname = classname.replace('.', '-')notes = '' for note in chord.notesout_of_36 = 36 - (note.int + ((note.octave - 1) * 12))notes += '<span class="note note-' + out_of_36 + '"></span>'else if chord == 'sus' classname = 'sus'width = width_incrementnotes = '' elsewidth = width_increment classname = 'blank'notes = ''$seq_html.append '<span class="beat ' + classname + '" style="width: ' + width + '%; left: ' + left + '%">' + notes + '</span>'left += widthreturn $seq_htmldraw_sequences = () ->composition = p.composition$staffs = $('<div class="staffs-wrapper"></div>')$staffs.append getSequenceHtml('treble', composition, trebleSequence)$staffs.append getSequenceHtml('bass', composition, bassSequence)$('#staff').html $staffsreturnperformance_interval = undefined# play sequences
playSequences = () ->composition = p.compositionsequences = [trebleSequence, bassSequence]waves = [p.treble_clef.wave, p.bass_clef.wave]gains = [p.treble_clef.gain, p.bass_clef.gain]# total beat countbeats = composition.measures * (composition.beats * (composition.resolution / 4))# css width of beat beat_width = 100 / beats# relative index index = 0# tempo to ms tempo_time = 60000 / composition.tempo # single beat instancenext_beat = () ->for sequence, i in sequenceschord = sequence[index]# if beat in any rhythm array has value if typeof chord == "object"# beats per secondbps = composition.tempo / 60# how much of a beat is the length beat_count = chord.length / 0.25# sustain of the note in secondschord_length_secs = beat_count * bps / 2sustain = (chord_length_secs / bps) - 0.1for note in chord.notes# new noten = new Note({frequency: note.freq, sustain: sustain, wave: waves[i], gain: gains[i], vol: chord.notes.length})# new oscillatoro = n.osc()# play oscillator o.play()if i == 0 then clef = 'treble' else clef = 'bass'if typeof chord == "object" $('.' + clef + ' .beat.active').removeClass 'active'$('.' + clef + ' .beat.go').removeClass clef + '-go'$('.' + clef + ' .beat:nth-child(' + (index + 1) + ')').addClass clef + '-go'else if chord != 'sus' $('.' + clef + ' .beat.active').removeClass 'active'$('.' + clef + ' .beat.go').removeClass clef + '-go'$('.beat:nth-child(' + (index + 1) + ')').addClass 'active'# update index index = (index + 1) % beats# first call of next beatnext_beat()# ms to relative speed (based on resolution) time = tempo_time / (composition.resolution / 4)# set interval for next beat to occur at approriate timeperformance_interval = window.setInterval(next_beat, time)# stop button
stopSequences = () ->window.clearInterval(performance_interval)# get sequences
getSequences()playing = false
play_handler = (p) ->if p == true playSequences()else stopSequences()playing = p $('#play').click () ->$(this).toggleClass 'playing'$('body').toggleClass 'playing'$('#new').toggleClass 'inactive'play_handler(!playing)$('#new').click () ->getSequences()
该程序采用传统的“ Auld Lang Syne”旋律,并在钢琴中弹奏随机音符。 根据计数数据创建一个更改包,并生成一个随机数来选择一个值。 八度音阶也是随机选择的。
随机显示图片
HTML
<html><head><title>Random Picture Generator</title><link rel="stylesheet" href="assets/stylesheets/app.css"></head><body><header class="flex"><h1>Random Picture Generator</h1><button>Generate Random Picture</button></header><section class="flex"><img src=""></section><script src="assets/scripts/app.js"></script></body>
</html>
CSS
html, body {margin: 0;height: 100%;width: 100%;
}header {width: 100%;padding-bottom: 25px;flex-direction: column;
}img {width: 70%;
}.flex {display: flex;justify-content: center;align-items: center;
}
JavaScript
const imageArray = ["https://images.unsplash.com/photo-1508185159346-bb1c5e93ebb4?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=55cf14db6ed80a0410e229368963e9d8&auto=format&fit=crop&w=1900&q=80","https://images.unsplash.com/photo-1495480393121-409eb65c7fbe?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=05ea43dbe96aba57d48b792c93752068&auto=format&fit=crop&w=1351&q=80","https://images.unsplash.com/photo-1501611724492-c09bebdba1ac?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ebdb0480ffed49bd075fd85c54dd3317&auto=format&fit=crop&w=1491&q=80","https://images.unsplash.com/photo-1417106338293-88a3c25ea0be?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=d1565ecb73a2b38784db60c3b68ab3b8&auto=format&fit=crop&w=1352&q=80","https://images.unsplash.com/photo-1500520198921-6d4704f98092?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ac4bc726064d0be43ba92476ccae1a75&auto=format&fit=crop&w=1225&q=80","https://images.unsplash.com/photo-1504966981333-1ac8809be1ca?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=9a1325446cbf9b56f6ee549623a50696&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1437075130536-230e17c888b5?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ff573beba18e5bf45eb0cccaa2c862b3&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1515002246390-7bf7e8f87b54?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=1eac0f70640261e09152340f13b79144&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1506057278219-795838d4c2dd?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=f68d8d7b0223cd906ea8cac13421881d&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1488402410361-05152fa654d3?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=5266aadc96d5b5b23996e7120d3190a8&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1475598322381-f1b499717dda?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=cb49f991ce8dd947b45ccd1bd905ec8c&auto=format&fit=crop&w=1355&q=80","https://images.unsplash.com/photo-1501949997128-2fdb9f6428f1?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=951ee200e732c9b8c4ea0a7372ca9d27&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1494783367193-149034c05e8f?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=a98c0f9a6c602e964e6533de413d59ba&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1476547362848-ed2a9f99cd29?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=5b4647c9e25267c25866936c916e4aa8&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1506017669510-0bcbe8003d70?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=9403f5d4ac23a5726bfc3c8308b31c01&auto=format&fit=crop&w=1350&q=80","https://images.unsplash.com/photo-1489447068241-b3490214e879?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=a85cb0d68de38ae2aa00d8a9663a320a&auto=format&fit=crop&w=1350&q=80"
];
const image = document.querySelector("img");
const button = document.querySelector("button");
window.onload = () => generateRandomPicture(imageArray);
button.addEventListener("click", () => generateRandomPicture(imageArray));function generateRandomPicture(array){let randomNum = Math.floor(Math.random() * array.length); image.setAttribute("src", array[randomNum]);
}
图像存储在一个数组中。通过array.length
生成一个数字并乘以数组中的图像数量。然后,将Math.floor
将值四舍五入为整数,并在加载页面或单击按钮时在HTML中设置图像src
。
随机背景颜色
Pug
#app.wrap.bg.colors()button.refresh(v-on:click="newColors").<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" viewBox="0 0 23 23" version="1.1" x="0px" y="0px"><path d="M 12.109896,2.9653518 C 10.830826,2.9134678 9.5257058,3.132602 8.2817758,3.648946 c -3.9806,1.652399 -6.2540499,5.897846 -5.4179699,10.123046 0.8360799,4.2253 4.5540699,7.274132 8.8613301,7.269532 a 0.9995584,1.0006417 14.999899 1 0 0,-2 c -3.3667302,0 -6.2475202,-2.360557 -6.9004002,-5.660157 -0.65294,-3.2997 1.11025,-6.592765 4.22266,-7.884765 3.1124002,-1.292 6.6825102,-0.213669 8.5488302,2.582031 1.85391,2.77709 1.49946,6.460477 -0.8418,8.845703 l 0.0781,-2.365234 a 1.0001,1.0001 0 0 0 -0.98242,-1.046875 1.0001,1.0001 0 0 0 -1.01758,0.982422 l -0.15235,4.59375 a 1.0001,1.0001 0 0 0 1.03321,1.033203 l 4.5957,-0.152344 a 1.0001,1.0001 0 1 0 -0.0664,-1.998047 l -1.79492,0.06055 c 2.74739,-3.056097 3.10892,-7.618693 0.80859,-11.064453 -1.64326,-2.461525 -4.33252,-3.887808 -7.14648,-4.0019532 z"/></svg>button.expand(v-on:click="newColors").<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23" x="0px" y="0px"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}</style></defs><polyline class="cls-1" points="18.5 14.5 21.5 11.5 18.5 8.5"/><polyline class="cls-1" points="4.5 8.5 1.5 11.5 4.5 14.5"/><line class="cls-1" x1="1.5" y1="11.5" x2="8.5" y2="11.5"/><line class="cls-1" x1="14.5" y1="11.5" x2="21.5" y2="11.5"/></svg>color(v-for="(c, i) in colors", v-bind:name="names[i]" v-bind:color="c")a.fulllink(href="https://farbvelo.elastiq.ch/", target="_blank")strongspan Fspan uspan lspan l spanspan Vspan espan rspan sspan ispan ospan n
SCSS
@import url('https://fonts.googleapis.com/css?family=Space+Mono');button {border: none;margin: 0;padding: 0;width: auto;overflow: visible;background: transparent;/* inherit font & color from ancestor */color: inherit;font: inherit;/* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */line-height: normal;/* Corrects font smoothing for webkit */-webkit-font-smoothing: inherit;-moz-osx-font-smoothing: inherit;/* Corrects inability to style clickable `input` types in iOS */-webkit-appearance: none;
}html {font-size: calc(.75rem + 1.15vh);font-family: 'Space Mono', monospace;
}body {height: 100vh;background: #212121;overflow: hidden;
}input {position: absolute;z-index: 2;
}.wrap, .bg {position: absolute;top: 0; left: 0; bottom: 0; right: 0;
}.bg {//opacity: .9;//clip-path: inset(12vmin 26% 12vmin 26%);
}.colors {position: absolute;left: 50%;bottom: 10vmin; top: 10vmin;display: flex;flex-direction: column;cursor: pointer;transform: translateX(-50%);width: 52%;@media (max-width: 700px){width: 75%;}
}.colors .color {position: relative;display: flex;@media (max-width: 700px){display: block;padding: 1rem;}align-items: center;padding: 0 1rem;flex-grow: 1;&::after {opacity: .5;content: '';position: absolute;left: 0; right: 0; bottom: 0; top: 0;box-shadow: 0 0 10rem currentColor;}/*border: solid currentColor;border-width: 0 2px;*/transition: 200ms color linear, 200ms background-color linear, 300ms padding-bottom cubic-bezier(.7, .3, .3, 1) 100ms;min-height: 0.1vmax;&:last-child {padding-bottom: #{1.61803 * 4rem};}&:hover {padding-bottom: #{1.61803 * 4rem};}
}.colors:hover .color {&:last-child {padding-bottom: 1rem;}&:hover {padding-bottom: #{1.61803 * 4rem};}
}.label {flex-grow: 1;padding-right: 1rem;font-size: .75em;@media (max-width: 700px) { font-size: .6em;margin-bottom: .15em;}
}
.name {font-size: .8em;text-align: right;@media (max-width: 700px){text-align: left;}
}
.refresh, .expand {z-index: 1;position: absolute;top: 100%; left: 100%;margin: 0;padding: 0;transform: translate(-60%,-60%);font-size: 2em;width: 1.2em; height: 1.2em;background: #000;color: #fff;border-radius: 50%;outline: 0;box-shadow: 0 0 2rem rgba(#000, .2);cursor: pointer;svg {position: absolute;top: 50%; left: 50%;transform: translate(-50%,-50%);animation-name: rotate; animation-duration: 3s; width: .6em; height: .6em;animation-iteration-count: infinite;animation-timing-function: linear;animation-play-state: paused;line-height: 1;fill: #fff;}&:hover {svg {animation-play-state: running;}}
}.expand {display: none;margin-left: -1.4em;svg {fill: none;stroke: #fff;stroke-width: 1.5;animation: none;width: .75em; height: .75em;}
}@keyframes rotate {from {transform: translate(-50%,-50%) rotate(0deg);}to {transform: translate(-50%,-50%) rotate(360deg);}
}.fulllink {position: fixed;top: 0;right: 0;font-size: .65em;text-decoration: none;padding: 1.2em 3.5em;width: 10ex;text-align: center;transform: translateX(30%) rotate(45deg);span {position: relative;animation: .5s ease-in 1s infinite alternate jumpup;animation-duration: 1s;@for $i from 1 through 20 {&:nth-child(#{$i}) {animation-delay: 1000ms + $i * 100ms;}}}
}@keyframes jumpup {100% {opacity: .1;}
}
Babel
// full version: https://farbvelo.elastiq.ch/
// color-names: https://github.com/meodai/color-nameshttps://github.com/meodai/color-namesconst shuffleArray = arr => arr.map(a => [Math.random(), a]).sort((a, b) => a[0] - b[0]).map(a => a[1]);const random = (min, max) => {return Math.floor(Math.random() * (max - min + 1)) + min;
}var generateRandomColors = (total, mode = 'lab', padding = .175, parts = 4) => {let colors = [];const part = Math.floor(total / parts);const reminder = total % parts;// hues to pick fromconst baseHue = random(0, 360);const hues = [0, 60, 120, 180, 240, 300].map(offset => {return (baseHue + offset) % 360;});// low saturated colorconst baseSaturation = random(5, 40);const baseLightness = random(0, 20);const rangeLightness = 90 - baseLightness;colors.push( HUSL.toHex(hues[0],baseSaturation,baseLightness * random(.25, .75)) );for (let i = 0; i < (part - 1); i++) {colors.push( HUSL.toHex(hues[0],baseSaturation,baseLightness + (rangeLightness * Math.pow(i/(part - 1), 1.5))) );}// random shadesconst minSat = random(50, 70);const maxSat = minSat + 30;const minLight = random(45, 80);const maxLight = Math.min(minLight + 40, 95);for (let i = 0; i < (part + reminder - 1); i++) {colors.push( HUSL.toHex(hues[random(0, hues.length - 1)],random(minSat, maxSat),random(minLight, maxLight) ) )}colors.push( HUSL.toHex(hues[0],baseSaturation,rangeLightness) );//colors = shuffleArray(colors);return chroma.scale(colors).padding(padding).mode(mode).colors(total);
}function getContrastColor(color) {let currentColor = chroma( color );let lum = currentColor.luminance();let contrastColor;if ( lum < 0.15 ) {contrastColor = currentColor.set('hsl.l', '+.25'); } else {contrastColor = currentColor.set('hsl.l', '-.35');}return contrastColor;
}Vue.component('color', {props: ['color', 'name'],template: `<div class="color" v-bind:style="{background: color, color: textColor}"><div class="label">{{ color }}</div><div class="name">{{ name.name }}</div></div>`,computed: {/*name: function () {console.log(name)return getClosestNamedColor( this.color ).name;},*/textColor: function () {return getContrastColor(this.color);}}
});let colors = new Vue({el: '#app',data: () => {return {colors: [],names: [],amount: 6,}},methods: {getNames: function () {fetch(`https://api.color.pizza/v1/${this.colors.join().replace(/#/g, '')}?noduplicates=true&goodnamesonly=true`).then(data => data.json()).then(data => {this.names = data.colors;});},newColors: function () {let colorArr = generateRandomColors(this.amount)this.colors = colorArr;this.getNames();let gradient = [...colorArr];gradient[0] += ' 12vmin'gradient[gradient.length - 1] += ' 69%'//url("https://www.transparenttextures.com/patterns/concrete-wall.png"), document.querySelector('.bg').style['background-image'] = `linear-gradient(to bottom, ${gradient.join(',')})`;document.querySelector('.refresh').style.background = this.colors[this.colors.length - 1];document.querySelector('.expand').style.background = this.colors[this.colors.length - 1];document.querySelector('.fulllink').style.background = this.colors[1];document.querySelector('.fulllink').style.color = getContrastColor(this.colors[1]);}},mounted: function () {this.newColors();}
});
这就是奇迹发生的地方:
const random = (min, max) => {return Math.floor(Math.random() * (max - min + 1)) + min;
}
代码的第一行随机打乱数组,第二行返回0到10之间的随机数字。在随机颜色背景的示例中,可以设置颜色和特定范围,例如色相,饱和度和阴影。
有关生成随机十六进制颜色的另一种方法,请查看Chris Coyer的这篇文章
艺术效果
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas Generative Art</title>
<style type="text/css">
</style>
</head>
<body>
<div id="container"> <canvas id="displayCanvas" width="1024px" height="576px">Your browser does not support HTML5 canvas.</canvas><form><p id="caption">HTML5 Canvas - Morphing Fractal Curves, version 2.<input type="button", id="btnRegenerate" value="regenerate"/><input type="button", id="btnExport" value="export image (png)"/><br><a href="http://www.rectangleworld.com">rectangleworld.com</a></p></form>
</div>
</body>
</html>
CSS
body {background-color:#000000; color:#333333;} h4 {font-family: sans-serif; color:#333333; font-size:16px;}h3 {font-family: sans-serif; color:#333333;}p {font-family: sans-serif; color:#333333; font-size:14px;}#caption {position:absolute; width:1024px; text-align:center; top:520px; z-index:1}a {font-family: sans-serif; color:#d15423; text-decoration:none;}canvas {}#displayCanvas {position:absolute; top:10px; z-index:0;}div {}#container {width:1024px; height:576px; margin:auto;}
JavaScript
indow.addEventListener("load", windowLoadHandler, false);//for debug messages while testing code
var Debugger = function() { };
Debugger.log = function(message) {try {console.log(message);}catch (exception) {return;}
}function windowLoadHandler() {canvasApp();
}function canvasSupport() {return Modernizr.canvas;
}function canvasApp() {if (!canvasSupport()) {return;}var displayCanvas = document.getElementById("displayCanvas");var context = displayCanvas.getContext("2d");var displayWidth = displayCanvas.width;var displayHeight = displayCanvas.height;//off screen canvas used only when exporting imagevar exportCanvas = document.createElement('canvas');exportCanvas.width = displayWidth;exportCanvas.height = displayHeight;var exportCanvasContext = exportCanvas.getContext("2d");//var exportImage = document.createElement('img');//buttonsvar btnExport = document.getElementById("btnExport");btnExport.addEventListener("click", exportPressed, false);var btnRegenerate = document.getElementById("btnRegenerate");btnRegenerate.addEventListener("click", regeneratePressed, false);var numCircles;var maxMaxRad;var minMaxRad;var minRadFactor;var circles;var iterations;var numPoints;var timer;var drawsPerFrame;var drawCount;var bgColor,urlColor;var lineWidth;var colorParamArray;var colorArray;var dataLists;var minX, maxX, minY, maxY;var xSpace, ySpace;var lineNumber;var twistAmount;var fullTurn;var lineAlpha;var maxColorValue;var minColorValue;init();function init() {numCircles = 15; //35maxMaxRad = 200;minMaxRad = 200;minRadFactor = 0;iterations = 11;numPoints = Math.pow(2,iterations)+1;drawsPerFrame = 4;fullTurn = Math.PI*2*numPoints/(1+numPoints);minX = -maxMaxRad;maxX = displayWidth + maxMaxRad;minY = displayHeight/2-50;maxY = displayHeight/2+50;twistAmount = 0.67*Math.PI*2;stepsPerSegment = Math.floor(800/numCircles);maxColorValue = 100;minColorValue = 20;lineAlpha = 0.10;bgColor = "#000000";urlColor = "#333333";lineWidth = 1.01;startGenerate();}function startGenerate() {drawCount = 0;context.setTransform(1,0,0,1,0,0);context.clearRect(0,0,displayWidth,displayHeight);setCircles();colorArray = setColorList(iterations);lineNumber = 0;if(timer) {clearInterval(timer);}timer = setInterval(onTimer,1000/60);}function setColorList(iter) {var r0,g0,b0;var r1,g1,b1;var r2,g2,b2;var param;var colorArray;var lastColorObject;var i, len;var maxComponentDistance = 32;var maxComponentFactor = 0.5;r0 = minColorValue + Math.random()*(maxColorValue-minColorValue);g0 = minColorValue + Math.random()*(maxColorValue-minColorValue);b0 = minColorValue + Math.random()*(maxColorValue-minColorValue);;r1 = minColorValue + Math.random()*(maxColorValue-minColorValue);g1 = minColorValue + Math.random()*(maxColorValue-minColorValue);b1 = minColorValue + Math.random()*(maxColorValue-minColorValue);/*//can also set colors explicitly here if you like.r1 = 90;g1 = 60;b1 = 20;r0 = 30;g0 = 77;b0 = 66;*/a = lineAlpha;var colorParamArray = setLinePoints(iter);colorArray = [];len = colorParamArray.length;for (i = 0; i < len; i++) {param = colorParamArray[i];r = Math.floor(r0 + param*(r1 - r0));g = Math.floor(g0 + param*(g1 - g0));b = Math.floor(b0 + param*(b1 - b0));var newColor = "rgba("+r+","+g+","+b+","+a+")";colorArray.push(newColor);}return colorArray;}function setCircles() {var i;var r,g,b,a;var grad;circles = [];for (i = 0; i < numCircles; i++) {maxR = minMaxRad+Math.random()*(maxMaxRad-minMaxRad);minR = minRadFactor*maxR;var newCircle = {centerX: minX + i/(numCircles-1)*(maxX - minX),centerY: minY + i/(numCircles-1)*(maxY - minY),//centerY: minY + Math.random()*(maxY - minY),maxRad : maxR,minRad : minR,phase : i/(numCircles-1)*twistAmount,pointArray : setLinePoints(iterations)};circles.push(newCircle);}}function onTimer() {var i;var cosTheta, sinTheta;var theta;var numCircles = circles.length;var linParam;var cosParam;var centerX, centerY;var xSqueeze = 0.75;var x0,y0;var rad, rad0, rad1;var phase, phase0, phase1;for (var k = 0; k < drawsPerFrame; k++) {theta = lineNumber/(numPoints-1)*fullTurn;context.globalCompositeOperation = "lighter";context.lineJoin = "miter";context.strokeStyle = colorArray[lineNumber];context.lineWidth = lineWidth;context.beginPath();//move to first pointcenterX = circles[0].centerX;centerY = circles[0].centerY;rad = circles[0].minRad + circles[0].pointArray[lineNumber]*(circles[0].maxRad - circles[0].minRad);phase = circles[0].phase;x0 = centerX + xSqueeze*rad*Math.cos(theta + phase);y0 = centerY + rad*Math.sin(theta + phase);context.moveTo(x0,y0);for (i=0; i< numCircles-1; i++) {//draw between i and i+1 circlerad0 = circles[i].minRad + circles[i].pointArray[lineNumber]*(circles[i].maxRad - circles[i].minRad);rad1 = circles[i+1].minRad + circles[i+1].pointArray[lineNumber]*(circles[i+1].maxRad - circles[i+1].minRad);phase0 = circles[i].phase;phase1 = circles[i+1].phase;for (j = 0; j < stepsPerSegment; j++) {linParam = j/(stepsPerSegment-1);cosParam = 0.5-0.5*Math.cos(linParam*Math.PI);//interpolate centercenterX = circles[i].centerX + linParam*(circles[i+1].centerX - circles[i].centerX);centerY = circles[i].centerY + cosParam*(circles[i+1].centerY - circles[i].centerY);//interpolate radiusrad = rad0 + cosParam*(rad1 - rad0);//interpolate phasephase = phase0 + cosParam*(phase1 - phase0);x0 = centerX + xSqueeze*rad*Math.cos(theta + phase);y0 = centerY + rad*Math.sin(theta + phase);context.lineTo(x0,y0);}}context.stroke();lineNumber++;if (lineNumber > numPoints-1) {clearInterval(timer);timer = null;break;}}}//Here is the function that defines a noisy (but not wildly varying) data set which we will use to draw the curves.//We first define the points in a linked list, but then store the values in an array.function setLinePoints(iterations) {var pointList = {};var pointArray = [];pointList.first = {x:0, y:1};var lastPoint = {x:1, y:1}var minY = 1;var maxY = 1;var point;var nextPoint;var dx, newX, newY;var ratio;var minRatio = 0.5;pointList.first.next = lastPoint;for (var i = 0; i < iterations; i++) {point = pointList.first;while (point.next != null) {nextPoint = point.next;dx = nextPoint.x - point.x;newX = 0.5*(point.x + nextPoint.x);newY = 0.5*(point.y + nextPoint.y);newY += dx*(Math.random()*2 - 1);var newPoint = {x:newX, y:newY};//min, maxif (newY < minY) {minY = newY;}else if (newY > maxY) {maxY = newY;}//put between pointsnewPoint.next = nextPoint;point.next = newPoint;point = nextPoint;}}//normalize to values between 0 and 1//Also store y values in array here.if (maxY != minY) {var normalizeRate = 1/(maxY - minY);point = pointList.first;while (point != null) {point.y = normalizeRate*(point.y - minY);pointArray.push(point.y);point = point.next;}}//unlikely that max = min, but could happen if using zero iterations. In this case, set all points equal to 1.else {point = pointList.first;while (point != null) {point.y = 1;pointArray.push(point.y);point = point.next;}}return pointArray; }function exportPressed(evt) {//background - otherwise background will be transparent.exportCanvasContext.fillStyle = bgColor;exportCanvasContext.fillRect(0,0,displayWidth,displayHeight);//drawexportCanvasContext.drawImage(displayCanvas, 0,0,displayWidth,displayHeight,0,0,displayWidth,displayHeight);//add printed url to imageexportCanvasContext.fillStyle = urlColor;exportCanvasContext.font = 'bold italic 16px Helvetica, Arial, sans-serif';exportCanvasContext.textBaseline = "top";var metrics = exportCanvasContext.measureText("rectangleworld.com");exportCanvasContext.fillText("rectangleworld.com", displayWidth - metrics.width - 10, 5);//we will open a new window with the image contained within: //retrieve canvas image as data URL:var dataURL = exportCanvas.toDataURL("image/png");//open a new window of appropriate size to hold the image:var imageWindow = window.open("", "fractalLineImage", "left=0,top=0,width="+displayWidth+",height="+displayHeight+",toolbar=0,resizable=0");//write some html into the new window, creating an empty image:imageWindow.document.write("<title>Export Image</title>")imageWindow.document.write("<img id='exportImage'"+ " alt=''"+ " height='" + displayHeight + "'"+ " width='" + displayWidth + "'"+ " style='position:absolute;left:0;top:0'/>");imageWindow.document.close();//copy the image into the empty img in the newly opened window:var exportImage = imageWindow.document.getElementById("exportImage");exportImage.src = dataURL;}function regeneratePressed(evt) {startGenerate();}}
在此变形分形曲线中,Math.random
两次用于设置渐变的颜色,一次用于设置曲线的最大半径。 这是在每次迭代中构建全新外观的好方法!
文字效果
Slim
h1svg role="img"title.title Random Words! text.word x="50%" y="50%" text-anchor="middle" fill="#222" stroke="#222" stroke-width="1.5%" dominant-baseline="central" stroke-linecap="round" Random Words!text.word x="50%" y="50%" text-anchor="middle" fill="white" dominant-baseline="central" Random Words!p Made with <b>♥</b> by <a href="https://twitter.com/LandonSchropp">Landon Schropp</a>
Sass
html, body, h1height: 100%width: 100%bodytransition: background-color 0.3s ease-infont-family: 'Open Sans', sans-serifbackground-color: hsl(350, 100%, 50%)// in firefox, a transformed element causes a scroll when it extends beyond the element's size, so we'll disable itoverflow: hiddenfont-size: 12px@media (min-width: 480px)font-size: 14px@media (min-width: 640px)font-size: 16px.wordfont-family: 'Bangers', cursivesvgheight: 100%width: 100%position: relativetop: -1remanimation: pop-out 2s ease-in-out infinite.wordfont-family: 'Bangers', cursiveletter-spacing: 0.05emcolor: whitepadding: 0.5emfont-size: 28px@media (min-width: 480px)font-size: 36px@media (min-width: 640px)font-size: 48px@media (min-width: 960px)font-size: 64px@media (min-width: 1280px)font-size: 84pxpposition: fixedbottom: 0left: 0right: 0line-height: 2remtext-align: centercolor: transparentize(white, 0.25)background-color: transparentize(#222, 0.0)@keyframes pop-out0%transform: scale3d(0, 0, 1)opacity: 125%transform: scale3d(1, 1, 1)opacity: 1100%transform: scale3d(1.5, 1.5, 1)opacity: 0a, a:visitedcolor: inherit
V
JavaScript
$(document).ready(function () {// set the background to a random colorvar hue = 350;// cache the jquery elements to prevent dom queries during the animation eventsvar $body = $("body");var $svg = $("svg");var $word = $(".word");// when the animation iterates$("h1").on("webkitAnimationIteration oanimationiteration msAnimationIteration animationiteration ",function () {// replace the header with a random wordvar word = words[Math.floor(Math.random() * words.length)] + "!";$word.text(word);// update the background colorhue += 47;$body.css("background-color", "hsl(" + hue + ", 100%, 50%)");});
});// the 10,000 most comment words, taken from https://goo.gl/hfjFkz
words = ["the","of","and",];
我们使用Math.random
将标题替换为数组中随机选择的单词:
var word = words[Math.floor(Math.random() * words.length)] + "!";
这很像随机图像示例-对于初学者来说是一种完美的练习!
API密钥生成器
HTML
<div class="wrapper"><button class="form-control" id="keygen">Generate API Key</button><input class="form-control" id="apikey" type="text" value="" placeholder="Click on the button to generate a new API key ..." /></div>
CSS
body {text-align: center;background: #f1f1f1;
}.wrapper {padding-top:60px;
}button.form-control {background: #f7f7f7 none repeat scroll 0 0;border-color: #ccc;box-shadow: 0 1px 0 #ccc;color: #555;vertical-align: top;border-radius: 3px;border-style: solid;border-width: 1px;box-sizing: border-box;cursor: pointer;display: inline-block;font-size: 13px;height: 28px;line-height: 26px;margin: 0;padding: 0 10px 1px;text-decoration: none;white-space: nowrap;
}input.form-control {background-color: #fff;border: 1px solid #ddd;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;color: #32373c;outline: 0 none;transition: border-color 50ms ease-in-out 0s;margin: 1px;padding: 3px 5px;border-radius: 0;font-size: 14px;font-family: inherit;font-weight: inherit;box-sizing: border-box;color: #444;font-family: "Open Sans",sans-serif;line-height: 1.4em;width: 310px;
}
JavaScript
function generateUUID()
{var d = new Date().getTime();if( window.performance && typeof window.performance.now === "function" ){d += performance.now();} var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c){var r = (d + Math.random()*16)%16 | 0;d = Math.floor(d/16);return (c=='x' ? r : (r&0x3|0x8)).toString(16);});return uuid;
}/*** Generate new key and insert into input value*/
$( '#keygen' ).on('click',function(){$( '#apikey' ).val( generateUUID() );
});
这是一个随机数的超级现实应用案例! 该演示会生成16个随机数,以创建一个通用唯一标识符(UUID),该标识符可用作提供对API的访问的密钥。
打乱文本
HTML
<div class="container"><div class="text"></div>
</div>
Stylus
@import 'https://fonts.googleapis.com/css?family=Roboto+Mono:100'
html, bodyfont-family 'Roboto Mono', monospacebackground #212121height 100%
.containerheight 100%width 100%justify-content centeralign-items centerdisplay flex
.textfont-weight 100font-size 28pxcolor #FAFAFA
.dudcolor #757575
Babel
class TextScramble {constructor(el) {this.el = elthis.chars = '!<>-_\\/[]{}—=+*^?#________'this.update = this.update.bind(this)}setText(newText) {const oldText = this.el.innerTextconst 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 = 0this.update()return promise}update() {let output = ''let complete = 0for (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 = outputif (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 = ['Neo,','sooner or later','you\'re going to realize','just as I did','that there\'s a difference','between knowing the path','and walking the path'
]const el = document.querySelector('.text')
const fx = new TextScramble(el)let counter = 0
const next = () => {fx.setText(phrases[counter]).then(() => {setTimeout(next, 800)})counter = (counter + 1) % phrases.length
}next()
依次存储和显示一些短语,并由一个动画隔开,该动画看起来像是用Math.random
选择的短语之间的随机字符来扰乱字母。
石头剪刀布
HTML
<ul id="moves"><li data-move="rock"><span class="fa fa-fw fa-hand-rock-o"></span><span class="text">Rock</span></li><li data-move="paper"><span class="fa fa-fw fa-hand-paper-o"></span><span class="text">Paper</span></li><li data-move="scissors"><span class="fa fa-fw fa-hand-scissors-o"></span><span class="text">Scissors</span></li>
</ul>
<div class="scoreboard"><table><thead><td>Player</td><td>Computer</td></thead><tbody><tr><td class="Player-count">0</td><td class="Computer-count">0</td></tr></tbody></table>
</div>
SCSS
// Observify Colours
$light-blue: #edf0f9;
$dark-blue: #151e28;
$blue: #019cdf;
$green: #35b197;
$red: #e94d5a;
$orange: #f66e3a;
$pink: #f583b6;
$purple: #7e4894;
$black: #000000;
$white: #ffffff;// Variables
$body-bg: $dark-blue;
$color: $light-blue;
$font: 'Open Sans', sans-serif;
$font-size: 16px;@keyframes icon-animation {0% { transform: scale(1); opacity: 1; }50% { transform: scale(1.4); }60% { opacity: 0;} 80% { transform: scale(0.5); }90% { opacity: 0; }
}body {background-color: $body-bg;color: $color;font-family: $font;font-size: $font-size;
}// Put your prototype code here
#moves {list-style: none;width: 100%;padding: 0;display: flex;li {background: $green;width: 33.33%;margin: 1em;&:hover {background: lighten($green, 10);}&:active {background: $orange;}.fa {display: block;font-size: 48px;text-align: center;width: 100%;padding: 1em;box-sizing: border-box;&.animating {animation: icon-animation 2s 1;}}.text {text-align: center;width: 100%;display: block;padding-bottom: 2em;text-transform: uppercase;letter-spacing: 0.2em;font-weight: 600;font-size: 11px;}}
}.scoreboard {width: 100%;table {width: 100%;background: lighten($body-bg, 3);td {padding: .5em;box-sizing: border-box;text-align: center;text-transform: uppercase;}thead {font-size: 12px;font-weight: 700;letter-spacing: 0.2em;td {padding-top: 2em;}}tbody {td {font-size: 96px;font-weight: 900;line-height: 1em;}}}
}
JavaScript
$(window).load(function() {var movesContainer = $('#moves'),playerCount = $('.Player-count'),computerCount = $('.Computer-count');$('#moves li').on("click", function() {var yourMove = $(this).data('move');processMoves(yourMove);var icon = $(this).find('.fa');icon.addClass('animating');var s = setTimeout(function(icon) {$('#moves li .fa').removeClass('animating');clearTimeout();}, 5000);});});function processMoves(yourMove) {var opponentMove = generateRandomOpponentMove();calculateWinner(yourMove,opponentMove);
}function generateRandomOpponentMove() {var availableMoves = ['rock','paper','scissors'],randomNumber = Math.floor(Math.random() * availableMoves.length),opponentMove = availableMoves[randomNumber];return opponentMove;
}function calculateWinner(yourMove, opponentMove) {switch(yourMove) {case 'rock':if(opponentMove === 'rock') {return 'draw';} else if (opponentMove === 'scissors') {youWin();} else {youLose();}break;case 'paper':if(opponentMove === 'paper') {return 'draw';} else if (opponentMove === 'rock') {youWin();} else {youLose();}break;case 'scissors':if(opponentMove === 'scissors') {return 'draw';} else if (opponentMove === 'paper') {youWin();} else {youLose();}break;}
}function youWin() {var playerScore = $('.Player-count');var playerScoreUpdated = parseInt(playerScore.text()) + 1;playerScore.text(playerScoreUpdated);
}function youLose() {var computerScore = $('.Computer-count');var computerScoreUpdated = parseInt(computerScore.text()) + 1;computerScore.text(computerScoreUpdated);
}
在这个童年时代的经典剪刀石头布游戏中,Math.random
作为对手的计算机生成随机移动。 它从三个可用的招式中进行选择。
密码生成器
HTML
div id="app"><section class="wrapper"> <h1>The Password Genie</h1><div class="password-box"><span id="password" class="password" v-on:click="copyToClipboard">{{ password }}</span><span class="regenerate-password" v-on:click="generatePassword"></span><span class="copy-password" v-on:click="copyToClipboard"></span><span class="tooltip" v-if="copied">Password copied successfuly!</span></div><form @keydown.enter.prevent=""><div class="field-wrap"><label>Strength</label><span class="range-value">{{strength.text}}</span><div class="range-slider_wrapper slider-strength" v-bind:class="strength.text"><span class="slider-bar" v-bind:style="{ width: strength.score + '%' }"></span><input type="range" class="range-slider" min="0" max="100" v-model="strength.score" disabled></div> </div><div class="seperator"></div><div class="field-wrap"><label>Length</label><span class="range-value">{{settings.length}}</span><div class="range-slider_wrapper"><span class="slider-bar" v-bind:style="{ width: lengthThumbPosition + '%' }"></span><input type="range" class="range-slider" min="6" v-bind:max="settings.maxLength" v-model="settings.length"></div> </div><div class="field-wrap"> <label>Digits</label><span class="range-value">{{settings.digits}}</span><div class="range-slider_wrapper"><span class="slider-bar" v-bind:style="{ width: digitsThumbPosition + '%' }"></span><input type="range" class="range-slider" min="0" v-bind:max="settings.maxDigits" v-model="settings.digits"></div> </div><div class="field-wrap"> <label>Symbols</label><span class="range-value">{{settings.symbols}}</span><div class="range-slider_wrapper"><span class="slider-bar" v-bind:style="{ width: symbolsThumbPosition + '%' }"></span><input type="range" class="range-slider" min="0" v-bind:max="settings.maxSymbols" v-model="settings.symbols"></div> </div></form></section></div>
SCSS
$blue: #3fa4f4;
$purple: #6e77f7;
$peach: #fc8680;
$pink: #ef5081;
$green: #8BC34A;
$dark-green: #4caf50;
$red: #ff6666;
$orange: #ff9800;$wrapper-bg: #f4f7fc;
$wrapper-width: 400px;*{box-sizing: border-box;
}body{font-size: 15px;font-family: Tahoma,Verdana,Segoe,sans-serif;color: #444;background-color: #fefefe;background-image: linear-gradient(-45deg, #018bfd 0%, #3F51B5 100%);background-repeat: no-repeat;background-size: cover;padding: 0 20px;margin: 0;min-height: 100vh;position: relative;
}.header{padding: 2em 0;text-align: center;.title{font-size: 1.2em;font-weight: bold;color: #fff;img{width: 12px;margin: 0 2px 2px;vertical-align: bottom;}}
}.wrapper{width: $wrapper-width;max-width: 100%;min-height: 400px;margin: 40px auto;position: relative;border: 1px solid #eee;border-radius: 3px;padding: 40px 20px;font-size: 0.85em;-webkit-box-shadow: 0 0 15px 0 rgba(0,0,0,0.05);box-shadow: 0 0 15px 0 rgba(0,0,0,0.05);background-color: $wrapper-bg;position: relative;transition: all ease-in 0.25s;
}h1{text-align: center;margin: 0 0 40px;
}
.field-wrap{margin-bottom: 20px;
}form{overflow: overlay;margin-top: 30px;
}label{display: inline-block;min-width: 20%;
}.range-slider_wrapper{position: relative;width: 100%;margin: 10px 0 30px;
}.range-slider{-webkit-appearance: none;appearance: none;background: lighten($blue, 20%);width: 100%;border-radius: 3px;vertical-align: bottom;margin: 0;height: 6px;cursor: pointer;transition: all ease-in 0.25s;
}.range-slider::-webkit-slider-thumb{-webkit-appearance: none;appearance: none;border-radius: 0;border: 0;position:relative;width: 4px;height: 15px;background-color: darken($blue, 5%);
}
.range-slider::-moz-range-thumb{-moz-appearance: none;appearance: none;border-radius: 0;border: 0;position:relative;width: 4px;height: 15px;background-color: darken($blue, 5%);
}.range-slider{&:focus{outline: none;}&:hover, &:active{&::-webkit-slider-thumb{top: 0px;}}
}
::-moz-range-track {background: transparent;border: 0;
}
input::-moz-focus-inner,
input::-moz-focus-outer { border: 0;
}.range-value{text-transform: capitalize;float: right;vertical-align: bottom;min-width: 30px;display: inline-block;text-align: center;border-radius: 3px;font-size: 0.9em;
}.slider-bar{position: absolute;height: 6px;border-top-left-radius: 3px;border-bottom-left-radius: 3px;background: $blue;left: 0;bottom: 0;pointer-events: none;
}.slider{&-strength{.range-slider{cursor: default;}.slider-bar{border-radius: 3px;transition: all ease-in 0.25s;}.range-slider::-webkit-slider-thumb{background-color: transparent;}.range-slider::-moz-range-thumb{background-color: transparent;}&.weak{.range-slider{background-color: lighten($red, 30%);}.slider-bar, .slider-bar:after{background-color: $red;}}&.average{.range-slider{background-color: lighten($orange, 30%);}.slider-bar, .slider-bar:after{background-color: $orange;}}&.strong{.range-slider{background-color: lighten($green, 30%);}.slider-bar, .slider-bar:after{background-color: $green;}}&.secure{.range-slider{background-color: lighten($green, 30%);}.slider-bar, .slider-bar:after{background-color: $green;}}}
}.password-box{width: 100%;min-height: 80px;margin-bottom: 40px;position: relative;text-align: center;border-radius: 3px;background: #fff;letter-spacing: 2px;transition: all ease-in 0.3s;border: 1px solid rgb(189, 204, 230);.password{width: 70%;padding: 1.5em 1em;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);word-wrap: break-word;}
}.regenerate-password, .copy-password{width: 44px;height: 50%;position: absolute;right: 0;transition: all ease-in 0.25s;&:hover{opacity: 0.8;}
}.regenerate-password{top: 0;background-color: #fff;background-image: url('https://nourabusoud.github.io/password-genie/images/regenerate.svg');background-size: 40%;background-position: center center;background-repeat: no-repeat;transition: all ease-in 0.25s;cursor: pointer;&:hover{background-color: #fff;}
}.copy-password{bottom: 0;background-color: #fff;background-image: url('https://nourabusoud.github.io/password-genie/images/copy-full.svg');background-size: 50%;background-position: center center;background-repeat: no-repeat;transition: all ease-in 0.25s;cursor: pointer;&:hover{background-color: #fff;}
}.tooltip{font-size: 0.8em;display: block;text-align: center;padding: 0.5em;border-radius: 3px;position: absolute;bottom: -35px;left: 50%;transform: translateX(-50%);
}.seperator{width: 100%;height: 3px;background-color: #fff;margin: 60px 0 40px;
}/* Footer */
footer{ width: 100%;text-align: center;color: #fff;
}footer a{color: #fff;
}.github-links{margin-bottom: 30px;
}// fix for copy text
textarea, textarea:focus{font-size: 16px;
}
JavaScript
new Vue({el: '#app',data() {return {password: '',copied: false,settings: {maxLength: 64,maxDigits: 10,maxSymbols: 10,length: 12,digits: 4,symbols: 2,ambiguous: true,}};},computed: {lengthThumbPosition: function() {return (( (this.settings.length - 6) / (this.settings.maxLength - 6)) * 100);},digitsThumbPosition: function() {return (( (this.settings.digits - 0) / (this.settings.maxDigits - 0)) * 100);},symbolsThumbPosition: function() {return (( (this.settings.symbols - 0) / (this.settings.maxSymbols - 0)) * 100);},strength: function() {var count = {excess: 0,upperCase: 0,numbers: 0,symbols: 0};var weight = {excess: 3,upperCase: 4,numbers: 5,symbols: 5,combo: 0, flatLower: 0,flatNumber: 0};var strength = {text: '',score: 0};var baseScore = 30;for (i=0; i < this.password.length;i++){if (this.password.charAt(i).match(/[A-Z]/g)) {count.upperCase++;}if (this.password.charAt(i).match(/[0-9]/g)) {count.numbers++;}if (this.password.charAt(i).match(/(.*[!,@,#,$,%,^,&,*,?,_,~])/)) {count.symbols++;} }count.excess = this.password.length - 6;if (count.upperCase && count.numbers && count.symbols){weight.combo = 25; }else if ((count.upperCase && count.numbers) || (count.upperCase && count.symbols) || (count.numbers && count.symbols)){weight.combo = 15; }if (this.password.match(/^[\sa-z]+$/)){ weight.flatLower = -30;}if (this.password.match(/^[\s0-9]+$/)){ weight.flatNumber = -50;}var score = baseScore + (count.excess * weight.excess) + (count.upperCase * weight.upperCase) + (count.numbers * weight.numbers) + (count.symbols * weight.symbols) + weight.combo + weight.flatLower + weight.flatNumber;if(score < 30 ) {strength.text = "weak";strength.score = 10;return strength;} else if (score >= 30 && score < 75 ){strength.text = "average";strength.score = 40;return strength;} else if (score >= 75 && score < 150 ){strength.text = "strong";strength.score = 75;return strength;} else {strength.text = "secure";strength.score = 100;return strength;}},},mounted() {this.generatePassword();},watch: {settings: {handler: function() {this.generatePassword();},deep: true}},methods: {// copy password to clipboardcopyToClipboard(){// we should create a textarea, put the password inside it, select it and finally copy itvar copyElement = document.createElement("textarea");copyElement.style.opacity = '0';copyElement.style.position = 'fixed';copyElement.textContent = this.password;var body = document.getElementsByTagName('body')[0];body.appendChild(copyElement);copyElement.select();document.execCommand('copy');body.removeChild(copyElement);this.copied = true;// reset this.copiedsetTimeout(() => {this.copied = false;}, 750);},// generate the passwordgeneratePassword() {var lettersSetArray = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];var symbolsSetArray = [ "=","+","-","^","?","!","%","&","*","$","#","^","@","|"];//var ambiguousSetArray = ["(",")","{","}","[","]","(",")","/","~",";",":",".","<",">"];var passwordArray = [];var digitsArray = [];var digitsPositionArray = [];// first, fill the password array with letters, uppercase and lowecasefor (var i = 0; i < this.settings.length; i++) {// get an array for all indexes of the password arraydigitsPositionArray.push(i);var upperCase = Math.round(Math.random() * 1);if (upperCase === 0) {passwordArray[i] = lettersSetArray[Math.floor(Math.random()*lettersSetArray.length)].toUpperCase();}else {passwordArray[i] = lettersSetArray[Math.floor(Math.random()*lettersSetArray.length)];}}// Add digits to passwordfor (i = 0; i < this.settings.digits; i++) {digit = Math.round(Math.random() * 9);numberIndex = digitsPositionArray[Math.floor(Math.random()*digitsPositionArray.length)];passwordArray[numberIndex] = digit;/* remove position from digitsPositionArray so we make sure to the have the exact number of digits in our passwordsince without this step, numbers may override other numbers */var j = digitsPositionArray.indexOf(numberIndex);if(i != -1) {digitsPositionArray.splice(j, 1);}}// add special charachters "symbols"for (i = 0; i < this.settings.symbols; i++) {var symbol = symbolsSetArray[Math.floor(Math.random()*symbolsSetArray.length)];var symbolIndex = digitsPositionArray[Math.floor(Math.random()*digitsPositionArray.length)];passwordArray[symbolIndex] = symbol;/* remove position from digitsPositionArray so we make sure to the have the exact number of digits in our passwordsince without this step, numbers may override other numbers */var j = digitsPositionArray.indexOf(symbolIndex);if(i != -1) {digitsPositionArray.splice(j, 1);}}this.password = passwordArray.join("");},},
});
这个密码生成器使用Math.random
,获取包含大写和小写字母的密码数组,然后将随机数字添加到生成的密码中。这是另一个很实用的例子
值得关注的事情
Math.random()真的是随机的吗?
不完全是。 Math.random()
返回一个伪随机数
。 该算法称为伪随机数生成器(或PRNG)。 这意味着在某些情况下能够控制其随机性。
这一随机化是基于xorshift128 +算法,该算法可能在您的浏览器上运行。
所以,它是随机的。
如何处理重复值?
有许多方法可以在不重复的情况下获得独特的值。Fisher-Yates
是一种通过改变数组序列来防止两次获得相同数字的好方法。 Math.random
将从有限序列的变化数组中选择一个值,如下面的代码片段所示。
function shuffle (array) {var i = 0, j = 0, temp = nullfor (i = array.length - 1; i > 0; i -= 1) {j = Math.floor(Math.random() * (i + 1))temp = array[i]array[i] = array[j]array[j] = temp}
}
Math.random()与WebCrypto相同吗?
如您在本文中所见,Math.random()
非常棒!但是,如果您要处理敏感的应用程序,并且需要一种更安全的随机方法,则建议您使用WebCrypto
。 您可能要使用WebCrypto
的原因包括临时验证码,随机密码生成,随机彩票号码等。
如果出于网络安全、密码学或统计的目的需要随机化,请使用window.crypto.getRandomValues
函数,相关内容请查看Mozilla关于WebCrypto API的文档。
外文翻译 | 你以为你会用Math.random() ? 不,你不会……相关推荐
- matlab仿真的英文文献,matlab 外文翻译 外文文献 英文文献 MATALAB 混合仿真平台控制算法的概述...
matlab 外文翻译 外文文献 英文文献 MATALAB 混合仿真平台控制算法的概述 MATALAB 混合仿真平台控制算法的概述 MATALB 混合仿真平台,即为将硬件引入到仿真回路里的半实物仿真系 ...
- 开题报告、文献综述、外文翻译、论文反抄袭软件、论文目录,就差论文正文了,其他都全了!!
开题报告.文献综述.外文翻译.论文反抄袭软件.论文目录,就差论文正文了,其他都全了!! 开题报告主要包括以下几个方面: (一)论文名称 论文名称就是课题的名字 第一,名称要准确.规范.准确就是论文的名 ...
- 开题报告、文献检索账号、文献综述、外文翻译、抄袭检测软件、论文目录,都在这了都在这了,有备无患,拿去吧!
开题报告.文献综述.外文翻译.论文反抄袭软件.论文目录,就差论文正文了,其他都全了!! 开题报告主要包括以下几个方面: (一)论文名称 论文名称就是课题的名字 第一,名称要准确.规范.准确就是论文的名 ...
- 开题报告、文献检索账号、文献综述、外文翻译、抄袭检测软件、论文目录,免费分享,都在这了
开题报告.文献综述.外文翻译.论文反抄袭软件.论文目录,就差论文正文了,其他都全了!! 反论文抄袭检查,吼吼,终于找到了 来源:http://likelibrary.blog.163.com/blog ...
- matlab中的routte,matlab外文翻译外文文献英文文献MATALAB混合仿真平台控制算法的概述...
<matlab外文翻译外文文献英文文献MATALAB混合仿真平台控制算法的概述>由会员分享,可在线阅读,更多相关<matlab外文翻译外文文献英文文献MATALAB混合仿真平台控制算 ...
- 大学计算机专业全英文论文,5计算机专业 外文文献 英文文献 外文翻译 jsp应用框架 中英对照 大学学位论文.doc...
5计算机专业 外文文献 英文文献 外文翻译 jsp应用框架 中英对照 大学学位论文 外文JSP application frameworks brian wright.michael freedman ...
- 微型计算机系统外文,微型计算机控系统(单片机控制系统) 毕业论文外文翻译.doc...
微型计算机控系统(单片机控制系统) 毕业论文外文翻译 英语翻译 Microcontroller reset is to make the CPU and other system features a ...
- 计算机php外文翻译,php外文翻译.doc
文档介绍: 附录A外文翻译-原文部分PHPLanguageBasicsActiveServerPages(PHP)isaproven,well-establishedtechnologyforbuil ...
- 计算机专业英语外文翻译,计算机专业英语JAVA介绍外文翻译[共28页]
<计算机专业英语JAVA介绍外文翻译[共28页]>由会员分享,可在线阅读,更多相关<计算机专业英语JAVA介绍外文翻译[共28页](28页珍藏版)>请在读根文库上搜索. 1.荆 ...
最新文章
- appium-chromedriver@3.0.1 npm ERR! code ELIFECYCLE npm ERR! errno 1
- java建造_java建造者模式
- 在Heroku上创建node.js应用程序时,我应该将node_modules检入git吗?
- 大连东软信息学院计算机专业19分数线,2021大连东软信息学院录取分数线_历年各专业分数线(2017-2020),各省投档线_一品高考网...
- 快速解码base64和utf-8的ASCII编码和URL解码
- 在Linux中快速找到文件的几种方法
- leetcode 61 python
- kubernetes(K8s):管理云平台中多个主机上的容器化的应用
- 【转】dx11 devicecontext-map
- 数据结构之线性表学习一
- log4cpp 概述与基本使用实例(一)
- 电商后台管理系统项目介绍和项目初始化
- Centos7安装gos脚本
- 网络篇 OSPF的LSDB过载保护-52
- H桥驱动电机,STM32 PWM互补输出功能误用分析
- 如何学习android
- Ubuntu下连上网络开始学习啦
- HOUDINI TIP | USING HOU MODULE IN VISUAL STUDIO CODE_手动在vscode里设置houdiniPython模块
- jmeter正则表达式提取器的用法和正则
- .mk 文件中,= 、:= 、?= 、+= 的区别
热门文章
- 2022年第十四届蓝桥杯模拟赛【核酸日期】C语言详解
- NAACL2022信息抽取论文分类
- vs上C/C++并行计算#pragma omp
- 自定义圆形、半圆形ProgressBar
- 域名过期 脚本_域名宝已过期! …还是垃圾?
- 5G,上天了!卫星和基站擦出了火花?
- 如何关闭苹果手机自动扣费_iPhone自动扣费怎么取消?App Store、微信、支付宝关闭自动扣费教程...
- 图像mnf正变换_基于MNF 变换的多元变化检测变化信息的集中
- 基于pyqt5的登录界面及人脸识别功能界面相互跳转的设计(1)
- 汇编语言:以“年/月/日 时:分:秒”的格式,显示当前的日期、时间。